Full Code of HigherOrderCO/Bend for AI

main d184863f03e7 cached
1098 files
2.8 MB
798.4k tokens
863 symbols
1 requests
Download .txt
Showing preview only (3,177K chars total). Download the full file or copy to clipboard to get everything.
Repository: HigherOrderCO/Bend
Branch: main
Commit: d184863f03e7
Files: 1098
Total size: 2.8 MB

Directory structure:
gitextract_5jgx8w8i/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       └── checks.yml
├── .gitignore
├── .rustfmt.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── FAQ.md
├── FEATURES.md
├── GUIDE.md
├── LICENSE-APACHE
├── README.md
├── cspell.json
├── docs/
│   ├── builtins.md
│   ├── cli-arguments.md
│   ├── compilation-and-readback.md
│   ├── compiler-options.md
│   ├── defining-data-types.md
│   ├── dups-and-sups.md
│   ├── ffi.md
│   ├── imports.md
│   ├── lazy-definitions.md
│   ├── native-numbers.md
│   ├── pattern-matching.md
│   ├── syntax.md
│   ├── type-checking.md
│   ├── using-scopeless-lambdas.md
│   └── writing-fusing-functions.md
├── examples/
│   ├── bitonic_sort.bend
│   ├── bubble_sort.bend
│   ├── callcc.bend
│   ├── example_fun.bend
│   ├── fib.bend
│   ├── fusing_add.bend
│   ├── fusing_not.bend
│   ├── gen_tree.bend
│   ├── hello_world.bend
│   ├── insertion_sort.bend
│   ├── list.bend
│   ├── parallel_and.bend
│   ├── parallel_sum.bend
│   ├── queue.bend
│   ├── quick_sort.bend
│   └── radix_sort.bend
├── justfile
├── src/
│   ├── diagnostics.rs
│   ├── fun/
│   │   ├── builtins.bend
│   │   ├── builtins.rs
│   │   ├── check/
│   │   │   ├── check_untyped.rs
│   │   │   ├── mod.rs
│   │   │   ├── set_entrypoint.rs
│   │   │   ├── shared_names.rs
│   │   │   ├── type_check.rs
│   │   │   ├── unbound_refs.rs
│   │   │   └── unbound_vars.rs
│   │   ├── display.rs
│   │   ├── load_book.rs
│   │   ├── mod.rs
│   │   ├── net_to_term.rs
│   │   ├── parser.rs
│   │   ├── term_to_net.rs
│   │   └── transform/
│   │       ├── apply_args.rs
│   │       ├── definition_merge.rs
│   │       ├── definition_pruning.rs
│   │       ├── desugar_bend.rs
│   │       ├── desugar_fold.rs
│   │       ├── desugar_match_defs.rs
│   │       ├── desugar_open.rs
│   │       ├── desugar_use.rs
│   │       ├── desugar_with_blocks.rs
│   │       ├── encode_adts.rs
│   │       ├── encode_match_terms.rs
│   │       ├── expand_generated.rs
│   │       ├── expand_main.rs
│   │       ├── fix_match_defs.rs
│   │       ├── fix_match_terms.rs
│   │       ├── float_combinators.rs
│   │       ├── lift_local_defs.rs
│   │       ├── linearize_matches.rs
│   │       ├── linearize_vars.rs
│   │       ├── mod.rs
│   │       ├── resolve_refs.rs
│   │       ├── resolve_type_ctrs.rs
│   │       ├── resugar_list.rs
│   │       ├── resugar_string.rs
│   │       └── unique_names.rs
│   ├── hvm/
│   │   ├── add_recursive_priority.rs
│   │   ├── check_net_size.rs
│   │   ├── eta_reduce.rs
│   │   ├── inline.rs
│   │   ├── mod.rs
│   │   ├── mutual_recursion.message
│   │   ├── mutual_recursion.rs
│   │   └── prune.rs
│   ├── imp/
│   │   ├── gen_map_get.rs
│   │   ├── mod.rs
│   │   ├── order_kwargs.rs
│   │   ├── parser.rs
│   │   └── to_fun.rs
│   ├── imports/
│   │   ├── book.rs
│   │   ├── loader.rs
│   │   ├── mod.rs
│   │   └── packages.rs
│   ├── lib.rs
│   ├── main.rs
│   ├── net/
│   │   ├── hvm_to_net.rs
│   │   └── mod.rs
│   └── utils.rs
└── tests/
    ├── golden_tests/
    │   ├── check_file/
    │   │   ├── fail_type_bad_rec_fn_adt.bend
    │   │   ├── non_exaustive_limit.bend
    │   │   └── type_err_match_arm.bend
    │   ├── cli/
    │   │   ├── compile_all.args
    │   │   ├── compile_all.bend
    │   │   ├── compile_inline.args
    │   │   ├── compile_inline.bend
    │   │   ├── compile_no_opts.args
    │   │   ├── compile_no_opts.bend
    │   │   ├── compile_pre_reduce.args
    │   │   ├── compile_pre_reduce.bend
    │   │   ├── compile_strict_loop.args
    │   │   ├── compile_strict_loop.bend
    │   │   ├── compile_wrong_opt.args
    │   │   ├── compile_wrong_opt.bend
    │   │   ├── custom_hvm_bin.args
    │   │   ├── custom_hvm_bin.bend
    │   │   ├── debug_list_map.args
    │   │   ├── debug_list_map.bend
    │   │   ├── debug_u60_to_nat.args
    │   │   ├── debug_u60_to_nat.bend
    │   │   ├── desugar_bool_scott.args
    │   │   ├── desugar_bool_scott.bend
    │   │   ├── desugar_float_combinators.args
    │   │   ├── desugar_float_combinators.bend
    │   │   ├── desugar_linearize_matches.args
    │   │   ├── desugar_linearize_matches.bend
    │   │   ├── desugar_linearize_matches_alt.args
    │   │   ├── desugar_linearize_matches_alt.bend
    │   │   ├── desugar_merge.args
    │   │   ├── desugar_merge.bend
    │   │   ├── desugar_pretty.args
    │   │   ├── desugar_pretty.bend
    │   │   ├── desugar_prune.args
    │   │   ├── desugar_prune.bend
    │   │   ├── gen_hvm_no_eta_by_default.args
    │   │   ├── gen_hvm_no_eta_by_default.bend
    │   │   ├── input_file_not_found.args
    │   │   ├── input_file_not_found.bend
    │   │   ├── net_size_too_large.args
    │   │   ├── net_size_too_large.bend
    │   │   ├── no_check_net_size.args
    │   │   ├── no_check_net_size.bend
    │   │   ├── run_add.args
    │   │   ├── run_add.bend
    │   │   ├── run_pretty.args
    │   │   ├── run_pretty.bend
    │   │   ├── tuple_readback.args
    │   │   ├── tuple_readback.bend
    │   │   ├── warn_and_err.args
    │   │   └── warn_and_err.bend
    │   ├── compile_entrypoint/
    │   │   └── foo.bend
    │   ├── compile_file/
    │   │   ├── 360_no_scope.bend
    │   │   ├── add_args.bend
    │   │   ├── addition.bend
    │   │   ├── addition_const.bend
    │   │   ├── ask_outside_do.bend
    │   │   ├── church_one.bend
    │   │   ├── church_zero.bend
    │   │   ├── complicated_dup.bend
    │   │   ├── crlf.bend
    │   │   ├── cyclic_global_lam.bend
    │   │   ├── def_pat_unscoped.bend
    │   │   ├── dup_apply.bend
    │   │   ├── dup_global_lam.bend
    │   │   ├── elif.bend
    │   │   ├── elif_fun.bend
    │   │   ├── elif_no_else.bend
    │   │   ├── erased_dup.bend
    │   │   ├── error_data_def_name.bend
    │   │   ├── error_messages.bend
    │   │   ├── f24_oper.bend
    │   │   ├── fst_snd.bend
    │   │   ├── global_lam.bend
    │   │   ├── i24_oper.bend
    │   │   ├── id.bend
    │   │   ├── infer_dup.bend
    │   │   ├── inlining.bend
    │   │   ├── just_a_name.bend
    │   │   ├── just_data.bend
    │   │   ├── just_paren.bend
    │   │   ├── just_rule_paren.bend
    │   │   ├── let_substitution.bend
    │   │   ├── let_tup.bend
    │   │   ├── lets.bend
    │   │   ├── long_name.bend
    │   │   ├── match.bend
    │   │   ├── mismatched_ask_statements.bend
    │   │   ├── missing_adt_eq.bend
    │   │   ├── missing_ctrs.bend
    │   │   ├── missing_pat.bend
    │   │   ├── names_starting_with_keywords.bend
    │   │   ├── nested_ctr_wrong_arity.bend
    │   │   ├── nested_let.bend
    │   │   ├── number_too_large.bend
    │   │   ├── nums.bend
    │   │   ├── op2.bend
    │   │   ├── redex_order.bend
    │   │   ├── redex_order_recursive.bend
    │   │   ├── ref_to_main.bend
    │   │   ├── ref_to_ref.bend
    │   │   ├── repeated_bind_rule.bend
    │   │   ├── simple_tup.bend
    │   │   ├── switch_all_patterns.bend
    │   │   ├── switch_in_switch_arg.bend
    │   │   ├── switch_incomplete.bend
    │   │   ├── switch_unscoped_lambda.bend
    │   │   ├── top_level_name_slashslash.bend
    │   │   ├── tup.bend
    │   │   ├── tup_add.bend
    │   │   ├── unbound_unscoped_var.bend
    │   │   ├── unbound_var.bend
    │   │   ├── unbound_var_scope.bend
    │   │   ├── unbound_with_tup_pattern.bend
    │   │   ├── underscore.bend
    │   │   ├── unexpected_top_char.bend
    │   │   ├── unscoped_dup_use.bend
    │   │   ├── unscoped_supercombinator.bend
    │   │   ├── unused_let.bend
    │   │   ├── unused_unscoped_bind.bend
    │   │   ├── variable_name_double_underscore.bend
    │   │   ├── vicious_circles.bend
    │   │   ├── warn_and_err.bend
    │   │   ├── with_clause_parse_err.bend
    │   │   ├── wrong_ctr_arity.bend
    │   │   ├── wrong_ctr_var_arity.bend
    │   │   ├── wrong_nums.bend
    │   │   └── wrong_unicode_escape.bend
    │   ├── compile_file_o_all/
    │   │   ├── addition.bend
    │   │   ├── addition_var_fst.bend
    │   │   ├── adt_option_and.bend
    │   │   ├── adt_string.bend
    │   │   ├── and.bend
    │   │   ├── bad_parens_making_erased_let.bend
    │   │   ├── bool.bend
    │   │   ├── cyclic_dup.bend
    │   │   ├── double_main.bend
    │   │   ├── eta_chain.bend
    │   │   ├── ex0.bend
    │   │   ├── ex2.bend
    │   │   ├── example.bend
    │   │   ├── exp.bend
    │   │   ├── expr.bend
    │   │   ├── extracted_match_pred.bend
    │   │   ├── fst.bend
    │   │   ├── fst_fst.bend
    │   │   ├── hvm1_main.bend
    │   │   ├── inline_app.bend
    │   │   ├── inlining.bend
    │   │   ├── linearize_match.bend
    │   │   ├── list_merge_sort.bend
    │   │   ├── list_reverse.bend
    │   │   ├── match_adt_non_exhaustive.bend
    │   │   ├── match_dup_and_reconstruction.bend
    │   │   ├── match_mult_linearization.bend
    │   │   ├── match_num_explicit_bind.bend
    │   │   ├── match_tup.bend
    │   │   ├── merge_definitions.bend
    │   │   ├── non_exhaustive_and.bend
    │   │   ├── non_exhaustive_different_types.bend
    │   │   ├── non_exhaustive_pattern.bend
    │   │   ├── non_exhaustive_tree.bend
    │   │   ├── num_pattern_with_var.bend
    │   │   ├── recursive_combinator_inactive.bend
    │   │   ├── repeated_name_trucation.bend
    │   │   ├── scrutinee_reconstruction.bend
    │   │   ├── self_ref.bend
    │   │   ├── snd.bend
    │   │   ├── spacing.bend
    │   │   ├── spacing2.bend
    │   │   ├── str.bend
    │   │   ├── sum_predicates.bend
    │   │   ├── tagged_dup.bend
    │   │   ├── tagged_lam.bend
    │   │   ├── tagged_sup.bend
    │   │   ├── unapplied_eta.bend
    │   │   ├── unscoped_eta.bend
    │   │   ├── var_shadows_ref.bend
    │   │   └── weekday.bend
    │   ├── compile_file_o_no_all/
    │   │   ├── bitonic_sort.bend
    │   │   ├── list_reverse.bend
    │   │   ├── redex_order.bend
    │   │   └── sum_tree.bend
    │   ├── compile_long/
    │   │   ├── huge_tree.bend
    │   │   └── long_str_file.bend
    │   ├── desugar_file/
    │   │   ├── ask_branch.bend
    │   │   ├── bind_syntax.bend
    │   │   ├── combinators.bend
    │   │   ├── deref_loop.bend
    │   │   ├── dup_linearization.bend
    │   │   ├── local_def_shadow.bend
    │   │   ├── main_aux.bend
    │   │   ├── mapper_syntax.bend
    │   │   ├── switch_with_use.bend
    │   │   ├── tree_syntax.bend
    │   │   ├── use_id.bend
    │   │   ├── use_shadow.bend
    │   │   └── used_once_names.bend
    │   ├── encode_pattern_match/
    │   │   ├── adt_tup_era.bend
    │   │   ├── and3.bend
    │   │   ├── bool.bend
    │   │   ├── bool_tup.bend
    │   │   ├── box.bend
    │   │   ├── common.bend
    │   │   ├── concat.bend
    │   │   ├── concat_def.bend
    │   │   ├── def_tups.bend
    │   │   ├── definition_merge.bend
    │   │   ├── expr.bend
    │   │   ├── flatten_era_pat.bend
    │   │   ├── full_map.bend
    │   │   ├── is_some_some.bend
    │   │   ├── list_merge_sort.bend
    │   │   ├── list_str_encoding_undeclared_fn.bend
    │   │   ├── list_str_encoding_undeclared_map.bend
    │   │   ├── match_adt_unscoped_in_arm.bend
    │   │   ├── match_adt_unscoped_lambda.bend
    │   │   ├── match_adt_unscoped_var.bend
    │   │   ├── match_auto_linearization.bend
    │   │   ├── match_bind.bend
    │   │   ├── match_num_adt_tup_parser.bend
    │   │   ├── match_num_pred.bend
    │   │   ├── match_syntax.bend
    │   │   ├── merge_recursive.bend
    │   │   ├── no_patterns.bend
    │   │   ├── non_matching_fst_arg.bend
    │   │   ├── ntup_sum.bend
    │   │   ├── pattern_match_encoding.bend
    │   │   ├── switch_in_switch_arg.bend
    │   │   ├── var_only.bend
    │   │   └── weekday.bend
    │   ├── hangs/
    │   │   ├── bad_dup_interaction.bend
    │   │   └── recursive_with_unscoped.bend
    │   ├── import_system/
    │   │   ├── import_ctr_syntax.bend
    │   │   ├── import_main.bend
    │   │   ├── import_main2.bend
    │   │   ├── import_main3.bend
    │   │   ├── import_type.bend
    │   │   ├── import_types.bend
    │   │   ├── imports.bend
    │   │   ├── imports_alias.bend
    │   │   ├── imports_alias_shadow.bend
    │   │   ├── imports_conflict.bend
    │   │   ├── imports_file_and_dir.bend
    │   │   ├── imports_file_and_dir_conflict.bend
    │   │   ├── imports_shadow.bend
    │   │   ├── imports_shadow2.bend
    │   │   └── lib/
    │   │       ├── MyOption.bend
    │   │       ├── a/
    │   │       │   └── b.bend
    │   │       ├── a.bend
    │   │       ├── bool_xor.bend
    │   │       ├── ctr_type.bend
    │   │       ├── defs.bend
    │   │       ├── file_and_dir/
    │   │       │   ├── w.bend
    │   │       │   └── y.bend
    │   │       ├── file_and_dir.bend
    │   │       ├── folder/
    │   │       │   ├── import_entry3.bend
    │   │       │   └── myFun.bend
    │   │       ├── import_entry.bend
    │   │       ├── import_entry2.bend
    │   │       ├── myFun.bend
    │   │       ├── nums.bend
    │   │       └── types.bend
    │   ├── io/
    │   │   ├── eof.txt
    │   │   ├── load.bend
    │   │   ├── load.txt
    │   │   ├── load_fail.bend
    │   │   ├── read_line_eof.bend
    │   │   ├── store.bend
    │   │   ├── store.txt
    │   │   ├── store_fail.bend
    │   │   └── utf8.bend
    │   ├── linear_readback/
    │   │   └── church_mul.bend
    │   ├── mutual_recursion/
    │   │   ├── a_b_c.bend
    │   │   ├── len.bend
    │   │   ├── merged.bend
    │   │   ├── multiple.bend
    │   │   └── odd_even.bend
    │   ├── parse_file/
    │   │   ├── bad_floating.bend
    │   │   ├── bend_missing_else.bend
    │   │   ├── era.bend
    │   │   ├── fold_missing_case.bend
    │   │   ├── fun_def.bend
    │   │   ├── fun_def_name.bend
    │   │   ├── if_missing_else.bend
    │   │   ├── imp_map.bend
    │   │   ├── imp_program.bend
    │   │   ├── match_missing_case.bend
    │   │   ├── multi_line_comment.bend
    │   │   ├── redefinition_builtin.bend
    │   │   ├── redefinition_ctr_with_fun.bend
    │   │   ├── redefinition_fun_imp.bend
    │   │   ├── redefinition_imp_fun.bend
    │   │   ├── redefinition_type_with_object.bend
    │   │   ├── redefinition_with_def_between.bend
    │   │   ├── redefinition_with_object_between.bend
    │   │   ├── redefinition_with_type_between.bend
    │   │   ├── repeated_adt_name.bend
    │   │   ├── repeated_datatype_name.bend
    │   │   ├── scape_chars.bend
    │   │   ├── strange_pattern.bend
    │   │   ├── tab.bend
    │   │   ├── tup_with_signed.bend
    │   │   ├── tuple_assign.bend
    │   │   ├── tuple_commas.bend
    │   │   └── tuple_need_parens.bend
    │   ├── prelude/
    │   │   ├── applies_function_to_map.bend
    │   │   ├── get_values_from_map.bend
    │   │   ├── lists_to_map.bend
    │   │   ├── map_checked_test.bend
    │   │   ├── map_contains_test.bend
    │   │   └── set_node_when_empty.bend
    │   ├── readback_hvm/
    │   │   ├── addition.bend
    │   │   ├── bad_net.bend
    │   │   ├── bad_net1.bend
    │   │   ├── bad_net3.bend
    │   │   ├── complicated_dup.bend
    │   │   ├── fst_snd.bend
    │   │   ├── id.bend
    │   │   ├── invalid_op2_op2.bend
    │   │   ├── match.bend
    │   │   ├── nested_let.bend
    │   │   ├── nested_tup.bend
    │   │   ├── number.bend
    │   │   ├── simple_tup.bend
    │   │   └── tup_add.bend
    │   ├── run_entrypoint/
    │   │   └── foo.bend
    │   ├── run_file/
    │   │   ├── 360_no_scope.bend
    │   │   ├── addition.bend
    │   │   ├── adt_match.bend
    │   │   ├── adt_match_wrong_tag.bend
    │   │   ├── adt_option_and.bend
    │   │   ├── adt_wrong_tag.bend
    │   │   ├── and.bend
    │   │   ├── basic_num_ops.bend
    │   │   ├── bend_fold.bend
    │   │   ├── bitonic_sort.bend
    │   │   ├── bitonic_sort_lam.bend
    │   │   ├── box.bend
    │   │   ├── branch_statements_assignment.bend
    │   │   ├── callcc.bend
    │   │   ├── chars.bend
    │   │   ├── chars_forall.bend
    │   │   ├── chars_lambda.bend
    │   │   ├── checked_scott_encoding.bend
    │   │   ├── comprehension.bend
    │   │   ├── def_bool_num.bend
    │   │   ├── def_num_bool.bend
    │   │   ├── def_tups.bend
    │   │   ├── do_block_mixed.bend
    │   │   ├── dup_global_lam.bend
    │   │   ├── empty.bend
    │   │   ├── encode_decode_utf8.bend
    │   │   ├── erased_side_effect.bend
    │   │   ├── escape_sequences.bend
    │   │   ├── eta.bend
    │   │   ├── example.bend
    │   │   ├── exp.bend
    │   │   ├── expand_main_combinator.bend
    │   │   ├── expand_main_list.bend
    │   │   ├── extracted_match_pred.bend
    │   │   ├── filter_bool_id.bend
    │   │   ├── floating_numbers.bend
    │   │   ├── fold_with_state.bend
    │   │   ├── guide_bend_7tree.bend
    │   │   ├── guide_bend_sequential.bend
    │   │   ├── guide_bend_sum_tree.bend
    │   │   ├── guide_bitonic_sort.bend
    │   │   ├── guide_circle_area.bend
    │   │   ├── guide_distance_4args.bend
    │   │   ├── guide_distance_obj.bend
    │   │   ├── guide_distance_tup.bend
    │   │   ├── guide_enumerate.bend
    │   │   ├── guide_if_age.bend
    │   │   ├── guide_is_even_num.bend
    │   │   ├── guide_is_even_str.bend
    │   │   ├── guide_list_ctrs.bend
    │   │   ├── guide_list_match.bend
    │   │   ├── guide_list_sugar.bend
    │   │   ├── guide_mul2_inline.bend
    │   │   ├── guide_mul2_rec.bend
    │   │   ├── guide_shader_dummy.bend
    │   │   ├── guide_sum.bend
    │   │   ├── hvm_def_cast.bend
    │   │   ├── hvm_def_two_defs.bend
    │   │   ├── id_underscore.bend
    │   │   ├── imp_empty_literals.bend
    │   │   ├── imp_use_statement.bend
    │   │   ├── kind_compiled_tree_sum.bend
    │   │   ├── lam_op2.bend
    │   │   ├── lam_op2_nested.bend
    │   │   ├── let_tup_readback.bend
    │   │   ├── linearize_match.bend
    │   │   ├── list_resugar.bend
    │   │   ├── list_reverse.bend
    │   │   ├── list_reverse_imp.bend
    │   │   ├── list_take.bend
    │   │   ├── list_to_tree.bend
    │   │   ├── mapper_syntax.bend
    │   │   ├── match.bend
    │   │   ├── match_builtins.bend
    │   │   ├── match_mult_linearization.bend
    │   │   ├── match_num_adt_tup_parser.bend
    │   │   ├── match_num_explicit_bind.bend
    │   │   ├── match_num_num_to_char.bend
    │   │   ├── match_num_succ_complex.bend
    │   │   ├── match_str.bend
    │   │   ├── match_sup.bend
    │   │   ├── match_vars.bend
    │   │   ├── math.bend
    │   │   ├── merge_sort.bend
    │   │   ├── mixed_syntax.bend
    │   │   ├── names_hyphen.bend
    │   │   ├── names_hyphen_toplevel.bend
    │   │   ├── nat_add.bend
    │   │   ├── nat_add_num.bend
    │   │   ├── nested_list_and_string.bend
    │   │   ├── nested_map_get.bend
    │   │   ├── nested_map_set.bend
    │   │   ├── nested_str.bend
    │   │   ├── num_cast.bend
    │   │   ├── num_match_missing_var.bend
    │   │   ├── num_pred.bend
    │   │   ├── open.bend
    │   │   ├── open_object.bend
    │   │   ├── open_too_many_ctrs.bend
    │   │   ├── open_undefined_type.bend
    │   │   ├── ops.bend
    │   │   ├── override_list_ctr.bend
    │   │   ├── override_str_ctr.bend
    │   │   ├── pred.bend
    │   │   ├── queue.bend
    │   │   ├── radix_sort_ctr.bend
    │   │   ├── readback_hvm1_main.bend
    │   │   ├── readback_list_other_ctr.bend
    │   │   ├── readback_num_ops.bend
    │   │   ├── recursive_bind.bend
    │   │   ├── recursive_combinator.bend
    │   │   ├── recursive_combinator_nested.bend
    │   │   ├── recursive_match_native.bend
    │   │   ├── ref_resolution.bend
    │   │   ├── repeated_name_truncation.bend
    │   │   ├── scopeless_discard.bend
    │   │   ├── str_concat.bend
    │   │   ├── str_inc.bend
    │   │   ├── str_inc_eta.bend
    │   │   ├── str_len.bend
    │   │   ├── strict_monad_fn.bend
    │   │   ├── sum_tree.bend
    │   │   ├── sup_app.bend
    │   │   ├── sup_reconstruction.bend
    │   │   ├── superposed_is_even.bend
    │   │   ├── tagged_lam.bend
    │   │   ├── tree_to_list.bend
    │   │   ├── tup_list_strings.bend
    │   │   ├── tup_reconstruction.bend
    │   │   ├── tuple_eta.bend
    │   │   ├── tuple_rots.bend
    │   │   ├── unaplied_str.bend
    │   │   ├── unbound_wrap.bend
    │   │   ├── unscoped_never_used.bend
    │   │   ├── unused_dup_var.bend
    │   │   ├── unused_main_var.bend
    │   │   ├── world.bend
    │   │   └── wrong_string.bend
    │   ├── run_lazy/
    │   │   ├── addition.bend
    │   │   ├── adt_match.bend
    │   │   ├── adt_match_wrong_tag.bend
    │   │   ├── adt_option_and.bend
    │   │   ├── adt_wrong_tag.bend
    │   │   ├── and.bend
    │   │   ├── bitonic_sort.bend
    │   │   ├── bitonic_sort_lam.bend
    │   │   ├── box.bend
    │   │   ├── box2.bend
    │   │   ├── callcc.bend
    │   │   ├── chars.bend
    │   │   ├── def_tups.bend
    │   │   ├── dup_global_lam.bend
    │   │   ├── eta.bend
    │   │   ├── example.bend
    │   │   ├── exp.bend
    │   │   ├── extracted_match_pred.bend
    │   │   ├── field_vectorization.bend
    │   │   ├── lam_op2.bend
    │   │   ├── lam_op2_nested.bend
    │   │   ├── let_tup_readback.bend
    │   │   ├── linearize_match.bend
    │   │   ├── list_resugar.bend
    │   │   ├── list_reverse.bend
    │   │   ├── list_take.bend
    │   │   ├── list_to_tree.bend
    │   │   ├── match.bend
    │   │   ├── match_builtins.bend
    │   │   ├── match_mult_linearization.bend
    │   │   ├── match_num_explicit_bind.bend
    │   │   ├── merge_sort.bend
    │   │   ├── nested_list_and_string.bend
    │   │   ├── nested_str.bend
    │   │   ├── num_pred.bend
    │   │   ├── queue.bend
    │   │   ├── radix_sort_ctr.bend
    │   │   ├── recursive_match_native.bend
    │   │   ├── scopeless_discard.bend
    │   │   ├── str_concat.bend
    │   │   ├── str_inc.bend
    │   │   ├── str_inc_eta.bend
    │   │   ├── str_len.bend
    │   │   ├── sum_tree.bend
    │   │   ├── sup_app.bend
    │   │   ├── sup_reconstruction.bend
    │   │   ├── superposed_is_even.bend
    │   │   ├── tagged_lam.bend
    │   │   ├── tup_reconstruction.bend
    │   │   ├── tuple_rots.bend
    │   │   ├── unaplied_str.bend
    │   │   ├── unused_dup_var.bend
    │   │   ├── world.bend
    │   │   └── wrong_string.bend
    │   ├── scott_triggers_unused/
    │   │   └── test.bend
    │   └── simplify_matches/
    │       ├── adt_tup_era.bend
    │       ├── already_flat.bend
    │       ├── bits_dec.bend
    │       ├── complex_with_case.bend
    │       ├── double_unwrap_box.bend
    │       ├── double_unwrap_maybe.bend
    │       ├── flatten_with_terminal.bend
    │       ├── irrefutable_case.bend
    │       ├── linearize_match_all.bend
    │       ├── match_str.bend
    │       ├── nested.bend
    │       ├── nested2.bend
    │       ├── nested_0ary.bend
    │       ├── redundant_with_era.bend
    │       └── wrong_fn_arity.bend
    ├── golden_tests.rs
    └── snapshots/
        ├── check_file__fail_type_bad_rec_fn_adt.bend.snap
        ├── check_file__non_exaustive_limit.bend.snap
        ├── check_file__type_err_match_arm.bend.snap
        ├── cli__compile_all.bend.snap
        ├── cli__compile_inline.bend.snap
        ├── cli__compile_no_opts.bend.snap
        ├── cli__compile_pre_reduce.bend.snap
        ├── cli__compile_strict_loop.bend.snap
        ├── cli__compile_wrong_opt.bend.snap
        ├── cli__custom_hvm_bin.bend.snap
        ├── cli__debug_list_map.bend.snap
        ├── cli__debug_u60_to_nat.bend.snap
        ├── cli__desugar_bool_scott.bend.snap
        ├── cli__desugar_float_combinators.bend.snap
        ├── cli__desugar_linearize_matches.bend.snap
        ├── cli__desugar_linearize_matches_alt.bend.snap
        ├── cli__desugar_merge.bend.snap
        ├── cli__desugar_pretty.bend.snap
        ├── cli__desugar_prune.bend.snap
        ├── cli__gen_hvm_no_eta_by_default.bend.snap
        ├── cli__input_file_not_found.bend.snap
        ├── cli__net_size_too_large.bend.snap
        ├── cli__no_check_net_size.bend.snap
        ├── cli__run_add.bend.snap
        ├── cli__run_pretty.bend.snap
        ├── cli__tuple_readback.bend.snap
        ├── cli__warn_and_err.bend.snap
        ├── compile_entrypoint__foo.bend.snap
        ├── compile_file__360_no_scope.bend.snap
        ├── compile_file__add_args.bend.snap
        ├── compile_file__addition.bend.snap
        ├── compile_file__addition_const.bend.snap
        ├── compile_file__ask_outside_do.bend.snap
        ├── compile_file__church_one.bend.snap
        ├── compile_file__church_zero.bend.snap
        ├── compile_file__complicated_dup.bend.snap
        ├── compile_file__crlf.bend.snap
        ├── compile_file__cyclic_global_lam.bend.snap
        ├── compile_file__def_pat_unscoped.bend.snap
        ├── compile_file__dup_apply.bend.snap
        ├── compile_file__dup_global_lam.bend.snap
        ├── compile_file__elif.bend.snap
        ├── compile_file__elif_fun.bend.snap
        ├── compile_file__elif_no_else.bend.snap
        ├── compile_file__erased_dup.bend.snap
        ├── compile_file__error_data_def_name.bend.snap
        ├── compile_file__error_messages.bend.snap
        ├── compile_file__f24_oper.bend.snap
        ├── compile_file__fst_snd.bend.snap
        ├── compile_file__global_lam.bend.snap
        ├── compile_file__i24_oper.bend.snap
        ├── compile_file__id.bend.snap
        ├── compile_file__infer_dup.bend.snap
        ├── compile_file__inlining.bend.snap
        ├── compile_file__just_a_name.bend.snap
        ├── compile_file__just_data.bend.snap
        ├── compile_file__just_paren.bend.snap
        ├── compile_file__just_rule_paren.bend.snap
        ├── compile_file__let_substitution.bend.snap
        ├── compile_file__let_tup.bend.snap
        ├── compile_file__lets.bend.snap
        ├── compile_file__long_name.bend.snap
        ├── compile_file__match.bend.snap
        ├── compile_file__mismatched_ask_statements.bend.snap
        ├── compile_file__missing_adt_eq.bend.snap
        ├── compile_file__missing_ctrs.bend.snap
        ├── compile_file__missing_pat.bend.snap
        ├── compile_file__names_starting_with_keywords.bend.snap
        ├── compile_file__nested_ctr_wrong_arity.bend.snap
        ├── compile_file__nested_let.bend.snap
        ├── compile_file__number_too_large.bend.snap
        ├── compile_file__nums.bend.snap
        ├── compile_file__op2.bend.snap
        ├── compile_file__redex_order.bend.snap
        ├── compile_file__redex_order_recursive.bend.snap
        ├── compile_file__ref_to_main.bend.snap
        ├── compile_file__ref_to_ref.bend.snap
        ├── compile_file__repeated_bind_rule.bend.snap
        ├── compile_file__simple_tup.bend.snap
        ├── compile_file__switch_all_patterns.bend.snap
        ├── compile_file__switch_in_switch_arg.bend.snap
        ├── compile_file__switch_incomplete.bend.snap
        ├── compile_file__switch_unscoped_lambda.bend.snap
        ├── compile_file__top_level_name_slashslash.bend.snap
        ├── compile_file__tup.bend.snap
        ├── compile_file__tup_add.bend.snap
        ├── compile_file__unbound_unscoped_var.bend.snap
        ├── compile_file__unbound_var.bend.snap
        ├── compile_file__unbound_var_scope.bend.snap
        ├── compile_file__unbound_with_tup_pattern.bend.snap
        ├── compile_file__underscore.bend.snap
        ├── compile_file__unexpected_top_char.bend.snap
        ├── compile_file__unscoped_dup_use.bend.snap
        ├── compile_file__unscoped_supercombinator.bend.snap
        ├── compile_file__unused_let.bend.snap
        ├── compile_file__unused_unscoped_bind.bend.snap
        ├── compile_file__variable_name_double_underscore.bend.snap
        ├── compile_file__vicious_circles.bend.snap
        ├── compile_file__warn_and_err.bend.snap
        ├── compile_file__with_clause_parse_err.bend.snap
        ├── compile_file__wrong_ctr_arity.bend.snap
        ├── compile_file__wrong_ctr_var_arity.bend.snap
        ├── compile_file__wrong_nums.bend.snap
        ├── compile_file__wrong_unicode_escape.bend.snap
        ├── compile_file_o_all__addition.bend.snap
        ├── compile_file_o_all__addition_var_fst.bend.snap
        ├── compile_file_o_all__adt_option_and.bend.snap
        ├── compile_file_o_all__adt_string.bend.snap
        ├── compile_file_o_all__and.bend.snap
        ├── compile_file_o_all__bad_parens_making_erased_let.bend.snap
        ├── compile_file_o_all__bool.bend.snap
        ├── compile_file_o_all__cyclic_dup.bend.snap
        ├── compile_file_o_all__double_main.bend.snap
        ├── compile_file_o_all__eta_chain.bend.snap
        ├── compile_file_o_all__ex0.bend.snap
        ├── compile_file_o_all__ex2.bend.snap
        ├── compile_file_o_all__example.bend.snap
        ├── compile_file_o_all__exp.bend.snap
        ├── compile_file_o_all__expr.bend.snap
        ├── compile_file_o_all__extracted_match_pred.bend.snap
        ├── compile_file_o_all__fst.bend.snap
        ├── compile_file_o_all__fst_fst.bend.snap
        ├── compile_file_o_all__hvm1_main.bend.snap
        ├── compile_file_o_all__inline_app.bend.snap
        ├── compile_file_o_all__inlining.bend.snap
        ├── compile_file_o_all__linearize_match.bend.snap
        ├── compile_file_o_all__list_merge_sort.bend.snap
        ├── compile_file_o_all__list_reverse.bend.snap
        ├── compile_file_o_all__match_adt_non_exhaustive.bend.snap
        ├── compile_file_o_all__match_dup_and_reconstruction.bend.snap
        ├── compile_file_o_all__match_mult_linearization.bend.snap
        ├── compile_file_o_all__match_num_explicit_bind.bend.snap
        ├── compile_file_o_all__match_tup.bend.snap
        ├── compile_file_o_all__merge_definitions.bend.snap
        ├── compile_file_o_all__non_exhaustive_and.bend.snap
        ├── compile_file_o_all__non_exhaustive_different_types.bend.snap
        ├── compile_file_o_all__non_exhaustive_pattern.bend.snap
        ├── compile_file_o_all__non_exhaustive_tree.bend.snap
        ├── compile_file_o_all__num_pattern_with_var.bend.snap
        ├── compile_file_o_all__recursive_combinator_inactive.bend.snap
        ├── compile_file_o_all__repeated_name_trucation.bend.snap
        ├── compile_file_o_all__scrutinee_reconstruction.bend.snap
        ├── compile_file_o_all__self_ref.bend.snap
        ├── compile_file_o_all__snd.bend.snap
        ├── compile_file_o_all__spacing.bend.snap
        ├── compile_file_o_all__spacing2.bend.snap
        ├── compile_file_o_all__str.bend.snap
        ├── compile_file_o_all__sum_predicates.bend.snap
        ├── compile_file_o_all__tagged_dup.bend.snap
        ├── compile_file_o_all__tagged_lam.bend.snap
        ├── compile_file_o_all__tagged_sup.bend.snap
        ├── compile_file_o_all__unapplied_eta.bend.snap
        ├── compile_file_o_all__unscoped_eta.bend.snap
        ├── compile_file_o_all__var_shadows_ref.bend.snap
        ├── compile_file_o_all__weekday.bend.snap
        ├── compile_file_o_no_all__bitonic_sort.bend.snap
        ├── compile_file_o_no_all__list_reverse.bend.snap
        ├── compile_file_o_no_all__redex_order.bend.snap
        ├── compile_file_o_no_all__sum_tree.bend.snap
        ├── compile_long__huge_tree.bend.snap
        ├── compile_long__long_str_file.bend.snap
        ├── desugar_file__ask_branch.bend.snap
        ├── desugar_file__bind_syntax.bend.snap
        ├── desugar_file__combinators.bend.snap
        ├── desugar_file__deref_loop.bend.snap
        ├── desugar_file__dup_linearization.bend.snap
        ├── desugar_file__local_def_shadow.bend.snap
        ├── desugar_file__main_aux.bend.snap
        ├── desugar_file__mapper_syntax.bend.snap
        ├── desugar_file__switch_with_use.bend.snap
        ├── desugar_file__tree_syntax.bend.snap
        ├── desugar_file__use_id.bend.snap
        ├── desugar_file__use_shadow.bend.snap
        ├── desugar_file__used_once_names.bend.snap
        ├── encode_pattern_match__adt_tup_era.bend.snap
        ├── encode_pattern_match__and3.bend.snap
        ├── encode_pattern_match__bool.bend.snap
        ├── encode_pattern_match__bool_tup.bend.snap
        ├── encode_pattern_match__box.bend.snap
        ├── encode_pattern_match__common.bend.snap
        ├── encode_pattern_match__concat.bend.snap
        ├── encode_pattern_match__concat_def.bend.snap
        ├── encode_pattern_match__def_tups.bend.snap
        ├── encode_pattern_match__definition_merge.bend.snap
        ├── encode_pattern_match__expr.bend.snap
        ├── encode_pattern_match__flatten_era_pat.bend.snap
        ├── encode_pattern_match__full_map.bend.snap
        ├── encode_pattern_match__is_some_some.bend.snap
        ├── encode_pattern_match__list_merge_sort.bend.snap
        ├── encode_pattern_match__list_str_encoding_undeclared_fn.bend.snap
        ├── encode_pattern_match__list_str_encoding_undeclared_map.bend.snap
        ├── encode_pattern_match__match_adt_unscoped_in_arm.bend.snap
        ├── encode_pattern_match__match_adt_unscoped_lambda.bend.snap
        ├── encode_pattern_match__match_adt_unscoped_var.bend.snap
        ├── encode_pattern_match__match_auto_linearization.bend.snap
        ├── encode_pattern_match__match_bind.bend.snap
        ├── encode_pattern_match__match_num_adt_tup_parser.bend.snap
        ├── encode_pattern_match__match_num_pred.bend.snap
        ├── encode_pattern_match__match_syntax.bend.snap
        ├── encode_pattern_match__merge_recursive.bend.snap
        ├── encode_pattern_match__no_patterns.bend.snap
        ├── encode_pattern_match__non_matching_fst_arg.bend.snap
        ├── encode_pattern_match__ntup_sum.bend.snap
        ├── encode_pattern_match__pattern_match_encoding.bend.snap
        ├── encode_pattern_match__switch_in_switch_arg.bend.snap
        ├── encode_pattern_match__var_only.bend.snap
        ├── encode_pattern_match__weekday.bend.snap
        ├── examples__bitonic_sort.bend.snap
        ├── examples__bubble_sort.bend.snap
        ├── examples__callcc.bend.snap
        ├── examples__example_fun.bend.snap
        ├── examples__fib.bend.snap
        ├── examples__fusing_add.bend.snap
        ├── examples__fusing_not.bend.snap
        ├── examples__gen_tree.bend.snap
        ├── examples__hello_world.bend.snap
        ├── examples__insertion_sort.bend.snap
        ├── examples__list.bend.snap
        ├── examples__parallel_and.bend.snap
        ├── examples__parallel_hello_world.bend.snap
        ├── examples__parallel_sum.bend.snap
        ├── examples__queue.bend.snap
        ├── examples__quick_sort.bend.snap
        ├── examples__radix_sort.bend.snap
        ├── import_system__import_ctr_syntax.bend.snap
        ├── import_system__import_main.bend.snap
        ├── import_system__import_main2.bend.snap
        ├── import_system__import_main3.bend.snap
        ├── import_system__import_type.bend.snap
        ├── import_system__import_types.bend.snap
        ├── import_system__imports.bend.snap
        ├── import_system__imports_alias.bend.snap
        ├── import_system__imports_alias_shadow.bend.snap
        ├── import_system__imports_conflict.bend.snap
        ├── import_system__imports_file_and_dir.bend.snap
        ├── import_system__imports_file_and_dir_conflict.bend.snap
        ├── import_system__imports_shadow.bend.snap
        ├── import_system__imports_shadow2.bend.snap
        ├── io__load.bend.snap
        ├── io__load_fail.bend.snap
        ├── io__read_line_eof.bend.snap
        ├── io__store.bend.snap
        ├── io__store_fail.bend.snap
        ├── io__utf8.bend.snap
        ├── linear_readback__church_mul.bend.snap
        ├── mutual_recursion__a_b_c.bend.snap
        ├── mutual_recursion__len.bend.snap
        ├── mutual_recursion__merged.bend.snap
        ├── mutual_recursion__multiple.bend.snap
        ├── mutual_recursion__odd_even.bend.snap
        ├── parse_file__bad_floating.bend.snap
        ├── parse_file__bend_missing_else.bend.snap
        ├── parse_file__era.bend.snap
        ├── parse_file__fold_missing_case.bend.snap
        ├── parse_file__fun_def.bend.snap
        ├── parse_file__fun_def_name.bend.snap
        ├── parse_file__if_missing_else.bend.snap
        ├── parse_file__imp_map.bend.snap
        ├── parse_file__imp_program.bend.snap
        ├── parse_file__match_missing_case.bend.snap
        ├── parse_file__multi_line_comment.bend.snap
        ├── parse_file__redefinition_builtin.bend.snap
        ├── parse_file__redefinition_ctr_with_fun.bend.snap
        ├── parse_file__redefinition_fun_imp.bend.snap
        ├── parse_file__redefinition_imp_fun.bend.snap
        ├── parse_file__redefinition_type_with_object.bend.snap
        ├── parse_file__redefinition_with_def_between.bend.snap
        ├── parse_file__redefinition_with_object_between.bend.snap
        ├── parse_file__redefinition_with_type_between.bend.snap
        ├── parse_file__repeated_adt_name.bend.snap
        ├── parse_file__repeated_datatype_name.bend.snap
        ├── parse_file__scape_chars.bend.snap
        ├── parse_file__strange_pattern.bend.snap
        ├── parse_file__tab.bend.snap
        ├── parse_file__tup_with_signed.bend.snap
        ├── parse_file__tuple_assign.bend.snap
        ├── parse_file__tuple_commas.bend.snap
        ├── parse_file__tuple_need_parens.bend.snap
        ├── prelude__applies_function_to_map.bend.snap
        ├── prelude__get_values_from_map.bend.snap
        ├── prelude__lists_to_map.bend.snap
        ├── prelude__map_checked_test.bend.snap
        ├── prelude__map_contains_test.bend.snap
        ├── prelude__set_node_when_empty.bend.snap
        ├── readback_hvm__addition.bend.snap
        ├── readback_hvm__bad_net.bend.snap
        ├── readback_hvm__bad_net1.bend.snap
        ├── readback_hvm__bad_net3.bend.snap
        ├── readback_hvm__complicated_dup.bend.snap
        ├── readback_hvm__fst_snd.bend.snap
        ├── readback_hvm__id.bend.snap
        ├── readback_hvm__invalid_op2_op2.bend.snap
        ├── readback_hvm__match.bend.snap
        ├── readback_hvm__nested_let.bend.snap
        ├── readback_hvm__nested_tup.bend.snap
        ├── readback_hvm__number.bend.snap
        ├── readback_hvm__simple_tup.bend.snap
        ├── readback_hvm__tup_add.bend.snap
        ├── run_file__360_no_scope.bend.snap
        ├── run_file__addition.bend.snap
        ├── run_file__adt_match.bend.snap
        ├── run_file__adt_match_wrong_tag.bend.snap
        ├── run_file__adt_option_and.bend.snap
        ├── run_file__adt_wrong_tag.bend.snap
        ├── run_file__and.bend.snap
        ├── run_file__basic_num_ops.bend.snap
        ├── run_file__bend_fold.bend.snap
        ├── run_file__bitonic_sort.bend.snap
        ├── run_file__bitonic_sort_lam.bend.snap
        ├── run_file__box.bend.snap
        ├── run_file__branch_statements_assignment.bend.snap
        ├── run_file__callcc.bend.snap
        ├── run_file__chars.bend.snap
        ├── run_file__chars_forall.bend.snap
        ├── run_file__chars_lambda.bend.snap
        ├── run_file__checked_scott_encoding.bend.snap
        ├── run_file__comprehension.bend.snap
        ├── run_file__def_bool_num.bend.snap
        ├── run_file__def_num_bool.bend.snap
        ├── run_file__def_tups.bend.snap
        ├── run_file__do_block_mixed.bend.snap
        ├── run_file__dup_global_lam.bend.snap
        ├── run_file__empty.bend.snap
        ├── run_file__encode_decode_utf8.bend.snap
        ├── run_file__erased_side_effect.bend.snap
        ├── run_file__escape_sequences.bend.snap
        ├── run_file__eta.bend.snap
        ├── run_file__example.bend.snap
        ├── run_file__exp.bend.snap
        ├── run_file__expand_main_combinator.bend.snap
        ├── run_file__expand_main_list.bend.snap
        ├── run_file__extracted_match_pred.bend.snap
        ├── run_file__filter_bool_id.bend.snap
        ├── run_file__floating_numbers.bend.snap
        ├── run_file__fold_with_state.bend.snap
        ├── run_file__guide_bend_7tree.bend.snap
        ├── run_file__guide_bend_sequential.bend.snap
        ├── run_file__guide_bend_sum_tree.bend.snap
        ├── run_file__guide_bitonic_sort.bend.snap
        ├── run_file__guide_circle_area.bend.snap
        ├── run_file__guide_distance_4args.bend.snap
        ├── run_file__guide_distance_obj.bend.snap
        ├── run_file__guide_distance_tup.bend.snap
        ├── run_file__guide_enumerate.bend.snap
        ├── run_file__guide_if_age.bend.snap
        ├── run_file__guide_is_even_num.bend.snap
        ├── run_file__guide_is_even_str.bend.snap
        ├── run_file__guide_list_ctrs.bend.snap
        ├── run_file__guide_list_match.bend.snap
        ├── run_file__guide_list_sugar.bend.snap
        ├── run_file__guide_mul2_inline.bend.snap
        ├── run_file__guide_mul2_rec.bend.snap
        ├── run_file__guide_shader_dummy.bend.snap
        ├── run_file__guide_sum.bend.snap
        ├── run_file__hvm_def_cast.bend.snap
        ├── run_file__hvm_def_two_defs.bend.snap
        ├── run_file__id_underscore.bend.snap
        ├── run_file__imp_empty_literals.bend.snap
        ├── run_file__imp_use_statement.bend.snap
        ├── run_file__kind_compiled_tree_sum.bend.snap
        ├── run_file__lam_op2.bend.snap
        ├── run_file__lam_op2_nested.bend.snap
        ├── run_file__let_tup_readback.bend.snap
        ├── run_file__linearize_match.bend.snap
        ├── run_file__list_resugar.bend.snap
        ├── run_file__list_reverse.bend.snap
        ├── run_file__list_reverse_imp.bend.snap
        ├── run_file__list_take.bend.snap
        ├── run_file__list_to_tree.bend.snap
        ├── run_file__mapper_syntax.bend.snap
        ├── run_file__match.bend.snap
        ├── run_file__match_builtins.bend.snap
        ├── run_file__match_mult_linearization.bend.snap
        ├── run_file__match_num_adt_tup_parser.bend.snap
        ├── run_file__match_num_explicit_bind.bend.snap
        ├── run_file__match_num_num_to_char.bend.snap
        ├── run_file__match_num_succ_complex.bend.snap
        ├── run_file__match_str.bend.snap
        ├── run_file__match_sup.bend.snap
        ├── run_file__match_vars.bend.snap
        ├── run_file__math.bend.snap
        ├── run_file__merge_sort.bend.snap
        ├── run_file__mixed_syntax.bend.snap
        ├── run_file__names_hyphen.bend.snap
        ├── run_file__names_hyphen_toplevel.bend.snap
        ├── run_file__nat_add.bend.snap
        ├── run_file__nat_add_num.bend.snap
        ├── run_file__nested_list_and_string.bend.snap
        ├── run_file__nested_map_get.bend.snap
        ├── run_file__nested_map_set.bend.snap
        ├── run_file__nested_str.bend.snap
        ├── run_file__num_cast.bend.snap
        ├── run_file__num_match_missing_var.bend.snap
        ├── run_file__num_pred.bend.snap
        ├── run_file__open.bend.snap
        ├── run_file__open_object.bend.snap
        ├── run_file__open_too_many_ctrs.bend.snap
        ├── run_file__open_undefined_type.bend.snap
        ├── run_file__ops.bend.snap
        ├── run_file__override_list_ctr.bend.snap
        ├── run_file__override_str_ctr.bend.snap
        ├── run_file__pred.bend.snap
        ├── run_file__queue.bend.snap
        ├── run_file__radix_sort_ctr.bend.snap
        ├── run_file__readback_hvm1_main.bend.snap
        ├── run_file__readback_list_other_ctr.bend.snap
        ├── run_file__readback_num_ops.bend.snap
        ├── run_file__recursive_bind.bend.snap
        ├── run_file__recursive_combinator.bend.snap
        ├── run_file__recursive_combinator_nested.bend.snap
        ├── run_file__recursive_match_native.bend.snap
        ├── run_file__ref_resolution.bend.snap
        ├── run_file__repeated_name_truncation.bend.snap
        ├── run_file__scopeless_discard.bend.snap
        ├── run_file__str_concat.bend.snap
        ├── run_file__str_inc.bend.snap
        ├── run_file__str_inc_eta.bend.snap
        ├── run_file__str_len.bend.snap
        ├── run_file__strict_monad_fn.bend.snap
        ├── run_file__sum_tree.bend.snap
        ├── run_file__sup_app.bend.snap
        ├── run_file__sup_reconstruction.bend.snap
        ├── run_file__superposed_is_even.bend.snap
        ├── run_file__tagged_lam.bend.snap
        ├── run_file__tree_to_list.bend.snap
        ├── run_file__tup_list_strings.bend.snap
        ├── run_file__tup_reconstruction.bend.snap
        ├── run_file__tuple_eta.bend.snap
        ├── run_file__tuple_rots.bend.snap
        ├── run_file__unaplied_str.bend.snap
        ├── run_file__unbound_wrap.bend.snap
        ├── run_file__unscoped_never_used.bend.snap
        ├── run_file__unused_dup_var.bend.snap
        ├── run_file__unused_main_var.bend.snap
        ├── run_file__world.bend.snap
        ├── run_file__wrong_string.bend.snap
        ├── scott_triggers_unused__test.bend.snap
        ├── simplify_matches__adt_tup_era.bend.snap
        ├── simplify_matches__already_flat.bend.snap
        ├── simplify_matches__bits_dec.bend.snap
        ├── simplify_matches__complex_with_case.bend.snap
        ├── simplify_matches__double_unwrap_box.bend.snap
        ├── simplify_matches__double_unwrap_maybe.bend.snap
        ├── simplify_matches__flatten_with_terminal.bend.snap
        ├── simplify_matches__irrefutable_case.bend.snap
        ├── simplify_matches__linearize_match_all.bend.snap
        ├── simplify_matches__match_str.bend.snap
        ├── simplify_matches__nested.bend.snap
        ├── simplify_matches__nested2.bend.snap
        ├── simplify_matches__nested_0ary.bend.snap
        ├── simplify_matches__redundant_with_era.bend.snap
        └── simplify_matches__wrong_fn_arity.bend.snap

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: Create a report to help us improve.
body:
 - type: markdown
   attributes: 
     value: |
      ### Bug Report
      Your issue might have been already reported. Please check the [frequently asked questions](https://github.com/HigherOrderCO/Bend/blob/main/FAQ.md) first, especially if you're having trouble installing or running the GPU runtime.
      Then, please check the [existing issues](https://github.com/HigherOrderCO/Bend/issues) to see if someone else already reported it. If you find a similar issue, respond with a reaction or any additional information that you feel may be helpful.
      Before opening a new issue, make sure that your Bend and HVM versions are up-to-date.

      ### For Windows Users
      There is currently no native way to make Bend work on windows, as a temporary workaround, please use [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install).
  
 - type: textarea
   attributes:
    label: Reproducing the behavior
    description: A clear and concise description of what the bug is.
    value: |
      Example:
       Running command...
       With code....
       Error...
       Expected behavior....
   validations:
    required: true
 
 - type: textarea
   attributes:
    label: System Settings
    description: Your System's settings
    value: |
     Example:
      - HVM: [e.g. HVM 2.0.13]
      - Bend: [e.g. 0.2.11]
      - OS: [e.g. Linux (Ubuntu 22.04)]
      - CPU: [e.g. Intel i9-14900KF]
      - GPU: [e.g. RTX 4090]
      - Cuda Version [e.g. release 12.4, V12.4.131]
   validations:
     required: true

 - type: textarea
   attributes:
    label: Additional context
    description: Add any other context about the problem here (Optional). 
   


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links: 
    - name: HVM Related Issues
      url: https://github.com/HigherOrderCO/HVM/issues/new/choose
      about: For HVM related Issues, please Report them on the HVM repository.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest a feature that you think should be added.
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/workflows/checks.yml
================================================
name: Checks

on:
  pull_request:
  merge_group:
  push:
    branches:
      - main

jobs:
  check:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-check-${{ hashFiles('**/Cargo.lock') }}
      - run: RUSTFLAGS="-D warnings" cargo check --all-targets
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-test-${{ hashFiles('**/Cargo.lock') }}
      - run: cargo install hvm
      - run: cargo test -- --test-threads=1
  clippy:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-clippy-${{ hashFiles('**/Cargo.lock') }}
      - run: RUSTFLAGS="-D warnings" cargo clippy
  fmt:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt
      - run: cargo fmt --check
  cspell:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3
      - uses: streetsidesoftware/cspell-action@v5
        with:
          incremental_files_only: false
          config: ./cspell.json
          files: |
            **/*.rs
            **/*.md


================================================
FILE: .gitignore
================================================
/target
*.snap.new
.out.hvm
.DS_Store
.vscode

================================================
FILE: .rustfmt.toml
================================================
edition = "2021"
max_width = 110
# won't add \r\n on windows machines, better on diffs
newline_style = "Unix"
use_small_heuristics = "Max"
tab_spaces = 2
use_field_init_shorthand = true
use_try_shorthand = true


================================================
FILE: CHANGELOG.md
================================================
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project does not currently adhere to a particular versioning scheme.

## [0.2.38] - 2025-02-23

### Added

- Emit a warning when a rule in a pattern matching function is unreachable. ([#736][gh-736])

### Fixed
- Fix type checker not properly unifying all the arms of a match expression. ([#734][gh-734])
- Fix signed numbers (i24 and f24) not being parsed after parenthesis `(`. ([#748][gh-748])

## [0.2.37] - 2024-10-18

### Fixed

- Fix variable binding in pattern matching when the irrefutable pattern optimization occurs. ([#618][gh-618])
- Don't warn on unused generated definitions. ([#514][gh-514])
- Fix local definitions not being desugared properly. ([#623][gh-623])
- Expand references to functions generated by the `float_combinators` pass inside the main function. ([#642][gh-642])
- Expand references inside constructors in the main function. ([#643][gh-643])
- Fix readback when hvm net has `a{n}` or `x{n}` vars. ([#659][gh-659])
- Fix imported constructors not being updated to Constructor expression. ([#674][gh-674])
- Fix parse error on parenthesized eraser. ([#675][gh-675])
- Fix IO/FS/read_line when the line ends with a EOF. ([#638][gh-638])
- Fix lambda body being parsed as tuple in imp syntax. ([#706][gh-706])

### Added

- Add type system for Bend. ([#615][gh-615], [#679][gh-679], see [Type Checking](docs/type-checking.md))
- Add import system. ([#544][gh-544])
- Add multi line comment `#{ ... #}` syntax. ([#595][gh-595])
- Add error message when input file is not found. ([#513][gh-513])
- Add `List/filter` and `String/{equals, filter}` builtins.
- Add IO functions for loading dynamically linked libraries (`IO/DyLib/open`, `IO/DyLib/call`, `IO/DyLib/close`). ([#621][gh-621])

### Changed

- Change tuple syntax to not require parentheses in some cases. ([#554][gh-554])
- Improve error messages in branching statements. ([#464][gh-464])
- Change branches to support ending with ask statements. ([#629][gh-629])
- Improve hexadecimal and binary floating numbers. ([#648][gh-648])
- Change IO functions to return Result. ([#657][gh-657])
- Revamp the diagnostics system and parser to show more error and warning messages ([#673][gh-673])

## [0.2.36] - 2024-07-04

### Changed

- Improve error messages for redefinition of types and objects. ([#485][gh-485])
- Don't allow tabs to be used for indentation or spacing. ([#463][gh-463])
- Rename builtin function `sleep` to `IO/nanosleep`. ([#581][gh-581])
- Equational number pattern compilation to use the predecessor variable when possible. ([#470][gh-470])
- Rename `Bytes/decode_utf8` to `String/decode_utf8` and `Bytes/decode_ascii` to `String/decode_ascii`.
- Rename `log` to `Math/log` and `atan2` to `Math/atan2`.

### Fixed

- Fix readback of numeric operations. ([#467][gh-467])
- Propagate the "builtin" attribute of definitions when extracting functions from `bend` and `fold` syntax.
- Panic while using unscoped variables on definition patterns. ([#468][gh-468])

### Added

- Create new type of top-level definition for writing native HVM definitions. ([#586][gh-586])
- Add `log` and `atan2` builtin functions. ([#583][gh-583])
- Add `to_f24`, `to_u24` and `to_i24` number casting builtin functions. ([#582][gh-582])
- Add `IO/sleep` builtin function to sleep for a given amount of seconds as a float. ([#581][gh-581])
- Add primitive file IO functions `IO/FS/{read, write, seek, open, close}`. ([#573][gh-573])
- Add encoding/decoding builtin functions `Bytes/{decode_utf8, decode_ascii} String/{encode_ascii, decode_ascii} Utf8/{decode_character, REPLACEMENT_CHARACTER}`. ([#580][gh-580])
- Add `IO/print` function to print to stdout. ([#579][gh-579])
- Add `IO/input` function to read a line of input from stdin. ([#579][gh-579])
- Add file IO utilities `IO/FS/{read_file, write_file, read_line, read_to_end}`. ([#578][gh-578])
- Add list utilities `List/{length, reverse, flatten, concat}`.
- Add `elif` chains to functional syntax. ([#596][gh-596])
- Add local definitions to imperative syntax. ([#562][gh-562])
- Add local definitions to functional syntax.
- Add repeated field name error message.
- Add `Math` builtin functions. ([#570][gh-570])
- Add primitive file IO function `IO/FS/flush`. ([#598][gh-598])
- Changed `bend run` to `bend run-rs` and `bend run` defaults to the C implementation. ([#620][gh-620])

## [0.2.35] - 2024-06-06

### Changed

- Make lambda `Term` with bind patterns display as `let` terms. ([#466][gh-466])

## [0.2.34] - 2024-06-05

### Added

- Add syntax for "less than or equal" `<=` and "greater than or equal" `>=` numeric operators. ([#451][gh-451])

## [0.2.33] - 2024-06-05

### Added

- Implement `expand_main`, a compilation pass that expands references in the entry point function. ([#424][gh-424])

### Changed

- Make the `float_combinators` pass no longer extract in the entry point function. ([#424][gh-424])

## [0.2.32] - 2024-06-05

### Added

- Implement the built-in `Tree` datatype. ([#528][gh-528])
- Implement `![]` and `!` syntax for `Tree` literals. ([#528][gh-528])
- Create a changelog.

### Changed

- Move the builtins documentation to `/docs`.

## [0.2.30] - 2024-06-04

### Changed

- No longer expand generated recursive definitions. ([#502][gh-502])

## [0.2.29] - 2024-06-04

### Added

- Support custom HVM binaries. ([#479][gh-479])

### Changed

- Make monadic blocks lazy by deferring execution of continuations with free vars. ([#526][gh-526])

## [0.2.28] - 2024-05-30

### Added

- Support mapper statements. ([#465][gh-465])

## [0.2.27] - 2024-05-29

### Changed

- Make `with` clauses take a bind and an argument. ([#516][gh-516])

## [0.2.26] - 2024-05-28

### Changed

- `do` keyword to `with`. ([#494][gh-494])

### Added

- `wrap` alias inside `with` blocks. ([#494][gh-494])

## [0.2.25] - 2024-05-28

### Added

- Generated constructor tags. ([#512][gh-512])

## [0.2.24] - 2024-05-27

### Added

- `elif` chains. ([#427][gh-427])

## [0.2.23] - 2024-05-27

### Fixed

- `gen-cu` and `gen-c` commands after move to HVM syntax tree.

## [0.2.22] - 2024-05-26

### Changed

- Rust channel from `nightly` to `stable`. ([#486][gh-486])

## [0.2.21] - 2024-05-25

### Changed

- HVM syntax tree for representing inets inside the compiler. ([#475][gh-475])

## [0.2.20] - 2024-05-24

### Fixed

- Map getters generation inside map setters. ([#489][gh-489])

## [0.2.19] - 2024-05-24

### Changed

- Variable names to not allow `__`. ([#478][gh-478])

## [0.2.18] - 2024-05-24

### Fixed

- Nested map getters generation. ([#483][gh-483])

## [0.2.17] - 2024-05-23

### Changed

- Top-level names to not start with `//`. ([#443][gh-443])

## [0.2.16] - 2024-05-23

### Added

- New `IO` builtins.

### Fixed

- Definition pruning transformation.

## [0.2.15] - 2024-05-22

### Fixed

- Exponentiation miscompilation. ([#444][gh-444])

## [0.2.14] - 2024-05-22

### Changed

- Inet level eta-reduction pass to not reduce number nodes.

## [0.2.13] - 2024-05-22

### Fixed

- Scope of `fork`.

## [0.2.12] - 2024-05-22

### Changed

- Functional syntax `data` keyword to `type`.

## [0.2.11] - 2024-05-22

### Added

- List comprehension.
- Bit shift left and Bit shift right.

## [0.2.10] - 2024-05-21

### Changed

- Numbers to new HVM number operation format.
- Rules definition to be in a single block.
- Disabled `net-size` check by default.

## [0.2.9] - 2024-05-19

### Changed

- Readback error messages.

## [0.2.8] - 2024-05-19

### Changed

- Increase max net size.
- `check-net-size` to be optional.

## [0.2.7] - 2024-05-17

### Added

- Apache-2.0 License.

## [0.2.6] - 2024-05-17

### Added

- Simple readback of tuples.

### Changed

- Imperative syntax to require `,` in list-like builtins.

### Fixed

- Empty map parsing.

## [0.2.5] - 2024-05-16

### Added

- Exponentiation `**` operator.

### Changed

- `go` to `fork` inside `bend` statement.

## [0.2.4] - 2024-05-15

### Changed

- New version for hvm-core compatibility.

## [0.2.3] - 2024-05-15

### Changed

- Rename to `bend-lang`.
- Use crates.io HVM.

### Added

- List readback.

## [0.2.2] - 2024-05-15

### Changed

- Comments from `//` to `#`.
- Lambda syntax and built-in constructor names.
- Fold to require explicit state passing.

### Added

- Record types and destructuring.
- String readback.

## [0.2.1] - 2024-05-15

### Fixed

- Number parsing in imperative syntax.

### Changed

- Require `\n` after return.

## [0.2.0] - 2024-05-14

- Initial public release of Bend.

[0.2.0]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.0
[0.2.1]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.1
[0.2.2]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.2
[0.2.3]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.3
[0.2.4]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.4
[0.2.5]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.5
[0.2.6]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.6
[0.2.7]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.7
[0.2.8]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.8
[0.2.9]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.9
[0.2.10]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.10
[0.2.11]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.11
[0.2.12]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.12
[0.2.13]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.13
[0.2.14]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.14
[0.2.15]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.15
[0.2.16]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.16
[0.2.17]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.17
[0.2.18]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.18
[0.2.19]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.19
[0.2.20]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.20
[0.2.21]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.21
[0.2.22]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.22
[0.2.23]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.23
[0.2.24]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.24
[0.2.25]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.25
[0.2.26]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.26
[0.2.27]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.27
[0.2.28]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.28
[0.2.29]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.29
[0.2.30]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.30
[0.2.32]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.32
[0.2.33]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.33
[0.2.34]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.34
[0.2.35]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.35
[0.2.36]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.36
[0.2.37]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.37
[0.2.38]: https://github.com/HigherOrderCO/Bend/releases/tag/0.2.38
[gh-424]: https://github.com/HigherOrderCO/Bend/issues/424
[gh-427]: https://github.com/HigherOrderCO/Bend/issues/427
[gh-443]: https://github.com/HigherOrderCO/Bend/issues/443
[gh-444]: https://github.com/HigherOrderCO/Bend/issues/444
[gh-451]: https://github.com/HigherOrderCO/Bend/issues/451
[gh-463]: https://github.com/HigherOrderCO/Bend/issues/463
[gh-464]: https://github.com/HigherOrderCO/Bend/issues/464
[gh-465]: https://github.com/HigherOrderCO/Bend/issues/465
[gh-466]: https://github.com/HigherOrderCO/Bend/issues/466
[gh-467]: https://github.com/HigherOrderCO/Bend/issues/467
[gh-468]: https://github.com/HigherOrderCO/Bend/issues/468
[gh-470]: https://github.com/HigherOrderCO/Bend/issues/470
[gh-475]: https://github.com/HigherOrderCO/Bend/issues/475
[gh-478]: https://github.com/HigherOrderCO/Bend/issues/478
[gh-479]: https://github.com/HigherOrderCO/Bend/issues/479
[gh-483]: https://github.com/HigherOrderCO/Bend/issues/483
[gh-485]: https://github.com/HigherOrderCO/Bend/issues/485
[gh-486]: https://github.com/HigherOrderCO/Bend/issues/486
[gh-489]: https://github.com/HigherOrderCO/Bend/issues/489
[gh-494]: https://github.com/HigherOrderCO/Bend/issues/494
[gh-502]: https://github.com/HigherOrderCO/Bend/issues/502
[gh-512]: https://github.com/HigherOrderCO/Bend/issues/512
[gh-513]: https://github.com/HigherOrderCO/Bend/issues/513
[gh-514]: https://github.com/HigherOrderCO/Bend/issues/514
[gh-516]: https://github.com/HigherOrderCO/Bend/issues/516
[gh-526]: https://github.com/HigherOrderCO/Bend/issues/526
[gh-528]: https://github.com/HigherOrderCO/Bend/issues/528
[gh-544]: https://github.com/HigherOrderCO/Bend/pull/544
[gh-554]: https://github.com/HigherOrderCO/Bend/issues/554
[gh-562]: https://github.com/HigherOrderCO/Bend/issues/562
[gh-570]: https://github.com/HigherOrderCO/Bend/issues/570
[gh-573]: https://github.com/HigherOrderCO/Bend/issues/573
[gh-578]: https://github.com/HigherOrderCO/Bend/issues/578
[gh-579]: https://github.com/HigherOrderCO/Bend/issues/579
[gh-580]: https://github.com/HigherOrderCO/Bend/issues/580
[gh-581]: https://github.com/HigherOrderCO/Bend/issues/581
[gh-582]: https://github.com/HigherOrderCO/Bend/issues/582
[gh-583]: https://github.com/HigherOrderCO/Bend/issues/583
[gh-586]: https://github.com/HigherOrderCO/Bend/issues/586
[gh-595]: https://github.com/HigherOrderCO/Bend/issues/595
[gh-596]: https://github.com/HigherOrderCO/Bend/issues/596
[gh-598]: https://github.com/HigherOrderCO/Bend/issues/598
[gh-618]: https://github.com/HigherOrderCO/Bend/issues/618
[gh-620]: https://github.com/HigherOrderCO/Bend/issues/620
[gh-621]: https://github.com/HigherOrderCO/Bend/issues/621
[gh-623]: https://github.com/HigherOrderCO/Bend/issues/623
[gh-629]: https://github.com/HigherOrderCO/Bend/issues/629
[gh-638]: https://github.com/HigherOrderCO/Bend/issues/638
[gh-642]: https://github.com/HigherOrderCO/Bend/issues/642
[gh-643]: https://github.com/HigherOrderCO/Bend/issues/643
[gh-648]: https://github.com/HigherOrderCO/Bend/issues/648
[gh-657]: https://github.com/HigherOrderCO/Bend/issues/657
[gh-659]: https://github.com/HigherOrderCO/Bend/pull/659
[gh-673]: https://github.com/HigherOrderCO/Bend/pull/673
[gh-674]: https://github.com/HigherOrderCO/Bend/issues/674
[gh-675]: https://github.com/HigherOrderCO/Bend/issues/675
[gh-706]: https://github.com/HigherOrderCO/Bend/issues/706
[gh-734]: https://github.com/HigherOrderCO/Bend/issues/734
[gh-736]: https://github.com/HigherOrderCO/Bend/issues/736
[gh-748]: https://github.com/HigherOrderCO/Bend/issues/748


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Bend

Thank you for considering contributing to Bend!

## How to Contribute

### Reporting bugs

1. **Check for existing issues:** Before you create a new issue, please do a search in [our issues](https://github.com/HigherOrderCO/Bend/issues) to see if the issue or feature request has already been filed.
2. **Create a new issue:** If you find no issue or your issue differs, [create a new issue](https://github.com/HigherOrderCO/Bend/issues/new?template=bug_report.yml) and provide detailed information, including steps to reproduce the problem.

### Suggesting Enhancements

1. **Check for existing suggestions:** Before suggesting a new feature, please check if it's already been suggested in [our issues](https://github.com/HigherOrderCO/Bend/issues).
2. **Create a new suggestion:** If you find no similar suggestion, [create a new suggestion issue](https://github.com/HigherOrderCO/Bend/issues/new?template=feature_request.md) and provide detailed information about the enhancement and why it would be useful.

### Checking HVM Issues

Since Bend depends on HVM, some issues might be related to HVM rather than Bend itself. Please also check the [HVM issues page](https://github.com/HigherOrderCO/HVM/issues) to see if your issue has already been reported there.

### Submitting Changes

1. **Fork the repository:** Create your own fork of the repository on GitHub.
2. **Create a new branch:** Make your changes in a new branch in your forked repository.
3. **Run formatting and linting checks:** Before submitting your changes, ensure your code is properly formatted and linted:
   - Run `cargo fmt` to format your code.
   - Run `cargo clippy` to lint your code.
4. **Run tests:** Ensure all tests pass and update any test results:
   - Run `cargo insta test` to run the tests.
      > If insta is not available as a cargo command, install it using `cargo install cargo-insta`.
   - Run `cargo insta review` to save any changes to the test results.
5. **Submit a pull request:** Once your changes are ready, submit a pull request from your branch to the `main` branch of the Bend Repository

We appreciate every contribution!


================================================
FILE: Cargo.toml
================================================
[package]
name = "bend-lang"
description = "A high-level, massively parallel programming language"
license = "Apache-2.0"
version = "0.2.38"
edition = "2021"
rust-version = "1.74"
exclude = ["tests/"]

[lib]
name = "bend"
path = "src/lib.rs"

[[bin]]
name = "bend"
path = "src/main.rs"
required-features = ["cli"]

[profile.release]
lto = true

[features]
default = ["cli"]
cli = ["dep:clap"]

[dependencies]
TSPL = "0.0.13"
clap = { version = "4.4.1", features = ["derive"], optional = true }
highlight_error = "0.1.1"
hvm = "=2.0.22"
indexmap = "2.2.3"
interner = "0.2.1"
itertools = "0.11.0"
loaned = "0.1.0"
stacker = "0.1"

[dev-dependencies]
insta = "1.34.0"
stdext = "0.3.1"
walkdir = "2.3.3"

[profile.test]
opt-level = 2


================================================
FILE: FAQ.md
================================================
# Known Issues and Frequently Asked Questions

## Installation and Setup

### Can I run this on Windows?
- We're still working on the windows support, for the moment, please use [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install).

### I'm getting a `CUDA not available!` error even though I have it installed?
- CUDA support is enable only during installation. If you first installed HVM and then installed CUDA and `nvcc`, please try to install HVM again.

### I'm getting a `Failed to launch kernels (error code invalid argument)!` error.
- The current iteration of the `hvm.cu` was written with the RTX 4090 in mind, and won't work on older GPUs, since they contain about half of the newer GPUs shared memory, for better understanding please refer to [HVM#283](https://github.com/HigherOrderCO/HVM/issues/283). We are working on support for older GPUs and will release it soon.

### I get "Command `bend` not found" after installing, what do I do?
- If you are on Unix system (or WSL) then most likely bend did not add itself to the PATH variable in your rc file. To remedy this:
  - Determine if you are using bash or zsh (check for presence of `~/.bashrc` or `~/.zshrc`)
  - Make change to the relevant file by running `echo -n 'export PATH=$PATH:$HOME/.cargo/bin' >> ~/.bashrc`
    - use `~/.zshrc` in place of `~/.bashrc` in the case you are on zsh system
  - You will then need to run `source ~/.bashrc` or `source ~/.zshrc` for the changes to take effect immediately
  - Try running `bend` once more - it should work now! 

### I got an error when installing HVM on Linux
- If the error happens when compiling the CUDA runtime or contains anything regarding `ccbin`, please refer to [HVM#291](https://github.com/HigherOrderCO/HVM/issues/291).

- If the error contains anything regarding `libc` missing, please refer to [HVM#355](https://github.com/HigherOrderCO/Bend/issues/355)

### Can I run this on AMD/Intel/Apple GPUs?
- We plan on adding support to many other GPUs as soon as the CUDA version is sufficiently stable.

### What GPUs are supported?
GPUs with >=96KB L1 cache per SM *should* work. This includes the following:
| GPU                         | Tested? |
|-----------------------------|---------|
| RTX 4090                    | Yes     |
| All Other Desktop 40 Series | No      |
| All Desktop 30 Series       | No      |
| All Mobile 40 Series        | No      |
| All Mobile 30 Series        | No      |

## Using Bend

### How do I use IO?
- IO is still being developed and is expected to come soon.

### How to do FFI?
- Not as soon as basic IO, but planned or at least something similar to FFI.

### Are there any Libraries, Packages etc?
- A package manager will be added soon.

### Why are my numbers giving me wrong results?
Some possibilities:
- Your program is causing an overflow on 24-bit number values.
- Your program is doing operations on numbers of different types. (e.g. `2.0 + 1` is not allowed, you must use `2.0 + 1.0`)
- Floating point numbers are currently bugged and are interpreted incorrectly in some cases.
- There's a bug with signed integers numbers that flips that sometimes flips the order of the operations.

### I'm getting an error of failed assertion
- HVM currently has a bug in its conversion of f32 to f24 and it's unable to read the number 0.0. We already have a fix that we're working on.


================================================
FILE: FEATURES.md
================================================
## Features

Bend offers two flavors of syntax, the user-friendly python-like syntax "Imp" (the default) and the core ML/Haskell-like syntax "Fun".
You can read the full reference for both of them [here](docs/syntax.md), but these examples will use the first one.

To see some more complex examples programs, check out the [examples](examples/) folder.

### Basic features

We can start with a basic program that adds the numbers 3 and 2.
```py
def main() -> u24:
  return 2 + 3
```

Running this program will show the number 5.
Be careful with `run` since it will not show any warnings by default. Before running a new program, it's useful to first `check` it.

Bend programs consist of a series of function definitions, always starting with a function called `main` or `Main`.

Functions can receive arguments both directly and using a lambda abstraction.

```py
# These two are equivalent
def add(x: u24, y: u24) -> u24:
  return x + y

def add2() -> (u24 -> u24 -> u24): 
  return lambda x, y: x + y
```

You can then call this function like this:

```py
def main() -> u24:
  sum = add(2, 3)
  return sum
```

### Data types

You can bundle multiple values into a single value using a tuple or a struct.

```py
# With a tuple
def tuple_fst(x: (a, b)) -> a:
  # This destructures the tuple into the two values it holds.
  # '*' means that the value is discarded and not bound to any variable.
  (fst, *) = x
  return fst

# With an object (similar to what other languages call a struct, a class or a record)
object Pair(a, b) { fst: a, snd: b }

def Pair/fst(x: Pair(a, b)) -> a:
  match x:
    case Pair:
      return x.fst

# We can also access the fields of an object after we `open` it.
def Pair/fst_2(x: Pair(a, b)) -> a:
  open Pair: x
  return x.fst

# This is how we can create new objects.
def Pair/with_one(x: a) -> Pair(a, u24):
  return Pair{ fst: x, snd: 1 }

# The function can be named anything, but by convention we use Type/function_name.
def Pair/swap(x: Pair(a, b)) -> Pair(b, a):
  open Pair: x
  # We can also call the constructor like any normal function.
  return Pair(x.snd, x.fst)
```

For more complicated data structures, we can use `type` to define algebraic data types.

```py
type MyTree:
  Node { val, ~left, ~right }
  Leaf
```

This defines a constructor function for each variant of the type, with names `MyTree/Node` and `MyTree/Leaf`.

Like most things in bend (except tuples and numbers), types defined with `type` and `object` become lambda encoded functions.
You can read how this is done internally by the compiler in [Defining data types](docs/defining-data-types.md) and [Pattern matching](docs/pattern-matching.md).

### Optional typing

Types in Bend are completely optional - you can write programs without any type annotations, but we'll be typing every function for clarity. For instace:
```py
def main():
  sum = add(2, 3)
  return sum
```
Here, this program will run just fine and return the exact same result as the example shown in [Basic features](#basic-features)

### Pattern matching

We can pattern match on values of a data type to perform different actions depending on the variant of the value.

```py
def Maybe/or_default(x: Maybe(T), default: T) -> T:
  match x:
    case Maybe/Some:
      # We can access the fields of the variant using 'matched.field'
      return x.value
    case Maybe/None:
      return default
```

### Folding and bending

We use `~` to indicate that a field is recursive.
This allows us to easily create and consume these recursive data structures with `bend` and `fold`.

`fold` is a recursive `match` that you can use to transform and consume data structures.
`bend` is a pure recursive loop that is very useful for generating data structures.

```py
#{
  Sum all the values in the tree.
#}
def MyTree.sum(x: MyTree) -> u24:
  fold x:
    # The fold is implicitly called for fields marked with '~' in their definition.
    case MyTree/Node:
      return x.val + x.left + x.right
    case MyTree/Leaf:
      return 0

def main() -> u24:
  bend val = 0:
    when val < 10:
      # 'fork' calls the bend recursively with the provided values.
      x = MyTree/Node { val:val, left:fork(val + 1), right:fork(val + 1) }
    else:
      # 'else' is the base case, when the condition fails.
      x = MyTree/Leaf

  return MyTree.sum(x)
```
> Note: since MyTree has no type annotations, its fields will be considered of type `Any`, which partially disables the type checker for these values. Thus the fact that `x` is holding a tree of u24 and not a tree of anything else won't be checked and it's up to the user to make sure it's correct.


These are equivalent to inline recursive functions that create a tree and consume it.

```py
def MyTree.sum(x: MyTree) -> u24:
  match x:
    case MyTree/Node:
      return x.val + MyTree.sum(x.left) + MyTree.sum(x.right)
    case MyTree/Leaf:
      return 0

def main_bend(val: u24) -> MyTree:
  if val < 10:
    return MyTree/Node(val, main_bend(val + 1), main_bend(val + 1))
  else:
    return MyTree/Leaf

def main() -> u24:
  x = main_bend(0)
  return MyTree.sum(x)
```

Making your program around folding trees is a very good way of making it parallelizable, since each core can be dispatched to work on a different branch of the tree.

You can also pass some state variables to `fold` just like the variables used in a `bend`.
If you give a `fold` some state, then you necessarily need to pass it by calling the folded fields of the matched value, like passing an additional argument to the fold call.

```py
# This function substitutes each value in the tree with the sum of all the values before it.
def MyTree.map_sum(x: MyTree) -> MyTree:
  acc = 0
  fold x with acc:
    case MyTree/Node:
      # `x.left` and `x.right` are called with the new state value.
      # Note that values are copied if you use them more than once, so you don't want to pass something very large.
      return MyTree/Node{ val: x.val + acc, left: x.left(x.val + acc), right: x.right(x.val + acc) }
    case MyTree/Leaf:
      return x
```

This allows `fold` to be a very powerful and generic tool that can be used to implement most pure data transformations.

### Some caveats and limitations

_Attention_: Note that despite the ADT syntax sugars, Bend is an _untyped_ language and the compiler will not stop you from using values incorrectly, which can lead to very unexpected results.
For example, the following program will compile just fine even though `!=` is only defined for native numbers:

```py
def main():
  bend val = [0, 1, 2, 3]:
    when val != []:
      match val:
        case List/Cons:
          x = val.head + fork(val.tail)
        case List/Nil:
          x = 0
    else:
      x = 0
  return x
```

Running this program will show `λ* *` and not the expected `6`.

It's also important to note that Bend is linear (technically affine), meaning that every variable is only used once. When a variable is used more than once, the compiler will automatically insert a duplication.
Duplications efficiently share the same value between two locations, only cloning a value when it's actually needed, but their exact behaviour is slightly more complicated than that and escapes normal lambda-calculus rules.
You can read more about it in [Dups and sups](docs/dups-and-sups.md) and learn how pattern matching avoids this problem in [Pattern matching](docs/pattern-matching.md).

To use a variable twice without duplicating it, you can use a `use` statement.
It inlines clones of some value in the statements that follow it.

```py
def foo(x):
  use result = (1, x)
  return (result, result)

# Is equivalent to
def foo(x):
  return ((1, x), (1, x))
```

Note that any variable in the `use` will end up being duplicated.

Bend supports recursive functions of unrestricted depth:

```py
def native_num_to_adt(n: u24) -> Nat:
  if n == 0:
    return Nat/Zero
  else:
    return Nat/Succ(native_num_to_adt(n - 1))
```

If your recursive function is not based on pattern matching syntax (like `if`, `match`, `fold`, etc) you have to be careful to avoid an infinite loop.

```py
# A scott-encoded list folding function.
# Writing it like this will cause an infinite loop.
def scott_list.add(xs, add):
  return xs( λxs.head xs.tail: λc n: (c (xs.head + add), scott_list.add(xs.tail, add)))

# Instead we want to write it like this;
def scott_list.add(xs, add):
  return xs(
    λxs.head xs.tail: λadd: λc n: (c (xs.head + add) scott_list.sum(xs.tail, add)),
    λadd: λc λn: n,
    add
  )
# These functions can't be typed with bend's type system.
```

Since Bend is eagerly executed, some situations will cause function applications to always be expanded, which can lead to looping situations.
You can read how to avoid this in [Lazy definitions](docs/lazy-definitions.md).

### Numbers

Bend has native numbers and operations.

```py
def main() -> (u24, i24, f24):
  a = 1      # A 24 bit unsigned integer.
  b = +2     # A 24 bit signed integer.
  c = -3     # Another signed integer, but with negative value.
  d = 1.0    # A 24 bit floating point number.
  e = +0.001 # Also a float.
  return (a * 2, b - c, d / e)
```

Unsigned numbers are written as just the number.
Signed numbers are written with a `+` or `-` sign.
Floating point numbers must have the decimal point `.` and can optionally take a sign `+` or `-`.

The three number types are fundamentally different.
If you mix two numbers of different types HVM will interpret the binary representation of one of them incorrectly, leading to incorrect results. Which number is interpreted incorrectly depends on the situation and shouldn't be relied on for now.

You can use `switch` to pattern match on unsigned native numbers:

```py
switch x = 4:
  # From '0' to n, ending with the default case '_'.
  case 0:  "zero"
  case 1:  "one"
  case 2:  "two"
  # The default case binds the name <arg>-<n>
  # where 'arg' is the name of the argument and 'n' is the next number.
  # In this case, it's 'x-3', which will have value (4 - 3) = 1
  case _:  String.concat("other: ", (String.from_num x-3))
```

You can also convert between the number types using the builtin casting functions.
Here's some of the builtin functions you can use to cast any native number into the corresponding type:

```py
def main() -> _:
  x = f24/to_i24(1.0)
  y = u24/to_f24(2)
  z = i24/to_u24(-3)

  return (x, y, z)
```
You can find the other casting functions and their declarations at [builtins.md](docs/builtins.md).
### Other builtin types

Bend has Lists and Strings, which support Unicode characters.
This is how they are defined:
```py
type String:
  Nil
  Cons { head: u24, ~tail: String }
type List(T):
  Nil
  Cons { head: T, ~tail: List(T) }
```

```py
# Here's an example of a List of Strings
def main() -> List(String):
  return ["You: Hello, 🌎", "🌎: Hello, user"]
```

A string is desugared to a String data type containing two constructors, `String/Cons` and `String/Nil`.
List also becomes a type with two constructors, `List/Cons` and `List/Nil`.

```py
# When you write this
def StrEx() -> String:
  return "Hello"
def ids() -> List(u24):
  return [1, 2, 3]

# The compiler converts it to this
def StrEx() -> String:
  return String/Cons('H', String/Cons('e', String/Cons('l', String/Cons('l', String/Cons('o', String/Nil)))))
def ids() -> List(u24):
  return List/Cons(1, List/Cons(2, List/Cons(3, List/Nil)))
```

Characters are delimited by `'` `'` and support Unicode escape sequences. They are encoded as a U24 with the unicode codepoint as their value.

```py
# These two are equivalent
def chars() -> List(u24):
  return ['A', '\u{4242}', '🌎']

def chars2()  -> List(u24):
  return [65, 0x4242, 0x1F30E]
```

Bend has a built-in binary tree Map data structure where the key is a `u24` value, meaning you can use numbers, characters, and symbols as keys.

Maps are delimited by `{` `}` and its entries are separated by commas. A key-value entry in a map is denoted using a colon `:`. For example:

```py
{ 42: [4, 2] } # 42 is the key and [4, 2] is the value
```

A Map is desugared to a Map data type containing two constructors `Map/Leaf` and `Map/Node`.

```py
# When you write this
def empty_map() -> Map(T):
  return {}

def init_map() -> Map(String):
  return { 1: "one", 2: "two", `blue`: "0x0000FF" }

def main() -> String:
  map = init_map
  one = map[1]    # map getter syntax
  map[0] = "zero" # map setter syntax
  return one

# The compiler converts it to this
def empty_map() -> Map(T):
  return Map/Leaf

def init_map() -> Map(String): 
  map = Map/set(Map/Leaf, 1, "one")
  map = Map/set(map, 2, "two")
  return map

def main() -> String:
  map = init_map
  (one, map) = Map/get(map, 1)
  map = Map/set(map, 0, "zero")
  return one

# The builtin Map type definition
type Map(T):
  Node { value: Maybe(T), ~left: Map(T), ~right: Map(T) }
  Leaf 
```

Notice that the getter and setter syntax induces an order on things using the map, since every get or set operation depends on the value of the previous map.
> **_NOTE:_** Do not get mistaken with lists creation syntax, that also uses `[` `]`.

### Mixing syntaxes

As was said in the beginning, Bend offers two flavors of syntax.
You can mix and match them freely in your program, as long as each function uses only one flavor.

```py
type Bool:
  True
  False

def is_odd(x: u24) -> Bool:
  switch x:
    case 0:
      return Bool/False
    case _:
      return is_even(x-1)

is_even(n: u24): u24 = switch n {
  0: Bool/True
  _: (is_odd n-1)
}

main = (is_odd 20)
```

### More features

Key:

- &#128215;: Basic resources
- &#128217;: Intermediate resources
- &#128213;: Advanced resources

Other features are described in the following documentation files:

- &#128215; Lazy definitions: [Making recursive definitions lazy](docs/lazy-definitions.md)
- &#128215; Data types: [Defining data types](docs/defining-data-types.md)
- &#128215; Pattern matching: [Pattern matching](docs/pattern-matching.md)
- &#128215; Native numbers and operations: [Native numbers](docs/native-numbers.md)
- &#128215; Builtin definitions: [Builtins](docs/builtins.md)
- &#128215; CLI arguments: [CLI arguments](docs/cli-arguments.md)
- &#128217; Duplications and superpositions: [Dups and sups](docs/dups-and-sups.md)
- &#128217; Scopeless lambdas: [Using scopeless lambdas](docs/using-scopeless-lambdas.md)
- &#128213; Fusing functions: [Writing fusing functions](docs/writing-fusing-functions.md)

## Further reading

- &#128217; [Compilation and readback](docs/compilation-and-readback.md)
- &#128217; [Old HVM wiki learning material](https://github.com/HigherOrderCO/HVM/wiki/HVM-Wiki). It is outdated, but it can still teach you some of the basics.


================================================
FILE: GUIDE.md
================================================
# Bend in X minutes - the ultimate guide!

Bend is a high-level, massively parallel programming language. That means it
feels like Python, but scales like CUDA. It runs on CPUs and GPUs, and you don't
have to do anything to make it parallel: as long as your code isn't "helplessly
sequential", it **will** use 1000's of threads!

While cool, Bend is far from perfect. In absolute terms it is still not so fast.
Compared to SOTA compilers like GCC or GHC, our code gen is still embarrassingly
bad, and there is a lot to improve. And, of course, in this beginning, there
will be tons of instability and bugs. That said, it does what it promises:
scaling horizontally with cores. And that's really cool! If you'd like to be an
early adopter of this interesting tech, this guide will teach you how to apply
Bend to build parallel programs in a new way!

For a more technical dive, check HVM2's
[paper](http://paper.HigherOrderCO.com/). For an entertaining, intuitive
explanation, see HVM1's classic
[HOW.md](https://github.com/HigherOrderCO/HVM/blob/master/guide/HOW.md). But if
you just want to dive straight into action - this guide is for you. Let's go!

## Installation

### Install dependencies

#### On Linux

```sh
# Install Rust if you haven't it already.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# For the C version of Bend, use GCC. We recommend a version up to 12.x.
sudo apt install gcc
```

For the CUDA runtime [install the CUDA toolkit for Linux](https://developer.nvidia.com/cuda-downloads?target_os=Linux) version 12.x.

#### On Mac

```sh
# Install Rust if you haven't it already.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# For the C version of Bend, use GCC. We recommend a version up to 12.x.
brew install gcc
```

### Install Bend

1. Install HVM2 by running:

```sh
# HVM2 is HOC's massively parallel Interaction Combinator evaluator.
cargo install hvm

# This ensures HVM is correctly installed and accessible.
hvm --version
```

2. Install Bend by running:

```sh
# This command will install Bend
cargo install bend-lang

# This ensures Bend is correctly installed and accessible.
bend --version
```

## Hello, World!

As we said, Bend _feels_ like Python - in some ways. It is high-level, you can
easily create objects and lists, there are ifs and loops. Yet, it is different:
there is some Haskell in it, in the sense algebraic datatypes, pattern-matching
and recursion play an important role. This is how its `"Hello, world!"` looks:

```python
def main():
  return "Hello, world!"
```
To run the program above, type:
```
bend run-rs main.bend
```
Wait - there is something strange there. Why `return`, not `print`? Well, _for
now_ (you'll read these words a lot), Bend's IO is in an experimental stage. We plan on
fully introducing it very soon! Nevertheless, here's an example on how you can use IO on bend to print `"Hello, world!"`:

```python
def main() -> IO(u24):
  with IO:
    * <- IO/print("Hello, world!\n")
    return wrap(0)
```
To run the program above, type:

```
bend run-c main.bend
```

If all goes well, you should see `"Hello, world!"` in both cases. The `bend run-rs` command uses
the reference interpreter, which is slow, whereas the `bend run-c` command uses the much faster C interpreter, but bend can run even faster! In a few moments, we'll teach you how to run your code in parallel, on both CPUs and GPUs. For now, let's learn some
fundamentals!

## Basic Functions and Datatypes

In Bend, functions are pure: they receive something, and they return something.
That's all. Here is a function that tells you how old you are:

```python
def am_i_old(age: u24) -> String:
  if age < 18:
    return "you're a kid"
  else:
    return "you're an adult"

def main() -> String:
  return am_i_old(32)
```

That is simple enough, isn't it? Here is one that returns the euclidean distance between
two points:

```python
def distance(ax: f24, ay: f24, bx: f24, by: f24) -> f24:
  dx = bx - ax
  dy = by - ay
  return (dx * dx + dy * dy) ** 0.5

def main() -> f24:
  return distance(10.0, 10.0, 20.0, 20.0)
```

This isn't so pretty. Could we use tuples instead? Yes:

```python
def distance(a: (f24, f24), b: (f24, f24)) -> f24:
  (ax, ay) = a
  (bx, by) = b
  dx = bx - ax
  dy = by - ay
  return (dx * dx + dy * dy) ** 0.5

def main() -> f24:
  return distance((10.0, 10.0), (20.0, 20.0))
```

So far, this does look like Python, doesn't it? What about objects? Well - here,
there is a difference. In Python, we have classes. In Bend, we just have the
objects themselves. This is how we create a 2D vector:

```python
object V2 { x, y }

def distance(a: V2, b: V2) -> f24:
  open V2: a
  open V2: b
  dx = b.x - a.x
  dy = b.y - a.y
  return (dx * dx + dy * dy) ** 0.5

def main() -> f24:
  return distance(V2 { x: 10.0, y: 10.0 }, V2 { x: 20.0, y: 20.0 })
```

This doesn't look too different, does it? What is that `open` thing, though? It
just tells Bend to _consume_ the vector, `a`, "splitting" it into its
components, `a.x` and `a.y`. Is that really necessary? Actually, no - not
really. But, _for now_, it is. This has to do with the fact Bend is an affine
language, which... well, let's not get into that. For now, just remember we
need `open` to access fields.

Bend comes with 3 built-in numeric types: `u24`, `i24`, `f24`. That's quite
small, we admit. Soon, we'll have larger types. For now, that's what we got.
The `u24` type is written like `123` or `0xF`. The `i24` type requires a sign,
as in, `+7` or `-7`. The `f24` type uses `.`, like `3.14`.

Other than tuples, Bend has another, very general, way to encode data:
datatypes! These are just "objects with tags". A classic example of this is a
"shape", which can be either a circle or a rectangle. It is defined like this:

```python
type Shape:
  Circle { radius }
  Rectangle { width, height }

def area(shape: Shape) -> f24:
  match shape:
    case Shape/Circle:
      return 3.14 * shape.radius ** 2.0
    case Shape/Rectangle:
      return shape.width * shape.height

def main() -> f24:
  return area(Shape/Circle { radius: 10.0 })
```

In this example, `Shape` is a datatype with two variants: `Circle` and
`Rectangle`. The `area` function uses pattern matching to handle each variant
appropriately. Just like objects need `open`, datatypes need `match`, which
give us access to fields in each respective case.

Datatypes are very general. From matrices, to JSON, to quadtrees, every type of
data can be represented as a datatype (I mean, that's the name!). In fact,
lists - which, on Python, are actually stored as arrays - are represented using
datatypes on Bend. Specifically, the type:

```python
type List:
  Nil
  Cons { head, ~tail }
```

Here, the `Nil` variant represents an empty list, and the `Cons` variant
represents a concatenation between an element (`head`) and another list
(`tail`). That way, the `[1,2,3]` list could be written as:

```python
def main() -> List(u24):
  my_list = List/Cons{head: 1, tail: List/Cons{head: 2, tail: List/Cons{head: 3, tail: List/Nil}}}
  return my_list
```

Obviously - that's terrible. So, you can write just instead:

```python
def main() -> List(u24):
  my_list = [1, 2, 3]
  return my_list
```

Which is decent. But while it is written the same as in Python, it is important
to understand it is just the `List` datatype, which means we can operate on it
using the `match` notation. For example:

```python
def main() -> u24:
  my_list = [1, 2, 3]
  match my_list:
    case List/Cons:
      return my_list.head
    case List/Nil:
      return 0
```

Will return `1`, which is the first element.

> **_NOTE:_** Despite creating lists with `[` `]`, the syntax used for accessing values as in `type[key]` is actually related to the `Map` built-in type.

We also have a syntax sugar for strings in Bend, which is just a list of `u24`
characters (UTF-16 encoded). The `"Hello, world!"` type we've seen used it!

> **_NOTE:_** The actual type used for strings is `String`, which has `String/Cons` and `String/Nil` just like `List` does.

Bend also has inline functions, which work just like Python:

```python
def main() -> u24:
  mul_2 = lambda x: x * 2
  return mul_2(7)
```

Except without the annoying syntax restrictions. You can also shorten it as `λ`,
if you can somehow type that.

You can also match on native numbers (`u24`) using the `switch` statement:

```python
def slow_mul2(n: u24) -> u24:
  switch n:
    case 0:
      return 0
    case _:
      return 2 + slow_mul2(n-1)

def main() -> u24:
  return slow_mul2(7)
```

The `if-else` syntax is a third option to branch, other than `match` and
`switch`. It expects a `u24` (`1` for `true` and `0` for `false`):

```python
def is_even(n: u24) -> u24:
  if n % 2 == 0:
    return 1
  else:
    return 0

def main() -> u24:
  return is_even(7)
```

_note - some types, like tuples, aren't being pretty-printed correctly after
computation. This will be fixed in the future (TM)_

## The Dreaded Immutability

Finally, let's get straight to the fun part: how do we implement parallel
algorithms with Bend? Just kidding. Before we get there, let's talk about loops.
You might have noticed we have avoided them so far. That wasn't by accident.
There is an important aspect on which Bend diverges from Python, and aligns with
Haskell: **variables are immutable**. Not "by default". They just **are**. For
example, in Bend, we're not allowed to write:

```python
def parity(x: u24) -> String:
  result = "odd"
  if x % 2 == 0:
    result = "even"
  return result
```

... because that would require mutating the `result` variable. Instead, we should write:

```python
def is_even(x: u24) -> String:
  if x % 2 == 0:
    return "even"
  else:
    return "odd"

def main() -> String:
  return is_even(7)
```

Which is immutable. If that sounds annoying, that's because **it is**. Don't
let anyone tell you otherwise. We are aware of that, and we have many ideas on
how to improve this, making Bend feel even more Python-like. For now, we have to
live with it. But, wait... if variables are immutable... how do we even do
loops? For example:

```python
def sum(x: u24) -> u24:
  total = 0
  for i in range(10)
    total += i
  return total
```

Here, the entire way the algorithm works is by mutating the `total` variable.
Without mutability, loops don't make sense. The good news is Bend has _something
else_ that is equally as - actually, more - powerful. And learning it is really
worth your time. Let's do it!

## Folds and Bends

### Recursive Datatypes

Let's start by implementing a recursive datatype in Bend:

```python
type Tree:
  Node { ~left, ~right }
  Leaf { value }
```

This defines a binary tree, with elements on leaves. Here, `~` flags a field as
_recursive_. For example, the tree:

```
  __/\__
 /\     /\
1  2   3  4
```

Could be represented as:

```
tree = Tree/Node{
  left:  Tree/Node{left: Tree/Leaf {value: 1}, right: Tree/Leaf {value: 2}},
  right: Tree/Node{left: Tree/Leaf {value: 3}, right: Tree/Leaf {value: 4}},
}
```

Binary trees are so useful in Bend that this type is already pre-defined in the
language and has its own dedicated syntax:

```py
# ![a, b] => Equivalent to Tree/Node { left: a, right: b }
# !x      => Equivalent to Tree/Leaf { value: x }
tree = ![![!1, !2],![!3, !4]]
```

### Fold: consuming recursive datatypes

Now, here's a question: how do we _sum_ the elements of a tree? In Python, we
could just use a loop. In Bend, we don't have loops. Fortunately, there is
another construct we can use: it's called `fold`, and it works like a _search
and replace_ for datatypes. For example, consider the code below:

```python
def sum(tree: Tree(u24)) -> u24:
  fold tree:
    case Tree/Node:
      return tree.left + tree.right
    case Tree/Leaf:
      return tree.value

def main() -> u24:
  tree = ![![!1, !2],![!3, !4]]
  return sum(tree)
```

It accomplishes the task by replacing every `Tree/Node { left, right }` by `left +
right`, and replacing every `Tree/Leaf` by `value`. As a result, the entire "tree of
values" is turned into a "tree of additions", and it evaluates as follows:

```python
nums = ((1 + 2) + (3 + 4))
nums = (3 + 7)
nums = 10
```

Now, this may look limiting, but it actually isn't. Folds are known for being
universal: _any algorithm that can be implemented with a loop, can be
implemented with a fold_. So, we can do much more than just compute an
"aggregated value". Suppose we wanted, for example, to transform every element
into a tuple of `(index,value)`, returning a new tree. Here's how to do it:

```python
def enum(tree):
  idx = 0
  fold tree with idx:
    case Tree/Node:
      return ![tree.left(idx * 2 + 0), tree.right(idx * 2 + 1)]
    case Tree/Leaf:
      return !(idx, tree.value)

def main() -> Tree(u24):
  tree = ![![!1, !2],![!3, !4]]
  return enum(tree)
```

Compared to the `sum` algorithm, 3 important things changed:

1. We initialize a state, `idx`, as `0`.

2. We pass new states down as `tree.xyz(new_idx)`

3. The base case receives the final state: the element index

So, in the end, we'll have computed a copy of the original tree, except that
every element has now became a tuple of index and value.

Now, please take a moment to think about this fact: **everything can be computed
with a fold.** This idea often takes some time to get used to, but, once you do,
it is really liberating, and will let you write better algorithms. As an
exercise, use `fold` to implement a "reverse" algorithm for lists:

```python
def reverse(list: List(T)) -> List(T):
  # exercise
  ?

def main() -> List(u24):
  return reverse([1,2,3])
```

## Bend: generating recursive datatypes

Bending is the opposite of folding. Whatever `fold` consumes, `bend` creates.
The idea is that, by defining an _initial state_ and a _halting condition_, we
can "grow" a recursive structure, layer by layer, until the condition is met.
For example, consider the code below:

```python
def main() -> Tree(u24):
  bend x = 0:
    when x < 3:
      tree = ![fork(x + 1), fork(x + 1)]
    else:
      tree = !7
  return tree
```

The program above will initialize a state (`x = 0`), and then, for as long as `x
< 3`, it will "fork" that state in two, creating a `Tree/Node`, and continuing
with `x + 1`. When `x >= 3`, it will halt and return a `Tree/Leaf` with `7`.
When all is done, the result will be assigned to the `tree` variable:

```python
tree = fork(0)
tree = ![fork(1), fork(1)]
tree = ![![fork(2),fork(2)], ![fork(2),fork(2)]]
tree = ![![![fork(3),fork(3)], ![fork(3),fork(3)]], ![![fork(3),fork(3)], ![fork(3),fork(3)]]]
tree = ![![![!7, !7], ![!7, !7]], ![![!7, !7], ![!7, !7]]]
```

With some imagination, we can easily see that, by recursively unrolling a state
this way, we can generate any structure we'd like. In fact, `bend` is so general
we can even use it to emulate a loop. For example, this Python program:

```python
sum = 0
idx = 0
while idx < 10:
  sum = idx + sum
  idx = idx + 1
```

Could be emulated in Bend with a "sequential bend":

```python
bend idx = 0:
  when idx < 10:
    sum = idx + fork(idx + 1)
  else:
    sum = 0
```

Of course, if you do it, Bend's devs will be very disappointed with you. Why?
Because everyone is here for one thing. Let's do it!

## Parallel "Hello, World"

So, after all this learning, we're now ready to answer the ultimate question:

**How do we write parallel algorithms in Bend?**

At this point, you might have the idea: by using _folds_ and _bends_, right?
Well... actually not! You do not need to use these constructs at all to make it
happen. Anything that _can_ be parallelized _will_ be parallelized on Bend. To
be more precise, this:

```
f(g(x))
```

Can NOT be parallelized, because `f` **depends** on the result of `g`. But this:

```
H(f(x), g(y))
```

Can be parallelized, because `f(x)` and `g(y)` are **independent**. Traditional
loops, on the other hands, are inherently sequential. A loop like:

```python
sum = 0
for i in range(8):
  sum += i
```

Is actually just a similar way to write:

```python
sum = (0 + (1 + (2 + (3 + (4 + (5 + (6 + 7)))))))
```

Which is _really bad_ for parallelism, because the only way to compute this is
by evaluating the expressions one after the other, in order:

```python
sum = (0 + (1 + (2 + (3 + (4 + (5 + (6 + 7)))))))
sum = (0 + (1 + (2 + (3 + (4 + (5 + 13))))))
sum = (0 + (1 + (2 + (3 + (4 + 18)))))
sum = (0 + (1 + (2 + (3 + 22))))
sum = (0 + (1 + (2 + 25)))
sum = (0 + (1 + 27))
sum = (0 + 28)
sum = 28
```

There is nothing Bend could do to save this program: sequentialism is an
inherent part of its logic. Now, if we had written, instead:

```python
sum = (((0 + 1) + (2 + 3)) + ((4 + 5) + (6 + 7)))
```

Then, we'd have a much easier time evaluating that in parallel. Look at it:

```python
sum = (((0 + 1) + (2 + 3)) + ((4 + 5) + (6 + 7)))
sum = ((1 + 5) + (9 + 13))
sum = (6 + 22)
sum = 28
```

That's so much better that even the _line count_ is shorter!

So, how do you write a parallel program in Bend?

**Just write algorithms that aren't helplessly sequential.**

That's all there is to it. As long as you write programs like that one, then
unlike the former one, they will run in parallel. And that's why `bend` and
`fold` are core features: they're, essentially, parallelizable loops. For
example, to add numbers in parallel, we can write:

```python
def main() -> u24:
  bend d = 0, i = 0:
    when d < 28:
      sum = fork(d+1, i*2+0) + fork(d+1, i*2+1)
    else:
      sum = i
  return sum
```

And that's the parallel "Hello, world"! Now, let's finally run it. But first,
let's measure its single-core performance. Also, remember that, for now, Bend
only supports 24-bit numbers (`u24`), thus, the results will always be in `mod
16777216`.

```
bend run-rs main.bend
```

On my machine (Apple M3 Max), it completes after `147s`, at `65 MIPS` (Million
Interactions Per Second - Bend's version of the FLOPS). That's too long. Let's
run it in parallel, by using the **C interpreter** instead:

```
bend run main.bend
```

> Note: `run` is an alias to the `run-c` command.

And, just like that, the same program now runs in `8.49s`, at `1137 MIPS`.
That's **18x faster**! Can we do better? Sure: let's use the **C compiler** now:

```
bend gen-c main.bend >> main.c
```

This command converts your `bend` file into a small, dependency-free C file
that does the same computation much faster. You can compile it to an executable:

```
gcc main.c -o main -O2 -lm -lpthread # if you're on Linux
gcc main.c -o main -O2               # if you're on OSX
./main
```

Now, the same program runs in `5.81s`, at `1661.91 MIPS`. That's now **25x
faster** than the original! Can we do better? Let's now enter the unexplored
realms of arbitrary high-level programs on... GPUs. How hard that could be?
Well, for us... it was. A lot. For you... just call the **CUDA interpreter**:

```
bend run-cu main.bend
```

And, simply as that, the same program now runs in `0.82s`, at a blistering
`11803.24 MIPS`. That's **181x faster** than the original. Congratulations!
You're now a thread bender.

~

As a last note, you may have noticed that the compiled version isn't much faster
than the interpreted one. Our compiler is still on its infancy, and the assembly
generated is quite abysmal. Most of our effort went into setting up a foundation
for the parallel evaluator, which was no easy task. With that out of our way,
improving the compiler is a higher priority now. You can expect it to improve
continuously over time. For now, it is important to understand the state of
things, and set up reasonable expectations.

## A Parallel Bitonic Sort

The bitonic sort is a popular algorithm that sorts a set of numbers by moving
them through a "circuit" (sorting network) and swapping as they pass through:

![bitonic-sort](https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/BitonicSort1.svg/1686px-BitonicSort1.svg.png)

In CUDA, this can be implemented by using mutable arrays and synchronization
primitives. This is well known. What is less known is that it can also be
implemented as a series of _immutable tree rotations_, with pattern-matching and
recursion. Don't bother trying to understand it, but, here's the code:

```python
def gen(d: u24, x: u24) -> Any:
  switch d:
    case 0:
      return x
    case _:
      return (gen(d-1, x * 2 + 1), gen(d-1, x * 2))
```
> Note: The type of this function can't be expressed with Bend's type system, but we can still write it using `Any`.

```python
def sum(d: u24, t: u24) -> u24:
  switch d:
    case 0:
      return t
    case _:
      (t.a, t.b) = t
      return sum(d-1, t.a) + sum(d-1, t.b)

def swap(s: u24, a: Any, b: Any) -> (Any, Any):
  switch s:
    case 0:
      return (a,b)
    case _:
      return (b,a)

def warp(d: u24, s: u24, a: Any, b: Any) -> (Any, Any):
  switch d:
    case 0:
      return swap(s ^ (a > b), a, b)
    case _:
      (a.a,a.b) = a
      (b.a,b.b) = b
      (A.a,A.b) = warp(d-1, s, a.a, b.a)
      (B.a,B.b) = warp(d-1, s, a.b, b.b)
      return ((A.a,B.a),(A.b,B.b))

def flow(d: u24, s: u24, t: Any) -> Any:
  switch d:
    case 0:
      return t
    case _:
      (t.a, t.b) = t
      return down(d, s, warp(d-1, s, t.a, t.b))

def down(d: u24, s: u24, t: Any) -> Any:
  switch d:
    case 0:
      return t
    case _:
      (t.a, t.b) = t
      return (flow(d-1, s, t.a), flow(d-1, s, t.b))

def sort(d: u24, s: u24, t: Any) -> Any:
  switch d:
    case 0:
      return t
    case _:
      (t.a, t.b) = t
      return flow(d, s, (sort(d-1, 0, t.a), sort(d-1, 1, t.b)))

def main() -> u24:
  return sum(18, sort(18, 0, gen(18, 0)))
```

As a test of Bend's ability to parallelize the most insanely high-level
computations possible, let's benchmark this program. Here are the results:

- 12.33s / 102 MIPS (Apple M3 Max, 1 thread)

- 0.96s / 1315 MIPS (Apple M3 Max, 16 threads) - 12x speedup

- 0.24s / 5334 MIPS (NVIDIA RTX 4090, 16k threads) - 51x speedup

And, just like magic, it works! 51x faster on RTX. How cool is that?

Of course, you would absolutely **not** want to sort numbers like that,
specially when mutable arrays exist. But there are many algorithms that _can
not_ be implemented easily with buffers. Evolutionary and genetic algorithms,
proof checkers, compilers, interpreters. For the first time ever, you can
implement these algorithms as high-level functions, in a language that runs on
GPUs. That's the magic of Bend!

## Graphics Rendering

While the algorithm above does parallelize well, it is very memory-hungry. It is
a nice demo of Bend's potential, but isn't a great way to sort lists. Currently,
Bend has a 4GB memory limit (for being a 32-bit architecture). When the memory
is filled, its performance will degrade considerably. But we can do better.

Since Bend is GC-free, we can express low memory footprint programs using `bend`
or tail calls. For maximum possible performance, one should first create enough
"parallel room" to fill all available cores, and then spend some time doing
compute-heavy, but less memory-hungry, computations. For example, consider:

```python
# given a shader, returns a square image
def render(depth: u24) -> Any:
  bend d = 0, i = 0:
    when d < depth:
      color = (fork(d+1, i*2+0), fork(d+1, i*2+1))
    else:
      width = depth / 2
      color = demo_shader(i % width, i / width)
  return color

# given a position, returns a color
# for this demo, it just busy loops
def demo_shader(x: Any, y: Any) -> Any:
  bend i = 0:
    when i < 100000:
      color = fork(i + 1)
    else:
      color = 0x000001
  return color

# renders a 256x256 image using demo_shader
def main() -> Any:
  return render(16, demo_shader)
```

It emulates an OpenGL fragment shader by building an "image" as a perfect binary
tree, and then calling the `demo_shader` function on each pixel. Since the tree
has a depth of 16, we have `2^16 = 65536 pixels`, which is enough to fill all
cores of an RTX 4090. Moreover, since `demo_shader` isn't doing many
allocations, it can operate entirely inside the GPU's "shared memory" (L1
cache). Each GPU thread has a local space of 64 IC nodes. Functions that don't
need more than that, like `demo_shader`, can run up to 5x faster!

On my GPU, it performs `22,000 MIPS` out of the box, and `40000+ MIPS` with a
tweak on the generated CUDA file (doubling the `TPC`, which doubles the number
of threads per block). In the near future, we plan to add immutable textures,
allowing for single-interaction sampling. With some napkin math, this should be
enough to render 3D games in real-time. Imagine a future where game engines are
written in Python-like languages? That's the future we're building, with Bend!

You can see your programs total cost (number of interactions) and performance
(MIPS) by adding the `-s` flag. This is a good way to check if your algorithm is
parallelizing. For example, on my Apple M3 Max, sequential algorithms will
perform about 100 MIPS on interpreted mode, and 130 MIPS on compiled mode
(remember our compiler is still **very** immature, which is why it isn't much
faster than the interpreter). A well-parallelizable program, though, will easily
reach 1000+ MIPS.

## To be continued...

This guide isn't extensive, and there's a lot uncovered. For example, Bend also
has an entire Haskell-like functional syntax that is compatible with old HVM1, you can find it documented [here](https://github.com/HigherOrderCO/Bend/blob/main/docs/syntax.md#fun-syntax). You can also check [this](https://gist.github.com/VictorTaelin/9cbb43e2b1f39006bae01238f99ff224) out, it's an implementation of the Bitonic Sort with Haskell-like equations. 

## Community

Remember: Bend is very new and experimental. Bugs and imperfections should be
expected. That said, [HOC](https://HigherOrderCO.com/) will provide long-term
support to Bend (and its runtime, HVM2). So, if you believe this paradigm will
be big someday, and want to be part of it in these early stages, join us on
[Discord](https://Discord.HigherOrderCO.com/). Report bugs, bring your
suggestions, and let's chat and build this future together!


================================================
FILE: LICENSE-APACHE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS


   Copyright 2023-2024 Higher Order Company

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
<h1 >Bend</h1>
<p>A high-level, massively parallel programming language</p>

## Index
1. [Introduction](#introduction)
2. [Important Notes](#important-notes)
3. [Install](#install)
4. [Getting Started](#getting-started)
5. [Speedup Example](#speedup-examples)
6. [Additional Resources](#additional-resources)

## Introduction

Bend offers the feel and features of expressive languages like Python and Haskell. This includes fast object allocations, full support for higher-order functions with closures, unrestricted recursion, and even continuations.                             
Bend scales like CUDA, it runs on massively parallel hardware like GPUs, with nearly linear acceleration based on core count, and without explicit parallelism annotations: no thread creation, locks, mutexes, or atomics.                     
Bend is powered by the [HVM2](https://github.com/higherorderco/hvm) runtime.


## Important Notes

* Bend is designed to excel in scaling performance with cores, supporting over 10000 concurrent threads.
* The current version may have lower single-core performance.
* You can expect substantial improvements in performance as we advance our code generation and optimization techniques.
* We are still working to support Windows. Use [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) as an alternative solution.
* [We only support NVIDIA Gpus currently](https://github.com/HigherOrderCO/Bend/issues/341).




## Install

### Install dependencies

#### On Linux
```sh
# Install Rust if you haven't already.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# For the C version of Bend, use GCC. We recommend a version up to 12.x.
sudo apt install gcc
```
For the CUDA runtime [install the CUDA toolkit for Linux](https://developer.nvidia.com/cuda-downloads?target_os=Linux) version 12.x.


#### On Mac
```sh
# Install Rust if you haven't it already.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# For the C version of Bend, use GCC. We recommend a version up to 12.x.
brew install gcc
```


### Install Bend

1. Install HVM2 by running:
```sh
# HVM2 is HOC's massively parallel Interaction Combinator evaluator.
cargo install hvm

# This ensures HVM is correctly installed and accessible.
hvm --version
```
2. Install Bend by running:
```sh
# This command will install Bend
cargo install bend-lang

# This ensures Bend is correctly installed and accessible.
bend --version
```

### Getting Started
#### Running Bend Programs
```sh
bend run    <file.bend> # uses the C interpreter by default (parallel)
bend run-rs <file.bend> # uses the Rust interpreter (sequential)
bend run-c  <file.bend> # uses the C interpreter (parallel)
bend run-cu <file.bend> # uses the CUDA interpreter (massively parallel)

# Notes
# You can also compile Bend to standalone C/CUDA files using gen-c and gen-cu for maximum performance.
# The code generator is still in its early stages and not as mature as compilers like GCC and GHC.
# You can use the -s flag to have more information on
  # Reductions
  # Time the code took to run
  # Interaction per second (In millions)
```

#### Testing Bend Programs
The example below sums all the numbers in the range from `start` to `target`. It can be written in two different methods: one that is inherently sequential (and thus cannot be parallelized), and another that is easily parallelizable. (We will be using the `-s`flag in most examples, for the sake of visibility)

#### Sequential version:
First, create a file named `sequential_sum.bend`
```sh
# Write this command on your terminal
touch sequential_sum.bend
```
Then with your text editor, open the file `sequential_sum.bend`, copy the code below and paste in the file.

```py
# Defines the function Sum with two parameters: start and target
def Sum(start, target):
  if start == target:
    # If the value of start is the same as target, returns start.
    return start
  else:
    # If start is not equal to target, recursively call Sum with
    # start incremented by 1, and add the result to start.
    return start + Sum(start + 1, target)  

def main():
  # This translates to (1 + (2 + (3 + (...... + (999999 + 1000000)))))
  # Note that this will overflow the maximum value of a number in Bend
  return Sum(1, 1_000_000)
```

##### Running the file
You can run it using Rust interpreter (Sequential)
```sh
bend run-rs sequential_sum.bend -s
```

Or you can run it using C interpreter (Sequential)
```sh
bend run-c sequential_sum.bend -s
```

If you have a NVIDIA GPU, you can also run in CUDA (Sequential)
```sh
bend run-cu sequential_sum.bend -s
```

In this version, the next value to be calculated depends on the previous sum, meaning that it cannot proceed until the current computation is complete. Now, let's look at the easily parallelizable version.


#### Parallelizable version:
First close the old file and then proceed to your terminal to create `parallel_sum.bend`
```sh
# Write this command on your terminal
touch parallel_sum.bend
```
Then with your text editor, open the file `parallel_sum.bend`, copy the code below and paste in the file.

```py
# Defines the function Sum with two parameters: start and target
def Sum(start, target):
  if start == target:
    # If the value of start is the same as target, returns start.
    return start
  else:
    # If start is not equal to target, calculate the midpoint (half),
    # then recursively call Sum on both halves.
    half = (start + target) / 2
    left = Sum(start, half)  # (Start -> Half)
    right = Sum(half + 1, target)
    return left + right

# A parallelizable sum of numbers from 1 to 1000000
def main():
  # This translates to (((1 + 2) + (3 + 4)) + ... (999999 + 1000000)...)
  return Sum(1, 1_000_000)
```

In this example, the (3 + 4) sum does not depend on the (1 + 2), meaning that it can run in parallel because both computations can happen at the same time. 

##### Running the file
You can run it using Rust interpreter (Sequential)
```sh
bend run-rs parallel_sum.bend -s
```

Or you can run it using C interpreter (Parallel)
```sh
bend run-c parallel_sum.bend -s
```

If you have a NVIDIA GPU, you can also run in CUDA (Massively parallel)
```sh
bend run-cu parallel_sum.bend -s
```

In Bend, it can be parallelized by just changing the run command. If your code **can** run in parallel it **will** run in parallel.


### Speedup Examples
The code snippet below implements a [bitonic sorter](https://en.wikipedia.org/wiki/Bitonic_sorter) with *immutable tree rotations*. It's not the type of algorithm you would expect to run fast on GPUs. However, since it uses a divide and conquer approach, which is inherently parallel, Bend will execute it on multiple threads, no thread creation, no explicit lock management.

#### Bitonic Sorter Benchmark

- `bend run-rs`: CPU, Apple M3 Max: 12.15 seconds
- `bend run-c`: CPU, Apple M3 Max: 0.96 seconds
- `bend run-cu`: GPU, NVIDIA RTX 4090: 0.21 seconds

 <details>
  <summary><b>Click here for the Bitonic Sorter code</b></summary>
   

```py
# Sorting Network = just rotate trees!
def sort(d, s, tree):
  switch d:
    case 0:
      return tree
    case _:
      (x,y) = tree
      lft   = sort(d-1, 0, x)
      rgt   = sort(d-1, 1, y)
      return rots(d, s, (lft, rgt))

# Rotates sub-trees (Blue/Green Box)
def rots(d, s, tree):
  switch d:
    case 0:
      return tree
    case _:
      (x,y) = tree
      return down(d, s, warp(d-1, s, x, y))

# Swaps distant values (Red Box)
def warp(d, s, a, b):
  switch d:
    case 0:
      return swap(s ^ (a > b), a, b)
    case _:
      (a.a, a.b) = a
      (b.a, b.b) = b
      (A.a, A.b) = warp(d-1, s, a.a, b.a)
      (B.a, B.b) = warp(d-1, s, a.b, b.b)
      return ((A.a,B.a),(A.b,B.b))

# Propagates downwards
def down(d,s,t):
  switch d:
    case 0:
      return t
    case _:
      (t.a, t.b) = t
      return (rots(d-1, s, t.a), rots(d-1, s, t.b))

# Swaps a single pair
def swap(s, a, b):
  switch s:
    case 0:
      return (a,b)
    case _:
      return (b,a)

# Testing
# -------

# Generates a big tree
def gen(d, x):
  switch d:
    case 0:
      return x
    case _:
      return (gen(d-1, x * 2 + 1), gen(d-1, x * 2))

# Sums a big tree
def sum(d, t):
  switch d:
    case 0:
      return t
    case _:
      (t.a, t.b) = t
      return sum(d-1, t.a) + sum(d-1, t.b)

# Sorts a big tree
def main:
  return sum(20, sort(20, 0, gen(20, 0)))

```

</details>
  
if you are interested in some other algorithms, you can check our [examples folder](https://github.com/HigherOrderCO/Bend/tree/main/examples)


### Additional Resources
 - To understand the technology behind Bend, check out the HVM2 [paper](https://paper.higherorderco.com/).
 - We are working on an official documentation, meanwhile for a more in depth
     explanation check [GUIDE.md](https://github.com/HigherOrderCO/Bend/blob/main/GUIDE.md)
 - Read about our features at [FEATURES.md](https://github.com/HigherOrderCO/Bend/blob/main/FEATURES.md)
 - Bend is developed by [HigherOrderCO](https://higherorderco.com/) - join our [Discord](https://discord.higherorderco.com)!


================================================
FILE: cspell.json
================================================
{
  "version": "0.2",
  "language": "en",
  "words": [
    "anni",
    "annihilations",
    "arities",
    "arity",
    "arrayvec",
    "behaviour",
    "bitand",
    "Bitonic",
    "builtins",
    "callcc",
    "chumsky",
    "clippy",
    "codegen",
    "codepoint",
    "codepoints",
    "combinators",
    "concat",
    "ctrs",
    "cuda",
    "datatypes",
    "Deque",
    "destructures",
    "desugared",
    "desugars",
    "devs",
    "dups",
    "effectful",
    "elif",
    "elifs",
    "foldl",
    "hasher",
    "hexdigit",
    "Hindley",
    "hvm's",
    "indexmap",
    "inet",
    "inets",
    "inlineable",
    "inlineables",
    "inlinees",
    "inlines",
    "inodes",
    "insta",
    "interner",
    "ints",
    "itertools",
    "ITRS",
    "kwarg",
    "kwargs",
    "lcons",
    "linearization",
    "linearizes",
    "linearizing",
    "lnil",
    "lpthread",
    "mant",
    "Milner",
    "miscompilation",
    "mult",
    "namegen",
    "nams",
    "nanosleep",
    "nats",
    "newtype",
    "nilary",
    "nullary",
    "numop",
    "nums",
    "OOM's",
    "oper",
    "opers",
    "parallelizable",
    "peekable",
    "postcondition",
    "powi",
    "prec",
    "proto",
    "Pythonish",
    "quadtree",
    "quadtrees",
    "rbag",
    "readback",
    "recursively",
    "redex",
    "redexes",
    "repr",
    "resugar",
    "resugared",
    "resugaring",
    "rfold",
    "rsplit",
    "rwts",
    "scons",
    "scopeless",
    "scrutinee",
    "sequentialism",
    "snil",
    "SOTA",
    "stdext",
    "struct",
    "subcmd",
    "submatch",
    "subpattern",
    "subpatterns",
    "subterm",
    "subterms",
    "succ",
    "supercombinator",
    "supercombinators",
    "Tarjan's",
    "tlsv",
    "TSPL",
    "tunr",
    "unbounds",
    "undefer",
    "vectorize",
    "vectorizes",
    "walkdir"
  ],
  "files": [
    "**/*.rs",
    "**/*.md"
  ],
  "ignoreRegExpList": [
    "HexValues",
    "/λ/g",
    "/-O/g",
    "/`.`/g",
    "/`..`/g",
    "/`...`/g",
    "/`....`/g",
    "/`.....`/g",
    "/```(.*\n)*```/g"
  ]
}


================================================
FILE: docs/builtins.md
================================================
> this is a WIP based on [Builtins.bend](https://github.com/HigherOrderCO/Bend/blob/main/src/fun/builtins.bend).

# Built-in Types and Functions

**Bend** built-in types and functions, this document serves as a reference guide. Read more at [FEATURES.md](https://github.com/HigherOrderCO/Bend/blob/main/FEATURES.md).

## String

```python
type String:
  Nil
  Cons { head: u24, ~tail: String }
```

- **Nil**: Represents an empty string.
- **Cons head ~tail**: Represents a string with a `head` character and a `tail` string.

### Syntax

A String literal is surrounded with `"`. Accepts the same values as characters literals.

```
"Hello, World!"
```

### Functions

#### String/equals

```python
#{
  Checks if two strings are equal.
#}
def String/equals (s1: String) (s2: String) : u24
```

#### String/split

```python
#{
  Splits a string into a list of strings based on the given delimiter.
#}
String/split (s: String) (delimiter: u24) : (List String)
```

## List

```python
type List(T):
  Nil
  Cons { head: T, ~tail: List(T) }
```

- **Nil**: Represents an empty list.
- **Cons head ~tail**: Represents a list with a `head` element and a `tail` list.
- **T**: Represents the type of the elements in the list.

### Syntax

A List of values can be written using `[ ]`, it can have multiple values inside, using `,` you can divide its value in a list of multiple elements.

```
["This", "List", "Has", "Multiple", "Values"]
```

### Functions

#### List/length

```python
#{
  Returns a tuple containing the length and the list itself.
#}
def List/length(xs: List(T)) -> (u24, List(T)):
```



#### List/reverse

```python
#{
  Reverses the elements of a list.
#}
def List/reverse(xs: List(T)) -> List(T):
```

#### List/flatten

```python
#{
  Returns a flattened list from a list of lists.
#}
List/flatten (xs: (List (List T))) : (List T)
```
Example:
```python
List/flatten([[1], [2, 3], [4]])

# Result: [1, 2, 3, 4]
```

#### List/concat

```python
#{
  Appends two lists together. 
#}
def List/concat(xs: (List T)) (ys: (List T)) : (List T)
```
Example:
```python
List/concat([1, 2], [4, 5])

# Result: [1, 2, 4, 5]
```

#### List/filter

```python
#{
  Filters a list based on a predicate function.
#}
List/filter(xs: List(T), pred: T -> Bool) -> List(T)
```

#### List/split_once

```python
#{
  Splits a list into two lists at the first occurrence of a value.
#}
def List/split_once(xs: List(T), cond: T -> u24) -> (Result((List(T), List(T)), List(T))): 
```
Example:
```python
  # Split list at first even number
  list = [1,3,4,5,6]
  result = List/split_once(list, λx: x % 2 == 0)
  return result
  # Result: Result/Ok/tag ([1, 3], [5, 6])
```

## Result

```python
type (Result o e) = (Ok (val: o)) | (Err (val: e))
```

### Result/unwrap

Returns the inner value of `Result/Ok` or `Result/Err`.

If the types `A` and `B` are different, should only be used in type unsafe programs or when only one variant is guaranteed to happen.

```python
#{
Returns the inner value of `Result/Ok` or `Result/Err`.

If the types `A` and `B` are different, should only be used in type unsafe programs or when only one variant is guaranteed to happen.
#}
def Result/unwrap(res: Result(T, E)) -> Any:
```

## Tree

```python
type Tree(T):
  Node { ~left: Tree(T), ~right: Tree(T) }
  Leaf { value: T }
```

**`Tree`** represents a tree with values stored in the leaves.
Trees are a structure that naturally lends itself to parallel recursion, so writing your problem in terms of trees is a good first approach to parallelize your code.

- **Node { ~left ~right }**: Represents a tree node with `left` and `right` subtrees.
- **Leaf { value }**: Represents one of the ends of the tree, storing `value`.
- **T**: Represents the type of the elements in the tree.

#### Syntax

**Bend** provides the `![]` operator to create tree branches and the `!` operator to create a tree leaf.

```py
# ![a, b] => Equivalent to Tree/Node { left: a, right: b }
# !x      => Equivalent to Tree/Leaf { value: x }
tree = ![![!1, !2],![!3, !4]]
```

Technically your trees don't need to end with leaves, but if you don't, your program will be very hard to reason about.
## Maybe

```python
type Maybe(T):
  Some{ value }
  None 
```
**`Maybe`** is a structure that may or not contain a value. It is meant to be used as a return type for functions that can fail. This way you don't need to resort to unreachable() in order to handle errors.

#### Syntax
Here's how you create a new `Maybe` containing the Nat value of 1:
```python
maybe = Maybe/Some(Nat/Succ(Nat/Zero))
```
## Maybe functions

### Maybe/unwrap
```python
#{
Returns the value inside the `Maybe` if it is `Some`, and returns `unreachable()` if it is `None`.
#}  
def Maybe/unwrap(m: Maybe(T)) -> T
```
## Map

```python
type Map(T):
  Node { value: Maybe(T), ~left: Map(T), ~right: Map(T) }
  Leaf  
```

**`Map`** represents a tree with values stored in the branches.
It is meant to be used as an efficient map data structure with integer keys and O(log n) read and write operations.

- **Node { value: Maybe(T), ~left: Map(T), ~right: Map(T) }**: Represents a map node with a `Maybe` and `left` and `right` subtrees. Empty nodes have `Maybe/None` stored in the `value` field, whilst non-empty nodes have `Maybe/Some` stored in the `value` field.
- **Leaf**: Represents an unwritten, empty portion of the map.

#### Syntax

Here's how you create a new `Map` with some initial values.:

```python
def main():
  return { 0: 4, `hi`: "bye", 'c': 2 + 3 }
```

The keys must be `U24` numbers, and can be given as literals or any other expression that evaluates to a `U24`.

As long as your function isn't typed, like the one in the example, the values can be anything. But storing data of different types in a `Map` will make it harder for you to reason about it.

You can read and write a value of a map with the `[]` operator:

```python
map = { 0: "zero", 1: "one", 2: "two", 3: "three" }
map[0] = "not zero"
map[1] = 2
map[2] = 3
map[3] = map[1] + map[map[1]]
```

Here, `map` must be the name of the `Map` variable, and the keys inside `[]` can be any expression that evaluates to a `U24`.

## Map functions

### Map/empty

```python
#{
  Initializes an empty map.
#} 
def Map/empty() -> Map(T)
```

### Map/get



```rust
#{
  Retrieves a `value` from the `map` based on the `key` and returns a tuple with the value and the `map` unchanged.
  
  The logic for checking whether a value is or not contained in a `map` is not done in the `get` function, so if we try to get a key that is not in the map, the program will return `unreachable`. 
#}
def Map/get (map: Map(T), key: u24) -> (T, Map(T))
```

#### Syntax

Considering the following map

```python
{ 0: "hello", 1: "bye", 2: "maybe", 3: "yes"}
```

The `get` function can be written as

```
return x[0]  # Gets the value of the key 0
```

And the value resultant from the get function would be:

```
"hello"
```

### Map/set

```rust
#{
  Sets a value on a Map, returning the map with the value mapped.
#}
def Map/set (map: Map(T), key: u24, value: T) -> Map(T)
```

#### Syntax

Considering the following tree

```python
{ 0: "hello", 1: "bye", 2: "maybe", 3: "yes"}
```

The `set` function can be written as

```py
x[0] = "swapped"     # Assigns the key 0 to the value "swapped"
```

And the value resultant from the get function would be:

```py
{ 0: "swapped", 1: "bye", 2: "maybe", 3: "yes"}
```

If there's no matching `key` in the tree, it would add a new branch to that tree with the value `set`

```py
x[4] = "added"     # Assigns the key 4 to the value "added"
```

The new tree

```py
{ 0: "swapped", 1: "bye", 2: "maybe", 3: "yes", 4: "added"}
```

### Map/map


```rust
#{
  Applies a function to a value in the map and returns the map with the value mapped.
#}
def Map/map (map: Map(T), key: u24, f: T -> T) -> Map(T)
```

#### Syntax

With the same map that we `set` in the previous section, we can map it's values with `@=`:

```py
x[0] @= lambda y: String/concat(y, " and mapped")
# x[0] now contains "swapped and mapped"
```


### Map/contains

```python
#{
  Checks if a `map` contains a given `key` and returns 0 or 1 along with and  `map` unchanged.
#}
def Map/contains (map: Map(T), key: u24) -> (u24, Map(T))

#### Syntax

With the same map that we `set` in the previous section, we can call the function `Map/contains` explicitly:

```python
(num, map) = Map/contains(m, key)
return num
```
Whilst the `num` variable will contain 0 or 1 depending on if the key is in the map or not.


## Nat

```python
type Nat = (Succ ~(pred: Nat)) | (Zero)
```

- **Succ ~pred**: Represents a natural number successor.
- **Zero**: Represents the natural number zero.

## DiffList

DiffList is a list that has constant time prepends (cons), appends and concatenation, but can't be pattern matched.

It is implemented as a function that receives a list to be appended to the last element of the DiffList.

For example, the list `List/Cons(1, List/Cons(2, List/Nil))` can be written as the difference list `lambda x: List/Cons(1, List/Cons(2, x))`.

### Functions

#### DiffList/new


```python
#{
Creates a new difference list.
#}
def DiffList/new() -> (List(T) -> List(T))
```

#### DiffList/append


```python
#{
  Appends a value to the end of the difference list.
#}
def DiffList/append(diff: List(T) -> List(T), val: T) -> (List(T) -> List(T))
```

#### DiffList/cons

```python
#{
  Appends a value to the beginning of the difference list.
#}
def DiffList/cons(diff: List(T) -> List(T), val: T) -> (List(T) -> List(T))
```

#### DiffList/to_list


```python
#{
  Converts a difference list to a regular cons list.
#}
def DiffList/to_list(diff: List(T) -> List(T)) -> (List(T))
```

## IO

The basic builtin IO functions are under development and will be stable in the next milestone.

Here is the current list of functions, but be aware that they may change in the near future.

### Printing

```python
#{
  Prints the string `text` to the standard output, encoded with utf-8.
#}
def IO/print(text: String) -> IO(None)
```


### Input

```python
#{
  Reads characters from the standard input until a newline is found.
  Returns the read input as a String decoded with utf-8.
#}
def IO/input() -> IO(Result(String, u24))
```



### File IO

#### File open

```python
#{
  Opens a file with with `path` being given as a string and `mode` being a string with the mode to open the file in. The mode should be one of the following:
#}
def IO/FS/open(path: String, mode: String) -> IO(Result(u24, u24))
```


- `"r"`: Read mode
- `"w"`: Write mode (write at the beginning of the file, overwriting any existing content)
- `"a"`: Append mode (write at the end of the file)
- `"r+"`: Read and write mode
- `"w+"`: Read and write mode
- `"a+"`: Read and append mode

Returns an U24 with the file descriptor. File descriptors are not necessarily the same as the ones assigned by the operating system, but rather unique identifiers internal to Bend's runtime.

#### File descriptors for standard files

The standard input/output files are always open and assigned the following file descriptors:

- `IO/FS/STDIN = 0`: Standard input
- `IO/FS/STDOUT = 1`: Standard output
- `IO/FS/STDERR = 2`: Standard error

#### File close

```python
#{
  Closes the file with the given `file` descriptor.
#}
def IO/FS/close(file: u24) -> IO(Result(None, u24))
```


#### File read

```python
#{
Reads `num_bytes` bytes from the file with the given `file` descriptor.
Returns a list of U24 with each element representing a byte read from the file.
#}
def IO/FS/read(file: u24, num_bytes: u24) -> IO(Result(List(u24), u24))
```



```python
#{
  Reads a line from the file with the given `file` descriptor.
  Returns a list of U24 with each element representing a byte read from the file.
#}
def IO/FS/read_line(fd: u24) -> IO(Result(List(u24), u24))
```



```python
#{
  Reads until the end of the file with the given `file` descriptor.
  Returns a list of U24 with each element representing a byte read from the file.
#}
def IO/FS/read_to_end(fd: u24) -> IO(Result(List(u24), u24))
```



```python
#{
  Reads an entire file with the given `path` and returns a list of U24 with each element representing a byte read from the file.
#}
def IO/FS/read_file(path: String) -> IO(Result(List(u24), u24))
```


#### File write

```python
#{
  Writes `bytes`, a list of U24 with each element representing a byte, to the file with the given `file` descriptor.
  Returns nothing (`*`).
#}
def IO/FS/write(file: u24, bytes: List(u24)) -> IO(Result(None, u24))
```

```python
#{
  Writes `bytes`, a list of U24 with each element representing a byte, as the entire content of the file with the given `path`.
#}
def IO/FS/write_file(path: String, bytes: List(u24)) -> IO(Result(None, u24))
```

#### File seek

```python
#{
  Moves the current position of the file with the given `file` descriptor to the given `offset`, an I24 or U24 number, in bytes.
#}
def IO/FS/seek(file: u24, offset: i24, mode: i24) -> IO(Result(None, u24)) 
```

`mode` can be one of the following:

- `IO/FS/SEEK_SET = 0`: Seek from start of file
- `IO/FS/SEEK_CUR = 1`: Seek from current position
- `IO/FS/SEEK_END = 2`: Seek from end of file

Returns nothing (`*`).

#### File flush

```python
#{
  Flushes the file with the given `file` descriptor.
  Returns nothing (`*`).
#}
def IO/FS/flush(file: u24) -> IO(Result(None, u24))
```

### Dinamically linked libraries

It's possible to dynamically load shared objects (libraries) with functions that implement the Bend IO interface.
You can read more on how to implement these libraries in the [Dynamically linked libraries and foreign functions](docs/ffi.md) documentation.

#### IO/DyLib/open

```py
#{
  Loads a dynamic library file.
#}
def IO/DyLib/open(path: String, lazy: u24) -> IO(Result(u24, String))
```
- `path` is the path to the library file.
- `lazy` is a boolean encoded as a `u24` that determines if all functions are loaded lazily (`1`) or upfront (`0`).
- Returns an unique id to the library object encoded as a `u24`.

#### IO/DyLib/call

```py
#{
  Calls a function of a previously opened library.
  - `dl` is the id of the library object.
  - `fn` is the name of the function in the library.
  - `args` are the arguments to the function. The expected values depend on the called function.
  - The returned value is determined by the called function.
#}
def IO/DyLib/call(dl: u24, fn: String, args: Any) -> IO(Result(Any, String))
```


#### IO/DyLib/close

```py
#{
  Closes a previously open library.
  - `dl` is the id of the library object.
  - Returns nothing (`*`).
#}
def IO/DyLib/close(dl: u24) -> IO(Result(None, String))
```


## Native number casting

### to_f24

```py
#{
  Casts an u24 number to an f24.
#}
def u24/to_f24 -> (u24 -> f24)

#{
  Casts an i24 number to an f24.
#}
def i24/to_f24 -> (i24 -> f24)
```
### to_u24

```py
#{
  Casts a f24 number to an u24.
#}
def f24/to_u24 -> (f24 -> u24)

#{
  Casts an i24 number to an u24.
#}
def i24/to_u24 -> (i24 -> u24)
```
### to_i24

```py
#{
  Casts an u24 number to an i24.
#}
def u24/to_i24 -> (u24 -> i24):
#{
  Casts a f24 number to an i24.
#}
def f24/to_i24 -> (f24 -> i24):
```

### to_string

```py
#{
  Casts an u24 native number to a string.
#}
def u24/to_string(n: u24) -> String:
```

## String encoding / decoding

### String/decode_utf8

```py
#{
  Decodes a sequence of bytes to a String using utf-8 encoding.
#}
String/decode_utf8 (bytes: (List u24)) : String
```


### String/decode_ascii

```py
#{
  Decodes a sequence of bytes to a String using ascii encoding.
#}
String/decode_ascii (bytes: (List u24)) : String
```


### String/encode_utf8

```py
#{
  Encodes a String to a sequence of bytes using utf-8 encoding.
#}
String/encode_utf8 (str: String) : (List u24)
```


### String/encode_ascii

```py
#{
  Encodes a String to a sequence of bytes using ascii encoding.
#}
String/encode_ascii (str: String) : (List u24)
```


### Utf8/decode_character

```py
#{
  Decodes a utf-8 character, returns a tuple containing the rune and the rest of the byte sequence.
#}
Utf8/decode_character (bytes: (List u24)) : (u24, (List u24))
```


### Utf8/REPLACEMENT_CHARACTER

```py
Utf8/REPLACEMENT_CHARACTER : u24 = '\u{FFFD}'
```

## Math

### Math/log

```py
#{
  Computes the logarithm of `x` with the specified `base`.
#}
def Math/log -> (f24 -> f24 -> f24)
```


### Math/atan2

```py
#{
  Computes the arctangent of `y / x`.
  Has the same behaviour as `atan2f` in the C math lib.
#}
def Math/atan2 -> (f24 -> f24 -> f24)
```


### Math/PI


```py
#{
  Defines the Pi constant.
#}
def Math/PI() -> f24
```

### Math/E


```py
#{
Euler's number
#}
def Math/E() -> f24
```

### Math/sin


```py
#{
  Computes the sine of the given angle in radians.
#}
def Math/sin -> (f24 -> f24)
```

### Math/cos


```py
#{
  Computes the cosine of the given angle in radians.
#}
def Math/cos -> (f24 -> f24)
```

### Math/tan


```py
#{
  Computes the tangent of the given angle in radians.
#}
def Math/tan -> (f24 -> f24)
```

### Math/cot


```py
#{
  Computes the cotangent of the given angle in radians.
#}
Math/cot (a: f24) : f24 
```

### Math/sec


```py
#{
  Computes the secant of the given angle in radians.
#}
Math/sec (a: f24) : f24 
```

### Math/csc


```py
#{
  Computes the cosecant of the given angle in radians.
#}
Math/csc (a: f24) : f24 
```

### Math/atan



```py
#{
  Computes the arctangent of the given angle.
#}
Math/atan (a: f24) : f24 
```

### Math/asin


```py
#{
  Computes the arcsine of the given angle.
#}
Math/asin (a: f24) : f24 
```

### Math/acos


```py
#{
  Computes the arccosine of the given angle.
#}
Math/acos (a: f24) : f24

### Math/radians


```py
#{
  Converts degrees to radians.
#}
Math/radians (a: f24) : f24 
```

### Math/sqrt


```py
#{
  Computes the square root of the given number.
#}
Math/sqrt (n: f24) : f24 
```

### Math/ceil


```py
#{
  Round float up to the nearest integer.
#}
def Math/ceil(n: f24) -> f24
```

### Math/floor


```py
#{
  Round float down to the nearest integer.
#}
def Math/floor(n: f24) -> f24
```

### Math/round


```py
#{
  Round float to the nearest integer.
#}
def Math/round(n: f24) -> f24
```

## Lazy thunks

You can force a function call to be evaluated lazily by wrapping it in a lazy thunk.
In Bend, this can be expressed as `lambda x: x(my_function, arg1, arg2, ...)`.

To evaluate the thunk, you can use the `undefer` function or apply `lambda x: x` to it.


================================================
FILE: docs/cli-arguments.md
================================================
# CLI arguments

It's possible to pass arguments to a program executed with `bend run`:

```sh
bend run <Path to program> [Arguments in expression form]...
```

It accepts any expression that would also be valid inside a bend function.

Arguments are passed to programs by applying them to the entry point function:

```py
# Imp syntax
def main(x1, x2, x3):
  return MainBody(x1 x2 x3)

# Calling with `bend run <file> arg1 arg2 arg3 argN`, it becomes (in the "fun" syntax):
main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3 argN)
```

There are no restrictions on the number of arguments passed to the program.
You can even pass more arguments than the function expects, although that can lead to unexpected results.
```py
# Expects 2 CLI arguments
def main(x, y):
  return {x - y, y - x}
```
```sh
# Calling with just one argument
> bend run <path> +5
λa {(- a 5) (- a +5)}

# Calling with two argument
> bend run <path> +5 +3
{+2 -2}
# Calling with three arguments
# In this case, the third argument doesn't change anything
# due to the underlying interaction rules.
# If this were a variant of simply-typed lambda-calculus
# it wouldn't be well-typed.
> bend run <path> +5 +3 +1
{+2 -2}
```




================================================
FILE: docs/compilation-and-readback.md
================================================
# Compilation and readback

How are terms compiled to interaction net nodes?

HVM has a bunch of useful nodes to write IC programs.
Every node contains one `main` port `0` and two `auxiliary` ports, `1` and `2`.

There are 7 kinds of nodes, Eraser, Constructor, Duplicator, Reference, Number, Operation and Match.

A lambda `λx x` compiles into a Constructor node.
An application `((λx x) (λx x))` also compiles into a Constructor node.

```
  0 - Points to the lambda occurrence      0 - Points to the function
  |                                        |
  λ Lambda                                 @ Application
 / \                                      / \
1   2 - Points to the lambda body        1   2 - Points to the application occurrence
|                                        |
Points to the lambda variable            Points to the argument
```

When reading back, if we visit a Constructor via port 0 then we know it's a lambda, and if we visit it via port 2 it's an application.

- The `Number` node uses the label to store it's number.
- An `Operation` node uses the label to store it's operation.

A duplication `let {a b} = x` compiles into a Duplicator node.
A superposition `{a b}` compiles to a Duplicator node too. The difference here comes from context too.

```
  0 - Points to the sup occurrence         0 - Points to the duplicated value
  |                                        |
  # Superposition                          # Duplication
 / \                                      / \
1   2 - Points to the second value       1   2 - Points to the second binding
|                                        |
Points to the first value                Points to the first binding
```
Bend core terms directly compile to HVM nodes.
- Application -> CON node with --+ polarization.
- Lambda -> CON node with ++- polarization.
- Duplication -> DUP node with -++ polarization.
- Superposition -> DUP node with +-- polarization
- Pairs -> CON node with +-- polarization.
- Pair elimination -> CON node with -++ polarization.
- Erasure values (as in λx *) -> ERA node with + polarization.
- Erased variables (as in λ* x) -> ERA node with + polarization.
- Numbers -> NUM node (always + polarization).
- Switches -> MAT node (--+) + CON node (+--) on port 1 that links to the if 0 and if >= 1 cases.
- Numeric operations -> an OPR node (--+) plus a NUM that holds the kind of operation as per the HVM2 paper.
- References to top level functions -> REF node (+).

Matches get compiled to the above core constructs according to the adt-encoding option.
Check out [HVM2](https://github.com/HigherOrderCO/HVM), one of the Higher Order Company's projects, to know more about this.

### Bend compiler passes:

**encode_adt**: Create functions for constructors.  
**desugar_open**: Convert open terms into match terms.  
**encode_builtins**: Convert sugars for builtin types (e.g., list, string) into function calls.  
**desugar_match_def**: Convert equational-style pattern matching functions into trees of match and switch terms.  
**fix_match_terms**: Normalize all match and switch terms.  
**lift_local_defs**: Convert `def` terms into top-level functions.  
**desugar_bend**: Convert Bend terms into top-level functions.  
**desugar_fold**: Convert `fold` terms into top-level functions.  
**desugar_with_blocks**: Convert `with` terms and ask (`<-`) terms into monadic bind and unit (wrap).  
**make_var_names_unique**: Give a unique name to each variable in each function.  
**desugar_use**: Resolve alias terms (`use`) by substituting their occurrences with the aliased term (syntactic duplication).  
**linearize_matches**: Linearize the variables in match and switch terms according to the linearize-matches option.  
**linearize_match_with**: Linearize the variables specified in `with` clauses of match and switch if they haven't already been linearized by `linearize_matches`.  
**type_check_book**: Run the type checker (no elaboration, only inference/checking).  
**encode_matches**: Transform match terms into their lambda-calculus forms as specified by the adt-encoding option.  
**linearize_vars**: Linearize the occurrences of variables by placing duplicates when variables are used more than once, erasing unused variables, and inlining `let` terms whose variables only occur once.  
**float_combinators**: Convert combinator terms into top-level functions according to the size heuristic described in the source code.  
**prune**: Remove unused functions according to the prune option.  
**merge_definitions**: Merge identical top-level functions.  
**expand_main**: Expand the term of the `main` function by dereferencing so that it includes computation and isn't just lazy refs or data containing lazy refs.  
**book_to_hvm**: Lower to HVM (as described in the compilation-and-readback file).  
**eta**: Perform eta-reduction at the inet level without reducing nodes with `ERA` or `NUM` at both ports (logically equivalent but looks incorrect to users).  
**check_cycles**: Heuristic check for mutually recursive cycles of function calls that could cause loops in HVM.  
**inline_hvm_book**: Inline REFs to networks that are nullary nodes.  
**prune_hvm_book**: Additional layer of pruning after eta-reducing at the inet level.  
**check_net_sizes**: Ensure no generated definition will be too large to run on the CUDA runtime.  
**add_recursive_priority**: Mark some binary recursive calls with a flag at the inet level so that the GPU runtime can properly distribute work.



================================================
FILE: docs/compiler-options.md
================================================
# Options

| flag                                                                     | Default       | What it does?                             |
| ------------------------------------------------------------------------ | ------------- | ----------------------------------------- |
| `-Oall`                                                                  | Disabled      | Enables all compiler passes               |
| `-Ono-all`                                                               | Disabled      | Disables all compiler passes              |
| `-Oeta` `-Ono-eta`                                                       | Disabled      | [eta-reduction](#eta-reduction)           |
| `-Oprune` `-Ono-prune`                                                   | Disabled      | [definition-pruning](#definition-pruning) |
| `-Olinearize-matches` `-Olinearize-matches-alt` `-Ono-linearize-matches` | Enabled       | [linearize-matches](#linearize-matches)   |
| `-Ofloat-combinators` `-Ono-float-combinators`                           | Enabled       | [float-combinators](#float-combinators)   |
| `-Omerge` `-Ono-merge`                                                   | Disabled      | [definition-merging](#definition-merging) |
| `-Oinline` `-Ono-inline`                                                 | Disabled      | [inline](#inline)                         |
| `-Ocheck-net-size` `-Ono-check-net-size`                                 | Disabled      | [check-net-size](#check-net-size)         |
| `-Oadt-scott` `-Oadt-num-scott`                                          | adt-num-scott | [adt-encoding](#adt-encoding)             |
| `-Otype-check` `-Ono-type-check`                                         | type-check    | [type-checking](#type-checking)            |
## Eta-reduction

Enables or disables Eta Reduction for defined functions.

Eta reduction simplifies lambda expressions, removing redundant parameters. [See also](https://wiki.haskell.org/Eta_conversion).

Example:

```py
# program
id = λx x
id_id = λx (id x)

# -Oeta
id_id = id

# -Ono-eta
id_id = λz (id z)
```

## Definition-pruning

If enabled, removes all unused definitions.

Example:

```py
# program
Id = λx x

Id2 = Id

Main = (Id 42)

# -Oprune
Id = λx x

Main = (Id 42)

# -Ono-prune
Id = λx x

Id2 = Id

Main = (Id 42)
```

## Definition-merging

If enabled, merges definitions that are identical at the term level.

Example:

```py
# Original program
id = λx x
also_id = λx x
main = (id also_id)

# After definition merging
id_$_also_id = λx x
main = (id also_id)

# -Ono-merge, compilation output
@also_id = (a a)
@id = (a a)
@main = a
& @id ~ (@also_id a)

# -Omerge, compilation output
@a = (a a)
@main = a
& @a ~ (@a a)
```

## linearize-matches

Linearizes the variables between match cases, transforming them into combinators when possible.

```py
# Linearization means going from this
@a @b switch a {
  0: (Foo b)
  _: (Bar a-1 b)
}
# To this
@a @b (switch a {
  0: @b (Foo b)
  _: @b (Bar a-1 b)
} b)
```

When the `linearize-matches` option is used, only linearizes variables that would generate an eta-reducible application.

Example:

```py
λa λb switch a { 0: b; _: b }

# Is transformed to
λa switch a { 0: λb b; _: λb b }

# But this stays the same
λa λb switch b { 0: a; _: a }
```

When the `linearize-matches-extra` option is used, it linearizes all variables used in the arms.

example:

```py
λa λb λc switch b { 0: a; _: c }

# Is transformed to (without eta-reducing 'c')
λa λb λc (switch b { 0: λa λc a; _: λa λc c } a c)
```

These automatic linearization passes are done before the manual linearization from `with` and doesn't duplicate manually linearized variables.

```py
# These variables are only linearized once
λa λb λc switch a with b c { 0: (b c); _: (a-1 b c) }

# With -Olinearize-matches becomes
λa λb λc (switch a { 0: λb λc (b c); _: λb λc (a-1 b c) } b c)

# And not
λa λb λc (switch a { 0: λb λc λb λc (b c); _: λb λc λb λc  (a-1 b c) } b c b c)
```

## float-combinators

Extracts closed terms to new definitions. See [lazy definitions](lazy-definitions.md#automatic-optimization).
Since HVM-Core is an eager runtime, this pass is enabled by default to prevent infinite expansions.

Example:

```py
True  =    λt λf λm t
False =    λt λf λm f
Maybe = λx λt λf λm (m x)

getVal = λb (b 1 0 (λx (== x 1)))
# `(λx (== x 1))` can be extracted, since there is no free variables.

Cons = λh λt λc λn (c h t)
Nil  = λc λn n

fold = λinit λf λxs (xs λh λt (fold (f init h) f t) init)
# Here we need to extract `λh λt (fold (f init h) f t)` to not expand `fold` infinitely, but it will not be extracted because of the free variable `init`.
```

# Inline

If enabled, inlines terms that compile to nullary inet nodes (refs, numbers, erasures).

Example:

```py
# program
foo = 2
id = λx x
main = (id foo)

# -Ono-inline, compilation output
@foo = 2
@id = (a a)
@main = a
& @id ~ (@foo a)

# -Oinline, compilation output
@foo = 2
@id = (a a)
@main = a
& @id ~ (2 a)
```

## Check-net-size

If enabled, checks that the size of each function after compilation has at most 64 HVM nodes.
This is a memory restriction of the CUDA runtime, if you're not using the `*-cu` you can disable it.

Example:

```py
# Without -Ocheck-net-size compiles normally.
# But with -Ocheck-net-size it fails with
# `Definition is too large for hvm`
(Radix n) =
  let r = Map_/Used
  let r = (Swap (& n 1) r Map_/Free)
  let r = (Swap (& n 2) r Map_/Free)
  let r = (Swap (& n 4) r Map_/Free)
  let r = (Swap (& n 8) r Map_/Free)
  let r = (Swap (& n 16) r Map_/Free)
  let r = (Swap (& n 32) r Map_/Free)
  let r = (Swap (& n 64) r Map_/Free)
  let r = (Swap (& n 128) r Map_/Free)
  let r = (Swap (& n 256) r Map_/Free)
  let r = (Swap (& n 512) r Map_/Free)
  let r = (Swap (& n 1024) r Map_/Free)
  let r = (Swap (& n 2048) r Map_/Free)
  let r = (Swap (& n 4096) r Map_/Free)
  let r = (Swap (& n 8192) r Map_/Free)
  let r = (Swap (& n 16384) r Map_/Free)
  let r = (Swap (& n 32768) r Map_/Free)
  let r = (Swap (& n 65536) r Map_/Free)
  let r = (Swap (& n 131072) r Map_/Free)
  let r = (Swap (& n 262144) r Map_/Free)
  let r = (Swap (& n 524288) r Map_/Free)
  let r = (Swap (& n 1048576) r Map_/Free)
  let r = (Swap (& n 2097152) r Map_/Free)
  let r = (Swap (& n 4194304) r Map_/Free)
  let r = (Swap (& n 8388608) r Map_/Free)
  r
```

## ADT Encoding

Selects the lambda encoding for types defined with `type` and `object`.

`-Oadt-scott` uses Scott encoding.
`-Oadt-num-scott` uses a variation of Scott encoding where instead of one lambda per constructor, we use a numeric tag to indicate which constructor it is. The numeric tag is assigned to the constructors in the order they are defined and each tag is accessible as a definition by `<type>/<ctr>/tag`.

```py
# Generates functions Option/Some and Option/None
type Option:
  Some { value }
  None

# With -Oadt-scott they become:
Option/Some = λvalue λSome λNone (Some value)
Option/None = λSome λNone (None)

# With -Oadt-num-scott they become:
Option/Some = λvalue λx (x Option/Some/tag value)
Option/None = λx (x Option/None/tag)

# Generated -Oadt-num-scott tags:
Option/Some/tag = 0
Option/None/tag = 1
```

Pattern-matching with `match` and `fold` is generated according to the encoding.

Note: IO is **only** available with `-Oadt-num-scott`.

## Type Checking

Type checking is enabled by default and verifies and enforces the constraints of types. When enabled, verifies the type safety of the program based on the source code. If it passes the check, then the program is guaranteed to satisfy type constraints for all possible inputs.

```py
  def main() -> Bool: 
    return 3
```
With type checking enabled, The following program will throw a type error `Expected function type 'Bool' but found 'u24'`, whereas if it is disabled, it will compile successfully and return `3`.


================================================
FILE: docs/defining-data-types.md
================================================
# Defining data types

It is possible to easily define complex data types using the `type` keyword.

```py
# A Boolean is either True or False 
type Bool:
  True
  False
```

If a constructor has any arguments, parentheses are necessary around it:
```py
# An option either contains some value, or None
type Option:
 Some { value }
 None
```
If the data type has a single constructor, it can be destructured using `open`:

```py
# A Box is a wrapper around a value.
type Boxed:
  Box { value }

def main() -> _:
  b = Boxed/Box(1)
  open Boxed: b
  return b.value
```


The fields of the constructor that is being destructured with the `match` are bound to the matched variable plus `.` and the field names.
```py
opt = Option/Some(1)
match opt:
  case Option/Some:
    return opt.value
  case Option/None:
    return 0
```

Rules can also have patterns.
They work like match expressions with explicit bindings:

```py
(Option.map (Some value) f) = (Some (f value))
(Option.map None f) = None
```

However, they also allow matching on multiple values at once, which is something that regular `match` can't do:

```py
type Boolean:
  True
  False

(Option.is_both_some (Some lft_val) (Some rgt_val)) = True
(Option.is_both_some lft rgt) = False
```

You can read more about pattern matching rules in [Pattern matching](/docs/pattern-matching.md).

In conclusion, the `type` keyword is very useful as it allows you to easily create data types and deconstruct them.


================================================
FILE: docs/dups-and-sups.md
================================================
# Dups and sups

Term duplication is done automatically when a variable is used more than once. But it's possible to manually duplicate a term using `let`. This type of statement is called `dup` or `duplication`.
```py
# the number 2 in church encoding using let.
ch2 = λf λx let {f1 f2} = f; (f1 (f2 x))

# the number 3 in church encoding using let.
ch3 = λf λx let {f0 f1} = f; let {f2 f3} = f0; (f1 (f2 (f3 x)))
```

A `sup` is a superposition of two values, it is defined using curly brackets with two terms inside. A superposition is the opposite of a duplication. 
```py
sup = {3 7}
```

Sups can be used anywhere a value is expected, if anything interacts with the superposition, the result is the superposition of that interaction on both the possible values:

```py
mul = λa λb (* a b)
result     = (mul 2 5)         # returns 10
result_sup = (mul 2 {5 7})     # returns {10 14}
multi_sup  = (mul {2 3} {5 7}) # returns {{10 14} {15 21}}
```

If we pair a superposition with a duplication, the result is that they behave like constructing and destructing a pair:

```py
# each dup variable now has a copy of the {1 2} superposition
let {x1 x2} = {1 2}
```

Due to how duplications are compiled, when two dups interact, they destructively interfere with each other.
In this case the result doesn't follow the expected behavior (it's well defined at the HVM level, but is incorrect at a lambda-calculus level).

That imposes a strong restriction on correct Bend programs: a variable should not duplicate another variable that itself duplicates some variables.

The program below is an example where this can go wrong when using higher-order functions.
```py
def List/map(xs: List(A), f: A -> B) -> List(B):
  fold xs:
    case List/Nil:
      return List/Nil
    case List/Cons:
      # 'f' is duplicated here
      return List/Cons(f(xs.head), List/map(xs.tail, f))
      # This line above is converted by the compiler to an explicit duplication of 'f'
      # {f1 f2} = f
      # return List/Cons(f1(xs.head), List/map(xs.tail, f2))

def main() -> _:
  # This lambda duplicates `x` and is itself duplicated by the map function.
  # This will result in wrong behavior.
  # In this specific case, the runtime will catch it and generate an error,
  # but at the moment that is not always the case.
  return List/map([1, 2, 3], lambda x: (+ x x))
```

In this case, we can only have one source of duplication, or our results will be incorrect.
Either List/map is linear (doesn't duplicate `f`) or the passed function is linear (doesn't duplicate `x` or any other variable inside it).


================================================
FILE: docs/ffi.md
================================================
# Dynamically linked libraries and foreign functions

We can add new IO functions to Bend during runtime by loading dynamic libraries.

## Using IO dynamic libraries in Bend

Here is an example of how we could load a Bend library that contains functions for working with directories.

```py
def main():
  with IO:
    # Open the dynamic library file
    # The second argument is '0' if we want to load all functions immediately.
    # Otherwise it should be '1' when we want to load functions as we use them.
    # 'dl' is the unique id of the dynamic library.
    dl <- IO/DyLib/open("./libbend_dirs.so", 0)

    # We can now call functions from the dynamic library.
    # We need to know what functions are available in the dynamic library.
    # If you're writing a library for Bend that uses a dynamically linked library
    # you should wrap the IO calls so that users don't need to know what's in the dynamic library.

    # The first argument is the dynamic library id.
    # The second argument is the name of the function we want to call as a String.
    # The third argument are the arguments to the function.
    # You need to know the types of the arguments and the return type of the function.

    # In our example, 'ls' receives a path as a String and
    # returns a String with the result of the 'ls' command.
    unwrapped_dl = Result/unwrap(dl)
    files_bytes <- IO/DyLib/call(unwrapped_dl, "ls", "./") 
    files_str = String/decode_utf8(Result/unwrap(files_bytes)) 
    files = String/split(files_str, '\n')

    # We want to create a directory for a new user "my_user" if it doesn't exist.
    my_dir = List/filter(files, String/equals("my_dir"))
    match my_dir:
      case List/Cons:
        # The directory already exists, do nothing.
        * <- IO/print("Directory already exists.\n")
        status = wrap(-1)
      case List/Nil:
        # The directory doesn't exist, create it.
        * <- IO/DyLib/call(unwrapped_dl, "mkdir", "./my_dir")
        * <- IO/print("Directory created.\n")
        status = wrap(+0)
    status <- status

    # Here the program ends so we didn't need to close the dynamic library,
    # but it's good practice to do so once we know we won't need it anymore.
    * <- IO/DyLib/close(unwrapped_dl)
    return wrap(status)
```

## Writing IO dynamic libraries for Bend

Bend IO libraries need to be implemented in C or Cuda (depending on the backend you're targeting) using the HVM API.

### Writing libraries for the C runtime

The functions you call from Bend using `IO/DyLib/call` must have the following signature:

```c
Port function_name(Net* net, Book* book, Port arg);
```

Where:

- `net` is a pointer to the current network state.
- `book` is a pointer to the book of function definitions.
- `arg` is a pointer to the arguments of the function.

The return value must be a `Port` that points to the return value of the function.

HVM provides some util functions to do the conversions from HVM to C and vice versa,
so that you don't need to understand the details of the HVM runtime.

We can implement the example library from earlier for the C runtime with the following C code:

```c
// This is a header file that contains the HVM API.
#include "hvm.h"

// The headers we need to open and read directories.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

// IO functions must have this exact signature.
// The first argument is a pointer to the graph with the current state of the program.
// The second argument is a pointer to the book of function definitions.
// The third argument points to the arguments of the function.
// The return value must be a port that points to the return value of the function.
Port ls(Net* net, Book* book, Port arg) {
  // The arguments first need to be converted from HVM to C.
  // For the 'ls' function, this is just a single string.
  Str path = readback_str(net, book, arg);


  // Now we can do the actual IO operations.
  // In this case, we list the contents of the directory
  // by calling the 'ls' program as a subprocess.
  char* cmd = malloc(path.len + strlen("ls ") + 1);
  sprintf(cmd, "ls %s", path.buf);
  free(path.buf);

  FILE* pipe = popen(cmd, "r");
  if (pipe == NULL) {
    // It'd be best practice to return a Result type instead of a null value (ERA).
    // If this command fails and the calling Bend program tries to use the result,
    // it will get corrupted and spit out garbage.
    fprintf(stderr, "failed to run command '%s': %s\n", cmd, strerror(errno));
    return new_port(ERA, 0);
  }
  char buffer[512];
  Bytes output = { .buf = NULL, .len = 0 };
  while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
    size_t len = strlen(buffer);
    char* new_result = realloc(output.buf, output.len + len + 1);
    if (new_result == NULL) {
      fprintf(stderr, "failed to allocate space for output of '%s': %s\n", cmd, strerror(errno));
      free(cmd);
      free(output.buf);
      pclose(pipe);
      return new_port(ERA, 0);
    }
    output.buf = new_result;
    strcpy(output.buf + output.len, buffer);
    output.len += len;
  }

  // After we're done with the operation, we convert it to HVM format.
  // In this case, the output is the output of the 'ls' command as a list of bytes.
  // We need to process it in Bend later to convert it to a list of file names.
  Port output_port = inject_bytes(net, &output);

  // Remember to free all the allocated memory.
  free(cmd);
  free(output.buf);
  pclose(pipe);
  return output_port;
}

Port mkdir(Net* net, Book* book, Port arg) {
  // We do the same thing here as in the 'ls' function,
  // except we call 'mkdir' which doesn't output anything.
  Str path = readback_str(net, book, arg);

  char* cmd = malloc(path.len + strlen("mkdir ") + 1);
  sprintf(cmd, "mkdir %s", path.buf);
  int res = system(cmd);

  free(path.buf);
  free(cmd);
  return new_port(ERA, 0);
}
```

To compile this code into a library, we can use the `gcc` compiler and include the HVM header files.

Assuming that it's saved in a file called `libbend_dirs.c`, we can compile it with the following command:

```sh
# Needs to be compiled as a shared library with unresolved symbols.
# For macOS:
gcc -shared -o libbend_dirs.so -I /path/to/HVM/src/ libbend_dirs.c -undefined dynamic_lookup -fPIC

# For Linux:
gcc -shared -o libbend_dirs.so -I /path/to/HVM/src/ libbend_dirs.c -Wl,--unresolved-symbols=ignore-all -fPIC
```

Now we can use the dynamic library in our Bend program, we just need to pass the path to the library to `IO/DyLib/open`.

### Writing libraries for the Cuda runtime

Writing libraries for the Cuda runtime is very similar to writing libraries for the C runtime.

The main difference is the function signature:

```c++
Port function_name(GNet* gnet, Port argm)
```

Where:

- `gnet` is a pointer to the current network state.
- `argm` is the argument to the function.

The return value must be a `Port` that points to the return value of the function.

To compile libraries of the Cuda runtime, we can use the `nvcc` compiler and include the HVM header files.

Assuming that it's saved in a file called `libbend_dirs.cu`, we can compile it with the following command:

```sh
nvcc -shared -o libbend_dirs.so -I /path/to/hvm/ libbend_dirs.cu
```

### Compiling Bend programs that use dynamic libraries

To compile the C or Cuda program generated from a Bend program that uses dynamic libraries, we need to use the `-rdynamic` flag to allow the dynamic library to use symbols from the main program.

For example, if we have a Bend program called `main.bend` that uses the dynamic library `libbend_dirs.so`, we need compile to it with the following commands:

```sh
# Compiling for C
bend gen-c my_app.bend > my_app.c
gcc -rdynamic -lm my_app.c -o my_app

# Compiling for Cuda
bend gen-cu my_app.bend > my_app.cu
nvcc --compiler-options=-rdynamic my_app.cu -o my_app
```


================================================
FILE: docs/imports.md
================================================
# Import System

## Case Sensitivity
All import paths are case-sensitive. Ensure that the case used in import statements matches exactly with the file and directory names.

## Syntax
Imports can be declared two ways:

```py
from path import name
# or
import path/name
# We recommend always placing the imports at the top of the file.
```

## Project Structure
Let's assume we have a bend project with the following structure:

```
my_project/
├── main.bend
├── utils/
│   ├── helper.bend
│   │   └── def calc
│   └── math.bend
│       ├── def add
│       └── def subtract
```

## Importing Relative Paths
Paths starting with `./` or `../` are imported relative to the file.

### Example:
```py
# if used inside `my_project/*.bend`
from ./utils import helper
# if used inside `my_project/*/*.bend`
import ../utils/helper
```

This will bind `calc` from `helper.bend` as `helper/calc`.

## Importing Absolute Paths
Otherwise, paths imported are relative to the folder of the main file.

### Example:
```py
from utils import math
# or
import utils/math
```

This will bind `add` and `subtract` from `math.bend` as `math/add` and `math/subtract`.

## Importing Specific Top-Level Names
You can import specific top-level names from a file.

### Example:
```py
from utils/helper import calc
from utils/math import (add, subtract)
# or
import (utils/helper/calc, utils/math/add, utils/math/subtract)
# or
import utils/helper/calc
import utils/math/add
import utils/math/subtract
```

This will bind the names `calc`, `add` and `subtract` from their respective files. 

## Importing All Names
You can import all top-level names from a file using the wildcard `*`.

### Example:
```py
from utils/math import *
```

This will bind the names `add` and `subtract` from `math.bend`. 

## Importing All `.bend` Files from a Folder
You can import all `.bend` files from a folder using the wildcard `*`.

### Example:
```py
from utils import *
```

This will bind the names from `helper.bend` and `math.bend`, as `helper/calc`, `math/add` and `math/subtract`.

## Aliasing Imports
You can alias imports to a different name for convenience.

### Importing a File with Alias
Import the `file` top-level name from `file.bend` aliased to `alias`, and all other names as `alias/name`.

### Example:
```py
from utils import helper as utilsHelper
import utils/math as mathLib
```

This will bind the names from `helper.bend` and `math.bend`, as `utilsHelper/calc`, `mathLib/add` and `mathLib/subtract`.

### Importing Specific Names with Aliases
You can import specific top-level names and alias them to different names.

### Example:
```py
from utils/helper import calc as calcFunc
from utils/math import (add as addFunc, subtract as subFunc)
# or
import (utils/math/add as addFunc, utils/math/subtract as subFunc)
```

This will bind `calc`, `add` and `subtract` as `calcFunc`, `addFunc` and `subFunc` from their respective files.

## Project Structure
Let's assume we have a bend project with the following structure:

```
my_project/
├── main.bend
├── types/
│   ├── List.bend
│   │   └── type List: Nil | (Cons ..)
│   └── List/
│       ├── concat.bend
│       │   └── def concat
│       └── append.bend
│           └── def append
│           └── def helper
```

## Importing data types

You can import a data type and its constructors by only importing its name.

### Example:
```py
from types/List import List
# behaves the same as 
from types/List import (List, List/Nil, List/Cons)
```

Importing only `List` from `List.bend` will import the type `List` and bind its constructors name `List/Nil` and `List/Cons`. 

## Importing files with a top level name equal to its name

When a file and a top-level name in it share a name, for example, `List.bend`, `concat.bend` and `append.bend`, the bind of that import is simplified to the file name.

### Example:
```py
from types/List import append
```

This will bind `append` and `append/helper` from `append.bend`.

## Files and directories with the same name

When files and directories share a name, both share the import namespace:

```py
from types/List import (List, concat)
```

This will attempt to import from both the `List.bend` file and the `List` folder, resulting in the binds `List/Nil`, `List/Cons` and `concat`.

```py
from types/List import *
```

This will import all the names from `List.bend`, then all the files inside the `List` folder, resulting in the binds `List/Nil`, `List/Cons`, `concat`, `append` and `append/helper`.

In both cases, if a name is present as a top-level name on the file, and as a `.bend` file name inside the folder, it will result in an error.

If you only want to import `List.bend` and not search the files in its folder, you can use the `import path` syntax:

```py
import types/List
```


================================================
FILE: docs/lazy-definitions.md
================================================
# Making recursive definitions lazy

In strict-mode, some types of recursive terms will unroll indefinitely.

This is a simple piece of code that works on many other functional programming languages but hangs on Bend due to the strict evaluation of HVM2.

```rust
Cons = λx λxs λcons λnil (cons x xs)
Nil  =        λcons λnil nil

Map = λf λlist
  let cons = λx λxs (Cons (f x) (Map f xs))
  let nil = Nil
  (list cons nil)

Main = (Map λx (+ x 1) (Cons 1 Nil))
```

The recursive `Map`  creates an infinite reduction sequence because each recursive call expands into another call to Map, never reaching a base case. Which means that functionally, it will reduce it infinitely, never reaching a normal form. 

For similar reasons, if we try using Y combinator it also won't work.

```rust
Y = λf (λx (f (x x)) λx (f (x x)))

Map = (Y λrec λf λlist
  let cons = λx λxs (Cons (f x) (rec f xs))
  let nil = Nil
  (list cons nil f))
```

By linearizing `f`, the `Map` function only expands after applying the argument `f`, because the `cons` function will be lifted to a separate top-level function by the compiler (when this option is enabled).

```rust
Map = λf λlist
  let cons = λx λxs λf (Cons (f x) (Map f xs))
  let nil = λf Nil
  (list cons nil f)
```

This code will work as expected, since `cons` and `nil` are lambdas without free variables, they will be automatically floated to new definitions if the [float-combinators](compiler-options.md#float-combinators) option is active, allowing them to be unrolled lazily by hvm.

The recursive part of the function should be part of a combinator that is not in an active position. That way it can be lifted into a top-level function which is compiled into a lazy reference thus preventing the infinite expansion. [Supercombinators](https://en.wikipedia.org/wiki/Supercombinator) can be used in order to ensure said lazy unrolling of recursive terms. Other combinator patterns can work as well, as long as they're lifted to the top level.

If you have a set of mutually recursive functions, you only need to make one of the steps lazy. This might be useful when doing micro-optimizations, since it's possible to avoid part of the small performance cost of linearizing lambdas.

### Automatic optimization

Bend carries out [match linearization](compiler-options.md#linearize-matches) and [combinator floating](compiler-options.md#float-combinators) optimizations, enabled through the CLI, which are active by default in strict mode.

Consider the code below:

```rs
Zero = λf λx x
Succ = λn λf λx (f n)
ToMachine = λn (n λp (+ 1 (ToMachine p)) 0)
```

The lambda terms without free variables are extracted to new definitions.

```rs
ToMachine0 = λp (+ 1 (ToMachine p))
ToMachine = λn (n ToMachine0 0)
```

Definitions are lazy in the runtime. Floating lambda terms into new definitions will prevent infinite expansion.

It's important to note that preventing infinite expansion through simple mutual recursion doesn't imply that a program lacks infinite expansion entirely or that it will terminate.


================================================
FILE: docs/native-numbers.md
================================================
# Native numbers

Currently Bend supports 3 types of native numbers for fast numeric operations (compared to lambda-encoded numbers):

- U24: Unsigned integers (24 bits)
- I24: Signed integers (24 bits, two's complement)
- F24: Floating point numbers (single precision IEEE-754 floating point with the last bits of the mantissa implicitly set to zero)

### U24

Unsigned numbers are written as just the number and are represented as a 24 bit unsigned integer.

```rs
two = 2
```

### I24

Signed numbers are written with a `+` or `-` sign and are represented as a 24 bit two's complement integer.

```rs
minus_two = -2
plus_0 = +0
```

Positive numbers _must_ be written with a `+` sign, otherwise they'll be interpreted as unsigned.

Numbers can also be written in binary or hexadecimal form. Underscores can be optionally used as digit separators to make large numbers more readable.

```rs
decimal =     1194684
binary =      0b100_100_011_101_010_111_100
hexadecimal = 0x123_abc
hex_signed = -0xbeef
```

### F24

Floating point numbers must have the decimal point `.` and can optionally take a sign `+` or `-`.
They are represented as IEEE-754 single precision floating point numbers with the last bits of the mantissa implicitly set to zero.

```py
one = 1.0
pi = +3.1415926535897932384626433 # Will get rounded to 24bit float
a_millionth = 0.000001
zero = 0.0
minus_zero = -0.0
```

### Mixing number types

The three number types are fundamentally different. At the HVM level, both type and the operation are stored inside the number nodes as tags. One number stores the type, the other the operation.
That means that we lose the type information of one of the numbers, which causes this behavior.
During runtime, the executed numeric function depends on both the type tag and the operation tag. For example, the same tag is used for unsigned bitwise and floating point atan2, so if you mix two numbers of different types, HVM will interpret the binary representation of one of them incorrectly, leading to incorrect results. Which number is interpreted incorrectly depends on the situation and shouldn't be relied on for now. Instead, you should make sure that all numbers are of the same type. 

#### Casting numbers

There is a way to convert between the different number types, and using it is very easy, here's an example:

```py
def main() -> _:
  x = f24/to_i24(1.0)
  y = u24/to_f24(2)
  z = i24/to_u24(-3)

  return (x, y, z)
```
You can find more number casting functions and their declarations at [builtins.md](docs/builtins.md).


### Operations

There is also support for native operations.
In "Imp" syntax they are infix operators and in "Fun" syntax they are written in reverse polish notation (like you'd call a normal function).
Each operation takes two arguments and returns a new number.

```rs
# In Fun syntax
some_val = (+ (+ 7 4) (* 2 3))
```

These are the currently available operations:

| Operation | Description              | Accepted types | Return type       |
| --------- | ------------------------ | -------------- | ----------------- |
| \+        | Addition                 | U24, I24, F24  | Same as arguments |
| \-        | Subtraction              | U24, I24, F24  | Same as arguments |
| \*        | Multiplication           | U24, I24, F24  | Same as arguments |
| \/        | Division                 | U24, I24, F24  | Same as arguments |
| \%        | Modulo                   | U24, I24, F24  | Same as arguments |
| \==       | Equality                 | U24, I24, F24  | U24               |
| \!=       | Inequality               | U24, I24, F24  | U24               |
| \<        | Less than                | U24, I24, F24  | U24               |
| \<=       | Less than or equal to    | U24, I24, F24  | U24               |
| \>        | Greater than             | U24, I24, F24  | U24               |
| \>=       | Greater than or equal to | U24, I24, F24  | U24               |
| \&        | Bitwise and              | U24, I24       | Same as arguments |
| \|        | Bitwise or               | U24, I24       | Same as arguments |
| \^        | Bitwise xor              | U24, I24       | Same as arguments |
| \*\*      | Exponentiation           | F24            | F24               |

### Functions

| Name           | Description                     | Accepted types | Return type |
| -------------- | ------------------------------- | -------------- | ----------- |
| `log(x, base)` | Logarithm                       | F24            | F24         |
| `atan2(x, y)`  | 2 arguments arctangent (atan2f) | F24            | F24         |

### Pattern matching

Bend also includes a `switch` syntax for pattern-matching U24 numbers.

```rs
Number.to_church = λn λf λx
  switch n {
    0: x
    _: (f (Number.to_church n-1 f x))
  }
```

The `0` case matches when `n` is 0, and the `_` case matches when `n` is greater than 0.
In the `_` arm, we can access the predecessor of `n` with the `n-1` variable.

We can also match on more than one value at once.
To do that, we must cover the cases in order, starting from 0.

```rs
Number.minus_three = λn λf λx
  switch n {
    0: 0
    1: 0
    2: 0
    _: n-3
  }
```

Using everything we learned, we can write a program that calculates the n-th Fibonacci number using native numbers:

```py
fibonacci = λn # n is the argument
  switch n {
    # If the number is 0, then return 0
    0: 0
    # If the number is 1, then return 1
    1: 1
    # Otherwise, return the sum of (fib (n-2 + 1)) and (fib n-2)
    # The successor pattern provides a `var`-`successor number` bind
    _: (+ (fibonacci (+ n-2 1)) (fibonacci n-2))
  }

main = (fibonacci 15)
```

### Pattern matching numbers in Fun syntax equations

In Fun syntax, we can also use pattern matching equations to match on native unsigned numbers.

```rs
(fib 1) = 1
(fib 0) = 0
(fib n) = (+ (fib (- n 1)) (fib (- n 2)))
```

Unlike with `switch`, you can match any number and in any order.
The variable pattern is used to match on all other numbers.
Unlike with `switch`, you can't directly access the predecessor of the number.

You can read [Pattern matching](pattern-matching.md) for more information about how pattern matching equations are converted to `switch` and `match` expressions.


================================================
FILE: docs/pattern-matching.md
================================================
# Pattern Matching

Switches on many numbers are compiled to sequences of simple switch expressions:
```py
  # These two are equivalent
  switch n {
    0: A
    1: B
    2: C
    _: (D n-3)
  }

  switch n {
    0: A
    _: switch n-1 = n-1 {
      0: B
      _: switch n-2 = n-1-1 {
        0: C
        _: use n-3 = n-2-1; (D n-3)
      }
    }
  }
```

Matches on ADT constructors are compiled to different expressions depending on the chosen encoding:
```py
type Maybe = (Some val) | None

UnwrapOrZero x = match x {
  Maybe/Some: x.val
  Maybe/None: 0
}

# If the current encoding is 'adt-num-scott' it becomes:
Maybe/Some = λval λx (x 0 val)
Maybe/None = λx (x 1)
UnwrapOrZero x = (x λtag switch tag {
  0: λx.val x.val
  _: λ* 0
})

# Otherwise, if the current encoding is 'adt-scott' it becomes:
Maybe/Some = λval λMaybe/Some λMaybe/None (Maybe/Some val)
Maybe/None = λMaybe/Some λMaybe/None Maybe/None
UnwrapOrZero x = (x λx.val x.val 0)
```

### Pattern Matching functions

Besides `match`and `switch` terms, Bend also supports equational-style pattern matching functions.

```py
And Bool/True  b = b
And Bool/False * = Bool/False
```

There are advantages and disadvantages to using this syntax.
They offer more advanced pattern matching capabilities and also take care linearizing variables to make sure that recursive definitions work correctly in strict evaluation mode, but take away your control of how the pattern matching is implemented and can be a bit more resource intensive in some cases.

Pattern matching equations are transformed into a tree of `match` and `switch` terms from left to right.
```py
# These two are equivalent
(Foo 0 Bool/False (List/Cons h1 (List/Cons h2 t))) = (Bar h1 h2 t)
(Foo 0 * *) = Baz
(Foo n Bool/False *) = n
(Foo n Bool/True *) = 0

Foo = λarg1 λarg2 λarg3 (switch arg1 {
  0: λarg2 λarg3 match arg2 {
    Bool/True: λarg3 Baz
    Bool/False: λarg3 match arg3 {
      List/Cons: (match arg3.tail {
        List/Cons: λarg3.head (Bar arg3.head arg3.tail.head arg3.tail.tail)
        List/Nil: λarg3.head Baz
      } arg3.head)
      List/Nil: Baz
    }
  }
  _: λarg2 λarg3 (match arg2 {
    Bool/True: λarg1 0
    Bool/False: λarg1 arg1
  } arg1)
} arg2 arg3)
```
Besides the compilation of complex pattern matching into simple `match` and `switch` expressions, this example also shows how some arguments are pushed inside the match.
When compiling for strict evaluation, by default any variables that are used inside a match get linearized by adding a lambda in each arm and an application passing its value inwards.
To ensure that recursive pattern matching functions don't loop in strict mode, it's necessary to make the match arms combinators, so that they can be converted into separate functions and a lazy reference is used in the match arm.
```py
# This is what the Foo function actually compiles to.
# With -Olinearize-matches and -Ofloat-combinators (default on strict mode)
# Main function
(Foo) = λa λb λc (switch a { 0: Foo__C8; _: Foo__C9; } b c)

# Case 0 branch
(Foo__C8) = λa λb (a Foo__C5 b)                       # Foo.case_0
(Foo__C5) = λa switch a { 0: λ* Baz; _: Foo__C4; }    # Foo.case_0.case_true
(Foo__C4) = λ* λa (a Foo__C3)                         # Foo.case_0.case_false
(Foo__C3) = λa switch a { 0: Baz; _: Foo__C2; }       # Foo.case_0.case_false_cons
(Foo__C2) = λ* λa λb (b Foo__C1 a)                    # Foo.case_0.case_false_cons_cons
(Foo__C1) = λa switch a { 0: λ* Baz; _: Foo__C0; }    # Foo.case_0.case_false_cons_nil
(Foo__C0) = λ* λa λb λc (Bar c a b)                   # Foo.case_0.case_false_nil

# Case non-zero branch
(Foo__C9) = λa λb λc (b Foo__C7 c a)                  # Foo.case_+
(Foo__C7) = λa switch a { 0: λ* λ* 0; _: Foo__C6; }   # Foo.case_+.case_false
(Foo__C6) = λ* λ* λa (+ a 1)                          # Foo.case_+.case_true

# As an user, you can't write a function with __ on its name, that sequence is reserved for things generated by the compiler.
```

Pattern matching equations also support matching on non-consecutive numbers:
```rust
Parse '(' = Token.LParenthesis
Parse ')' = Token.RParenthesis
Parse 'λ' = Token.Lambda
Parse  n  = (Token.Name n)
```
The compiler transforms this into an optimized cascade of switch expressions. Each switch computes the distance from the smallest character to efficiently test each case:
```py
Parse = λarg0 switch matched = (- arg0 '(') {
  0: Token.LParenthesis
  # ')' + 1 - '(' is resolved during compile time
  _: switch matched = (- matched-1 ( ')'-1-'(' ) {
    0: Token.RParenthesis
    _: switch matched = (- matched-1 ( 'λ'-1-')' ) {
      0: Token.Lambda
      _: use n = (+ 1 matched-1); (Token.Name n)
    }
  }
}
```
Unlike with `switch`, with pattern matching equations you can't access the value of the predecessor of the matched value directly, but instead you can match on a variable. Instead, variables (like n above) are bound to computed expressions based on the matched value.
Notice how in the example above, `n` is bound to `(+ 1 matched-1)`.

Notice that this definition is valid, since `*` will cover both `p` and `0` cases when the first argument is `False`.This example shows how patterns are considered from top to bottom, with wildcards covering multiple specific cases:
```rust
pred_if Bool/False * if_false = if_false
pred_if Bool/True  p *        = (- p 1)
pred_if Bool/True  0 *        = 0
```

Pattern matching on strings and lists desugars to a list of matches on Cons and Nil

```py
Hi "hi" = 1
Hi _ = 0

Foo [] = 0
Foo [x] = x
Foo _ = 3

# Becomes:
Hi (String/Cons 'h' (String/Cons 'i' String/Nil)) = 2
Hi _ = 0

Foo List/Nil = 0
Foo (List/Cons x List/Nil) = x
Foo _ = 3
```


================================================
FILE: docs/syntax.md
================================================
# Syntax

This file provides a reference of each possible syntax of bend programming language.

Click [here](#imp-syntax) to see the syntax for "imp", the variant of bend that looks like an imperative language like python.

Click [here](#fun-syntax) to see the syntax for "fun", the variant of bend that looks like a functional language like Haskell or ML.

Click [here](#import-syntax) to see the import syntax.

Click [here](#comments) to see the syntax for commenting code.

Click [here](#imp-type-syntax) to see the imperative type syntax.

Click [here](#fun-type-syntax) to see the functional type syntax.

Both syntaxes can be mixed in the same file like the example below:

```python
object Point { x, y }

type MyTree = (Node ~left ~right) | (Leaf value)

type Bool:
  True
  False

#{
  The identity function is a function that always returns the value that
  was used as its argument.
#}
def identity(x):
  return x

main =
  let result = (identity 41)
  (+ result 1)
```

<div id="imp-syntax"></div>

# Imp Syntax

## Top-level definitions

### Def

Defines a top level function.

```python
def add(x: u24, y: u24) -> u24:
  result = x + y
  return result

def unchecked two() -> u24:
  return 2

def main() -> u24:
  return add(40, two)
```

A function definition is composed by a name, a sequence of parameters and a body.

A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names) or start with `//`.

The last statement of each function must either be a `return` or a selection statement (`if`, `switch`, `match`, `fold`)
where all branches `return`.

Each parameter of the function can receive a type annotation with `param_name: type` and the return value of the function can also be annotated with `def fn_name(args) -> return_type:`.

We can force the type-checker to run or not on a specific function by adding `checked` or `unchecked` between `def` and the function name.

### Type

Defines an algebraic data type.

```python
type Option:
  Some { value }
  None

type Tree(T):
  Node { value: T, ~left: Tree(T), ~right: Tree(T) }
  Leaf
```

Type names must be unique, and should have at least one constructor.

For a generic or polymorphic type, all type variables used in the constructors must be declared first in the type definition with `type Name(type_var1, ...):`

Each constructor is defined by a name followed by its fields. The fields can be annotated with types that will be checked when creating values of that type.

The `~` notation indicates a recursive field. To use `fold` statements with a type its recursive fields must be correctly marked with `~`.

The constructor names inherit the name of their types and become functions (`Tree/Node` and `Tree/Leaf` in this case).
The exact function they become depends on the encoding.

Read [defining data types](./defining-data-types.md) to know more.

### Object

Defines a type with a single constructor (like a struct, a record or a class).

```python
object Pair(A, B) { fst: A, snd: B }

object Function(T) { name: String, args, body: T }

object Vec { len, data }
```

The constructor created from this definition has the same name as the type.

Since it only has one constructor, `fold`ing a recursive `object` requires some additional stop condition apart from pattern matching on the value itself (like an `if` statement).

## Statements

### Assignment

```python
value = 2
return value

(first, second) = (1, 2)
return second

{x y} = {2 3}
```

Assigns a value to a variable.

It's possible to assign to a pattern, like a tuple or superposition, which will destructure the value returned by the expression.

```python
(first, second) = (1, 2)

first, second = 1, 2
```

### Use

```rust
use x = 2 + 3
return x + x
```

Inline copies of the declared bind, it is equivalent to this code:

```rust
return ((2 + 3) + (2 + 3))
```

### In-Place Operation

```python
x += 1
return x
```

The in-place operation does an infix operation and re-assigns a variable.

The operations are:

- Addition `+=`
- Subtraction `-=`
- Multiplication `*=`
- Division `/=`
- Bit And `&=`
- Bit Or `|=`
- Bit Xor `^=`
- Mapper `@=`

The mapper in-place operation applies a function and re-assigns the variable:

```python
x = "hello"
x @= String/uppercase
```

### Return

```python
return "hello"
```

Returns the expression that follows. The last statement of each branch of a function must be a `return`.

```py
# Allowed, all branches return
def max(a, b):
  if a > b:
    return a
  else:
    return b
```

```py
# Not allowed, early return
def Foo(x):
  if test_condition(x):
    return "err"
  else:
    y = map(x)

  return y
```

```py
# Not allowed, one of the branches doesn't return
def Foo(a, b):
  if a < b:
    return a
  else:
    c = a + b
```

### If

```python
if condition:
  return 0
else:
  return 1
```

A branching statement where `else` is mandatory.

The condition must return a `u24` number, where 0 will run the `else` branch and any other value will return the first one.

It is possible to make if-chains using `elif`:

```python
if condition1:
  return 0
elif condition2:
  return 1
elif condition3:
  return 2
else:
  return 3
```

The conditions are evaluated in order, one by one, stopping at the first successful case.

### Switch

```python
switch x = 5:
  case 0:
    return 6
  case 1:
    return 7
  case _:
    return x-2
```

A switch binds a variable name to the result of a given condition and branches to the case matching its value. Cases
must be listed from least to greatest, beginning with `0` and incrementing by 1. The last case must be `_`, which
catches all values not explicitly enumerated. Switches may only be used with native numbers values.

In the last case, the predecessor value is available with the name `bound_var-next_num`, where `bound_var` is the variable
set by the condition and `next_num` is the expected value of the next case. For example, the above example code returns
`3`, since `x-2` is bound to `5 - 2` and the value of `x` doesn't match any explicit case.

This switch statement is equivalent to the `if` from the previous section:

```python
switch _ = condition:
  case 0:
    # else branch
    return 1
  case _:
    # then branch
    return 0
```

### Match

```python
match x = Option/none:
  case Option/some:
    y = x.value
  case Option/none:
    y = 0
```

A pattern matching statement, the cases must be the constructor names of the matching value.

It is possible to bind a variable name to the matching value. The fields of the matched constructor are bound to `matched_var.field_name`.

### Fold

```python
fold x = Tree/Leaf:
  case Tree/Node:
    return x.value + x.left + x.right
  case Tree/Leaf:
    return 0
```

A fold statement. Reduces the given value with the given match cases.

It is possible to bind a variable name to the matching value. Just like in `match`, the fields are bound to `matched_var.field_name`.

For fields notated with `~` in the type definition, the fold function is called implicitly.

It is equivalent to the inline recursive function:

```python
def fold(x: Tree(u24)) -> u24:
  match x:
    case Tree/Node:
      return x.value + fold(x.left) + fold(x.right)
    case Tree/Leaf:
      return 0
...
fold(Tree/Leaf)
```

### Bend

Bend can be used to create recursive data structures:

```rust
bend x = 0:
  when x < 10:
    left = fork(x + 1)
    right = fork(x + 1)
    y = Tree/Node(left, right)
  else:
    y = Tree/Leaf(x)
```

Which binds a variable to the return of an inline recursive function.
The function `fork` is available inside the `when` arm of the `bend` and calls it recursively.

It is possible to pass multiple state variables, which can be initialized:

```python
bend x = 1, y = 2 ...:
  when condition(x, y, ...):
    ...
```

When calling `fork`, the function must receive the same number of arguments as the number of state variables.

It is equivalent to this inline recursive function:

```python
def bend(x, y, ...):
  if condition(x, y, ...):
    ...
    return ... bend(x, y, ...) ...
  else:
    return ...
```

### Open

```python
p = Point { x: 1, y: 2 }
open Point: p
return Point { x: p.x * p.x, y: p.y * p.y }
```

Brings the inner fields of an object into scope. The original variable can still be accessed, but doing so will cause any used fields to be duplicated.

It's equivalent to pattern matching on the object, with the restriction that its type must have only one constructor.

```python
open Point: p
...

# Equivalent to:
match p:
  Point:
    ...
```

### With block

```python
with Result:
  x <- safe_div(2, 0)
  return x
```

A monadic `with` block.

Where `x <- ...` performs a monadic operation.

Expects `Result` to be a type defined with `type` or `object` and the function `Result/bind` to be defined.
The monadic bind function should be of type `(Result a) -> (a -> Result b) -> Result b`, like this:

```python
def Result/bind(res, nxt):
  match res:
    case Result/Ok:
      nxt = undefer(nxt)
      return nxt(res.value)
    case Result/Err:
      return res
```

However, the second argument, `nxt`, is actually a deferred call to the continuation, passing any free variables as arguments.
Therefore, all `bind` functions must call the builtin function `undefer` before using the value of `nxt`, as in the example above.
This is necessary to ensure that the continuation in recursive monadic functions stays lazy and doesn't expand infinitely.

This is an example of a recursive function that would loop if passing the variable `a` to the recursive call `Result/foo(a, b)` was not deferred:

```python
def Result/foo(x, y):
  with Result:
    a <- Result/Ok(1)
    if b:
      b = Result/Err(x)
    else:
      b = Result/Ok(y)
    b <- b
    return Result/foo(a, b)
```

Other statements are allowed inside the `with` block and it can both return a value at the end and bind a variable, like branching statements do.

```python
# Also ok:
with Result:
  x <- safe_div(2, 0);
  y = x
return y
```

The name `wrap` is bound inside a `with` block as a shorthand for `Type/wrap`,
and it calls the unit function of the monad, also called `pure` in some languages:

```python
def Result/wrap(x):
  return Result/Ok(x)

with Result:
  x <- some_operation(...)
  y <- some_operation(...)
  return wrap(x * y)
```

### Def

Creates a local function visible in the current block capturing variables:

```python
def main() -> _:
  y = 41
  x = 1
  def aux_add(x):
    return x + y
  return aux_add(x)
```

## Expressions

### Variables

```python
some_var

foo/bar
```

A variable can be anything matching the regex `[A-Za-z0-9_.-/]+` but with some restrictions:

- It can not start with `//`
- It can not contain `__`

A variable is a name for some immutable expression. It is possible to rebind variables with the same name.

```python
x = 1
x = x + 1
```

Note that `-` is also used for negative numbers and as the numeric operator. Bend's grammar is greedily parsed from left to right, meaning that `x-3` always represents a name and not `x - 3` or a sequence of expressions like in `[x -3]`.

### Lambdas

```python
lambda x: x

lambda x, y: y

λx y: x
```

Lambdas represents anonymous inline functions, it can bind a variable and has an expression as body.

Using `,` is optional.

### Unscoped Lambdas and Variables

```python
lambda $x: $x

λ$x $y: $x
```

Like lambdas, with the exception that the variable starts with a `$` sign. Every unscoped variable in a function must have a unique name and must be used exactly once.

Unscoped variables are not transformed and linearized like normal scoped variables.

Read [using scopeless lambdas](/docs/using-scopeless-lambdas.md) to know more about their behavior.

### Function Call

```python
callee(arg_1, arg_2, arg_n)
```

A call is written with a callee followed by a list of arguments. Arguments can be optionally separated by `,`.

The effect of a function call is to substitute the callee with it's body and replace the arguments by the passed variables.

The called function can be any expression and it supports partial applications.

Optionally, if you call a function by its name, you can used named arguments:

```python
callee(expr1, expr2, arg4 = expr3, arg3 = expr4)
```

In case named arguments are used, they must come after the positional arguments and the function must be called with exactly the number of arguments of its definition.

### Eraser

```python
*

eraser = *

*(41 + 1)  # applies 41 + 1 to `*` erasing the number and returns `*`

* = 41 + 1 # erases 41 + 1
```

The effect of an eraser is to free memory. Erasers behave like a `null`.

It's impossible to compare or match eraser values.

It is implicitly inserted for variables that have not been used:

```python
def constant(x):
  return 8345
```

### Tuple

```python
(3, 9)
```

A Tuple is surrounded by `(` `)` and should contain 2 or more elements. Elements are separated by `,`.

### Superposition

```python
{1 2 3}
```

A superposition of values is defined using `{` `}` with at least 2 expressions inside. Elements can be optionally separated by `,`.

Read [sups and dups](./dups-and-sups.md) to know more.

### Numbers and Infix Operations

Currently, bend supports 3 types of numbers: floats, integers and unsigned integers. All of then are 24 bit sized.

```python
f24 = +88.012

i24 = -42

u24 = 42
```

Currently, We can't write operations that mix two types of number but we can explicitly convert between them.

| Operation             | Syntax   | Supported Types  |
| --------------------- | -------- | ---------------- |
| Addition              | x + y    | int, float, uint |
| Subtraction           | x - y    | int, float, uint |
| Multiplication        | x \* y   | int, float, uint |
| Division              | x / y    | int, float, uint |
| Remainder             | x % y    | int, float, uint |
| Exponentiation        | x \*\* y | float            |
| Equal                 | x == y   | int, float, uint |
| Not Equal             | x != y   | int, float, uint |
| Less Than             | x < y    | int, float, uint |
| Greater Than          | x > y    | int, float, uint |
| Less Than or Equal    | x <= y   | int, float, uint |
| Greater Than or Equal | x >= y   | int, float, uint |
| Bitwise And           | x & y    | int, uint        |
| Bitwise Or            | x \| y   | int, uint        |
| Bitwise Xor           | x ^ y    | int, uint        |
| Bitwise Right Shift   | x >> y   | uint             |
| Bitwise Left Shift    | x << y   | uint             |

Hexadecimal and binary floating-point literals are also supported.

In these representations, each digit after the point is divided according to the base’s power of the digit's position.
Specifically, for hexadecimal floating-point numbers, each place after the dot represents a fraction of 16 to the power of the digit's depth.
Similarly, for binary floating-point numbers, each place after the dot represents a fraction of 2 to the power of the digit's depth.

```python
0xA.A == 10.625

0b111.111 == 7.875
```

### Constructor Literals

Constructors are just functions.
A Constructor expression is equivalent to calling a Constructor function, they have 2 syntaxes:

```python
# Constructor syntax, requires all field names
Type/Ctr { field1: 4, field2: 8 }

# Function syntax
Type/Ctr(field1 = 4, field2 = 8)

Type/Ctr(4, field2 = 8)

Type/Ctr(4, 8)

Type/Ctr(4) # Can be partially applied if not using named arguments
```

### Character Literal

```python
'x'
```

A Character is surrounded with `'`. Accepts unicode characters, unicode escapes in the form '\u{hex value}' and is desugared to the unicode codepoint as an `u24`.

Only supports unicode codepoints up to `0xFFFFFF`.

### Symbol Literal

```python
# Becomes 2146 (33 << 6 + 34)
`hi`
```

A Symbol encodes a up to 4 base64 characters as a `u24` number. It is surrounded by `\``.

Empty characters are interpreted as `A` which has value 0, meaning that `B` is the same as `AAAB`.

### String Literal

```python
"Hello, World!"
```

A String literal is surrounded with `"`. Accepts the same values as characters literals.

It is desugared to constructor calls of the built-in type String, `String/cons(head, ~tail)` and `String/nil` .

### List Literal

```python
[1, 2, "three"]
```

A List literal is surrounded by `[` `]`. The elements must be separated by `,`.

It is desugared to constructor calls of the built-in type List, `List/cons(head, ~tail)` and `List/nil` .

### Tree Literals

```python
![![1, 2], ![3, 4]]
```

The Tree literals `![]` and `!` are used to create values of the built-in type `Tree`.

`![a b]` is equivalent to `Tree/Node(a, b)`.

`!x` is equivalent to `Tree/Leaf(x)`.

### Map Literals

```python
{ 0: 4, `hi`: "bye", 'c': 2 + 3 }
x[0] = 5     # Assigns the key 0 to the value 5
return x[0]  # Gets the value of the key 0
```

Bend has a built-in binary tree map data structure where the key is a `u24`, meaning you can use numbers, characters, and symbols as keys.

### List Comprehension

```python
[x + 1 for x in list]

[x + 1 for x in list if x > 2]
```

A List Comprehension generates a new list, it can be extracted in 3 parts.

`[expression . iterator . condition]`

Expression: The expression to be performed in the iterator element.

Iterator: Binds a name to the list elements.

Condition: Optional, is used to filter the list elements.

It is desugared to a fold statement:

```python
fold list:
  List/cons:
    if condition:
      List/cons(list.head, list.tail)
    else:
      list.tail
  List/nil:
    List/nil
```

<div id="fun-syntax"></div>

# Fun Syntax

## Top-level definitions

```rust
type Name
  = (Ctr1 arg1 arg2)
  | Ctr2

Name (Ctr1 sub_arg1 sub_arg2) arg3 = rule0_body
Name Ctr2 arg3 = rule1_body
```

A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names) or start with `//`.

### Function Definitions

A function definition is composed of a sequence of pattern matching equations.
Each rule is the name of the function, a sequence of patterns and then the body.

```rust
identity x = x

(Bool.neg True)  = False
(Bool.neg False) = True

MapMaybe (Some val) f = (Some (f val))
MapMaybe None f = None

Pair.get (fst, snd) f = (f fst snd)
```

A rule pattern can be:

- A variable.
- A number.
- A constructor.
- A tuple.
- A superposition.
- A wildcard `*`.

And the builtin types that desugar to one of the above:

- A list (becomes a constructor).
- A string (becomes a constructor).
- A natural number (becomes a constructor).
- A character (becomes a number).
- A symbol (becomes a number);

Unscoped variables can't be defined in a rule pattern.

The rule body is a term, there are no statements in the Fun variant of Bend.

Read [pattern matching](./pattern-matching.md) to learn about what exactly the rules for pattern matching equations are.

### Type

Defines an Algebraic Data Type, it should have at least one constructor.

```rust
type Tree
  = (Leaf value)
  | (Node ~left ~right)
  | Nil
```

`Tree` is the ADT name and it should be unique, except that it can be used once by a constructor name.

Each constructor is defined by a name followed by its fields. The `~` notation describes a recursive field.

The constructors inherit the name of their types and become functions (`Tree/Node` and `Tree/Leaf` in this case).

## Terms

### Variables

A variable can be anything matching the regex `[A-Za-z0-9_.-/]+` but with some restrictions:

- It can not start with `//`
- It can not contain `__`

A variable is a name for some immutable expression. It is possible to rebind variables with the same name.

```rust
let x = 1
let x = (+ x 1)
```

### Lambda

```rust
@x x

λx x

λ(fst, snd) snd

λ{x y} x
```

Lambdas represents anonymous inline functions, it can be written with `λ` or `@` followed by a pattern and a term.

A tuple or duplication pattern is equivalent to a lambda followed by a `let`.

```rust
λ(fst, snd) snd
λa let (fst, snd) = a; snd

λ{x y} (x y)
λa let {x y} = a; (x y)
```

### Unscoped Variables

```rust
λ$x $x
```

Like a normal scoped variable, but starts with a `$` sign. Every unscoped variable in a function must have a unique name and must be used exactly once.
They can be defined anywhere a scoped variable would be defined in a term, like in a lambda or a `let`.

Unscoped variables are not transformed and linearized like normal scoped variables.

Read [using scopeless lambdas](/docs/using-scopeless-lambdas.md) to know more about.

### Application

```rust
(fun arg_1 arg_2 ... arg_n)
```

An application is surrounded by `(` `)`, written in lisp style.

> Lambdas have a higher precedence, so `(@x x 1)` and `((@x x) 1)` means the same thing.

### Tuples

```rust
(1, 2, 3)
```

A tuple is surrounded by `(` `)`, with the difference that it's elements are separated by `,`.

### Superposition

```rust
{1 2 3}
```

A superposition of values is defined using `{` `}` with at least 2 terms inside.

Read [sups and dups](./dups-and-sups.md) to know more.

### Let-bindings

```rust
let x = (+ 1 2)
x

let (fst, snd, era) = (1, 2, *);
(+ fst snd)

let {f1 f2} = λx x;
(f1 f2)

let $x = (some_fn $x);
*
```

> `*` is an eraser term.

A let term uses a pattern, it can be:

- A variable / unscoped variable.
- A tuple.
- A superposition.

The let term will expects a binding value followed by a `next` term.

Using `;` is optional.

### Use

```rust
use x = (+ 2 3)
(+ x x)
```

Inline copies of the declared bind, it is equivalent to this code:

```rust
(+ (+ 2 3) (+ 2 3))
```

### Switch

```rust
switch n {
  0: "zero"
  1: "one"
  _: "greater than 1"
}

switch x = (+ 1 1) {
  0: 42;
  _: x-1;
}
```

A switch for native numbers, it can hold a name binding if the matching term is not a variable.

The cases need to be typed from `0` to a wildcard `_` in sequence.

In the last case, the predecessor value is available with the name `bound_var-next_num`, where `bound_var` is the variable
set by the condition and `next_num` is the expected value of the next case. For example, the above example code returns
`1`, since `x-1` is bound to `(+ 1 1) - 1` and the value of `x` doesn't match any explicit case.

Using `;` is optional.

### Match

```rust
match opt = (Some "Bend") {
  Some: opt.value;
  None: "No name";
}
```

A pattern match expression, it can hold a name binding if the matching term is not a variable.

It is possible to use a _wildcard_, a named variable or `*` as default cases.

It is desugared according to the chosen encoding. Read [pattern matching](./pattern-matching.md) to know more.

Using `;` is optional.

### If

```rust
if condition {
  ...then
} else {
  ...else
}
```

A branching expression where `else` is mandatory.

The condition must return a `u24` number, where 0 will run the `else` branch and any other value will return the first one.

It is equivalent to this switch:

```rust
switch _ = condition {
  0: else
  _: then
}
```

It is possible to make if-chains using `elif`:

```rust
if condition1 {
  0
} elif condition2 {
  1
} elif condition3 {
  2
} else {
  3
}
```

### Bend

Bend can be used to create recursive data structures:

```rust
main =
  bend x = 0 {
    when (< x 3):
      (Tree/Node (fork (+ x 1)) (fork (+ x 1)))
    else:
      (Tree/Leaf x)
  }
```

Which binds a variable to the return of an inline recursive function.
The function `fork` is available inside the `when` arm of the `bend` and calls it recursively.

It is possible to pass multiple state variables, which can be initialized:

```rust
bend x = 0, y = 1 ... {
  when (condition x y ...):
    ...
}
```

When calling `fork`, the function must receive the same number of arguments as the number of state variables.

It is equivalent to this inline recursive function:

```rust
bend x y ... =
  if (condition x y ...) {
    ...
    ... (bend x y ...) ...
  } else {
    ...
  }
```

### Open

```rust
let x = (Pair 1 2);
open Pair x;
(+ x.fst x.snd)
```

Brings the inner fields of an object into scope. The original variable can still be accessed, but doing so will cause any used fields to be duplicated.

It's equivalent to pattern matching on the value, with the restriction that its type must have only one constructor.

```rust
let x = (Pair 1 2)
match x {
  Pair: (+ x.fst x.snd)
}
```

### With block

```rust
Result/bind (Result/Ok val) nxt = ((undefer nxt) val)
Result/bind err _nxt = err

div a b = switch b {
  0: (Result/Err "Div by 0")
  _: (Result/Ok (/ a b))
}

rem a b = switch b {
  0: (Result/Err "Mod by 0")
  _: (Result/Ok (% a b))
}

Main = with Result {
  ask y = (div 3 2);
  ask x = (rem y 0);
  x
}
```

Receives a type defined with `type` and expects `Result/bind` to be defined as a monadic bind function.
It should be of type `(Result a) -> (a -> Result b) -> Result b`, like in the example above.

However, the second argument, `nxt`, is actually a deferred call to the continuation, passing any free variables as arguments.
Therefore, all `bind` functions must call the builtin function `undefer` before using the value of `nxt`, as in the example above.
This is necessary to ensure that the continuation in recursive monadic functions stays lazy and doesn't expand infinitely.

This is an example of a recursive function that would loop if passing the variable `a` to the recursive call `Result/foo(a, b)` was not deferred:

```python
Result/foo x y = with Result {
  ask a = (Result/Ok 1)
  ask b = if b {
    (Result/Err x)
  } else {
    (Result/Ok y)
  }
  (Result/foo a b)
}
```

Inside a `with` block, you can use `ask`, to access the continuation value of the monadic operation.

```rust
ask y = (div 3 2)
ask x = (rem y 0)
x

# Becomes
(Result/bind (div 3 2) λy (Result/bind (rem y 0) λx x))
```

It can be used to force a sequence of operations. Since the continuation receives the result through a lambda, it is only fully evaluated after something is applied to it.

The name `wrap` is bound inside a `with` block as a shorthand for `Type/wrap`,
the equivalent as a `pure` function in other functional languages:

```rust
Result/wrap x = (Result/Ok x)

with Result {
  ask x = (some_operation ...)
  ask y = (some_operation ...)
  (wrap (* x y))
}
```

### Def

Creates a local function visible in the current block capturing variables:

```rust
main =
  let base = 0
  def aux [] = base
      aux (List/Cons head tail) = (+ head (aux tail))
  (aux [1, 2, 3])
```

### Numbers and operations

Currently, bend supports 3 types of numbers: floats, integers and unsigned integers. All of then are 24 bit sized.

```rust
f24 = +88.012

i24 = -42

u24 = 42
```

Currently, the 3 number types cannot be mixed.

| Operation             | Syntax     | Supported Types  |
| --------------------- | ---------- | ---------------- |
| Addition              | (+ x y)    | int, float, uint |
| Subtraction           | (- x y)    | int, float, uint |
| Multiplication        | (\* x y)   | int, float, uint |
| Division              | (/ x y)    | int, float, uint |
| Remainder             | (% x y)    | int, float, uint |
| Exponentiation        | (\*\* x y) | float            |
| Equal                 | (== x y)   | int, float, uint |
| Not Equal             | (!= x y)   | int, float, uint |
| Less Than             | (< x y)    | int, float, uint |
| Greater Than          | (> x y)    | int, float, uint |
| Less Than or Equal    | (<= x y)   | int, float, uint |
| Greater Than or Equal | (>= x y)   | int, float, uint |
| Bitwise And           | (& x y)    | int, uint        |
| Bitwise Or            | (\| x y)   | int, uint        |
| Bitwise Xor           | (^ x y)    | int, uint        |
| Bitwise Right Shift   | (>> x y)   | uint             |
| Bitwise Left Shift    | (<< x y)   | uint             |

Hexadecimal and binary floating-point literals are also supported.

In these representations, each digit after the point is divided according to the base’s power of the digit's position.
Specifically, for hexadecimal floating-point numbers, each place after the dot represents a fraction of 16 to the negative power of the digit's depth.
Similarly, for binary floating-point numbers, each place after the dot represents a fraction of 2 to the negative power of the digit's depth.

```python
(== 0xA.A 10.625)

(== 0b111.111 7.875)
```

### Character Literal

```rust
'a'
```

A Character is surrounded with `'`. Accepts unicode characters, unicode escapes in the form '\u{hex value}' and is desugared to the unicode codepoint as an `u24`.

Only supports unicode codepoints up to `0xFFFFFF`.

### Symbol Literal

```python
# Becomes 2146 (33 << 6 + 34)
`hi`
```

A Symbol encodes a up to 4 base64 characters as a `u24` number. It is surrounded by `\``.

Empty characters are interpreted as `A` which has value 0, meaning that `B` is the same as `AAAB`.

### String Literal

```rust
"Hello"
```

A String literal is surrounded with `"`. Accepts the same values as characters literals.

The syntax above is desugared to:

```
(String.cons 'H' (String.cons 'e' (String.cons 'l' (String.cons 'l' (String.cons 'o' String.nil)))))
```

### List Literal

```rust
[1, 2, 3 4]
```

The syntax above is desugared to:

```
(List.cons 1 (List.cons 2 (List.cons 3 (List.cons 4 List.nil))))
```

Using `,` is optional.

### Tree Literals

```python
![![1, 2], ![3, 4]]
```

The Tree literals `![]` and `!` are used to create values of the built-in type `Tree`.

`![a b]` is equivalent to `Tree/Node(a, b)`.

`!x` is equivalent to `Tree/Leaf(x)`.

### Nat Literal

```rust
#3
```

The syntax above is desugared to:

```
(Nat/succ (Nat/succ (Nat/succ Nat/zero)))
```

# Native HVM definitions

```py
# This function causes two ports to be linked and returns *.
# This can be used to interpret a lambda as an application and apply something to it for example.
# It can be used like this: `let * = (link_ports @x x y)`
hvm link_ports:
  (a (b *))
  & (c a) ~ (d e)
  & (e b) ~ (d c)

# Casts a `u24` to itself.
# We can give type annotations to HVM definitions.
hvm u24_to_u24 -> (u24 -> u24):
  ($([u24] ret) ret)
```

It's also possible to define functions using HVM syntax. This can be
thought of as a way to write "HVM assembly" directly in a Bend program.
You can find the reference of this syntax in the [HVM paper](https://github.com/HigherOrderCO/HVM/blob/main/paper/PAPER.pdf).

This is meant for writing things that would otherwise be hard or
impossible to write in normal Bend syntax.

It will also ignore all term-level compiler passes and so can be
useful for writing programs with exact behaviour that won't ever be
changed or optimized by the compiler.

<div id="import-syntax"></div>

# Import Syntax

### Import Relative to the File

Paths starting with `./` or `../` are imported relative to the file.

### Import Relative to the Main Folder

Paths that do not start with `./` or `../` are relative to the folder of the main file.

## Syntax

### Import Specific Names from a File, or Files from a Folder

```py
from path import name
from path import (name1, name2)
import (path/name1, path/name2)
```

### Import All Names from a File, or All Files from a Folder

```py
from path import *
```

### Aliasing Imports

```py
from path import name as alias
from path import (name1 as Alias1, name2 as Alias2)
import path as alias
import (path/name1 as Alias1, path/name2 as Alias2)
```

<div id="comments"></div>

# Comments

## Syntax

### Single Line Comment

Use `#` to indicate a single line comment.

```py
# Single line comment

def main():
  # return 0
```

### Multi Line Comment

Use `#{ ... #}` to indicate a multi-line comment.

Multi-line commenting should also be used to document code.
Documentation for functions is meant to be written as a multiline comment right above the function.
```py
#{
  Expects two arguments to be passed.

  This function always returns the second value that was used as argument.
#}
def second(x: A, y: B) -> B:
  return y
```

<div id="imp-type-syntax"></div>

# Imp Type Syntax

## Variable

Any name represents a type variable.

Used in generic or polymorphic type definitions.

```python
# T is a type variable
type Option(T):
  Some { value: T }
  None

# A is a type variable
def id(x: A) -> A:
  return x
```

## Constructor

`Ctr(...)` represents a constructor type.

Used for defining custom data types or algebraic data types.
Can contain other types as parameters.

```python
def head(list: List(T)) -> Option(T)
  match list:
    case List/Nil:
      return Option/None
    case List/Cons:
      return Option/Some(list.head)
```

## Any

`Any` represents the untyped type.

It accepts values of alls type and will forcefully cast any type to `Any`.

Can be used for values that can't be statically typed, either because
they are unknown (like in raw IO calls), because they contain untypable
expressions (like unscoped variables), or because the expression cannot
be typed with the current type system (like the self application `lambda x: x(x)`).

```python
def main -> Any:
  return 24
```

## None

`None` represents the eraser `*` or absence of a value.

Often used to indicate that a function doesn't return anything.

```python
def none -> None:
  return *
```

## Hole

`_` represents a hole type.

This will let the type checker infer the most general type for an argument or return value.

```python
def increment(x: _) -> _:
  return x + 1
```

## u24

`u24` represents an unsigned 24-bit integer.

```python
def zero -> u24:
  return 0
```

## i24

`i24` represents a signed 24-bit integer.

```python
def random_integer -> i24:
  return -42
```

## f24

`f24` represents a 24-bit floating-point number.

```python
def PI -> f24:
  return 3.14
```

## Tuple

`(_, _, ...)` represents a tuple type.

Can contain two or more types separated by commas.

```python
def make_tuple(fst: A, snd: B) -> (A, B):
  return (fst, snd)
```

## Function

`a -> b` represents a function type.

`a` is the input type, and `b` is the output type.

```python
def apply(f: A -> B, arg: A) -> B:
  return f(arg)
```

<div id="fun-type-syntax"></div>

# Fun Type Syntax

## Variable

Any name represents a type variable.

Used in generic or polymorphic type definitions.

```python
# T is a type variable
type (Option T)
  = (Some T)
  | None

# A is a type variable
id : A -> A
id x = x
```

## Constructor

`(Ctr ...)` represents a constructor type.

Used for defining custom data types or algebraic data types.
Can contain other types as parameters.

```python
head : (List T) -> (Option T)
head [] = Option/None
head (List/Cons head _) = (Option/Some head)
```

## Any

`Any` represents the untyped type.

It accepts values of alls type and will forcefully cast any type to `Any`.

Can be used for values that can't be statically typed, either because
they are unknown (like in raw IO calls), because they contain untypable
expressions (like unscoped variables), or because the expression cannot
be typed with the current type system (like the self application `λx (x x)`).

```python
main : Any
main = @x x
```

## None

`None` represents the eraser `*` or absence of a value.

Often used to indicate that a function doesn't return anything.

```python
none : None
none = *
```

## Hole

`_` represents a hole type.

This will let the type checker infer the most general type for an argument or return value.

```python
increment : _ -> _
increment x = (+ x 1)
```

## u24

`u24` represents an unsigned 24-bit integer.

```python
zero : u24
zero = 0
```

## i24

`i24` represents a signed 24-bit integer.

```python
random_integer : i24
random_integer = -24
```

## f24

`f24` represents a 24-bit floating-point number.

```python
PI : f24
PI = 3.14
```

## Tuple

`(_, _, ...)` represents a tuple type.

Can contain two or more types separated by commas.

```python
make_tuple : A -> B -> (A, B)
make_tuple fst snd = (fst, snd)
```

## Function

`a -> b` represents a function type.

`a` is the input type, and `b` is the output type.

```python
apply : (A -> B) -> A -> B
apply f arg = (f arg)
```


================================================
FILE: docs/type-checking.md
================================================
# Type Checking

Bend has a type checker with optional typing support based on a Hindley Milner type system.

Programs can be optionally typed using the respective imp or fun type syntax. Type checking is
enabled by default, but can be toggled with the `-Otype-check` and `-Ono-type-check` options.

Every function can be annotated with a type for its arguments and return value.
The type checker will infer the type of the function and then compare if it's compatible with the annotated type.

```python
def add(x: u24, y: u24) -> u24:
  return x + y

# Arguments or return value without annotation are considered `Any`.
# They will be accepted by any function, regardless of being correct or not.
def push(list: List(T), value) -> List(T):
  match list:
    case List/Nil:
      return List/Cons(value, List/Nil)
    case List/Cons:
      return List/Cons(list.head, push(list.tail, value))

# Error, List(T) must only receive values of type `T`.
def append_num(list: List(T), num: u24) -> List(T):
  return List/Cons(num, list)

# Error, Tree(T) can only store one type of value.
def my_tree() -> _:
  return ![!1, !"a"]

# Error, can't add a `u24` and a `f24`.
# Bend doesn't have implicit type conversions.
def add_float(x: u24, y: f24) -> f24:
  return x + y
```

Bend comes with the following builtin types:

* `u24`: Unsigned 24-bit integer.
* `i24`: Signed 24-bit integer.
* `f24`: Floating point number.
* `(T1, ..., Tn)`: Tuple with `n` elements of types `T1` to `Tn`.
* `Any`: Untyped value.
* `None`: Eraser `*`.
* `_`: A type that will be inferred by the type checker.

The prelude library also defines some basic types that are used in Bend programs:

* `String`: Text represented as a sequence of Unicode characters.
* `List(T)`: A list of values of type `T`.
* `Tree(T)`: A binary tree with values of type `T` at the leaves.
* `Map(T)`: A map from keys of type `u24` to values of type `T`.
* `IO(T)`: A monadic IO type that can be used to perform IO operations.
* `Result(O, E)`: Represents the result of an operation that can either succeed with an `O` or fail with an `E`.


Additionally, you can define your own algebraic data types.
In this case, all the type variables that occur in the constructors must be previously defined.

```python
type Option(T):
  Some { value: T }
  None
```

All the constructors will be declared with the same type `TypeName(var2, var2, ...)`.

### Enabling and disabling type checking

In some cases we know that dynamically our program will not do something wrong despite not being able to give it the proper type.

We can disable type checking for a specific function by either removing the type annotations or by giving it the `unchecked` keyword:

```python
# Error, type-checked functions can't contain an unscoped variable.
def channel(x: u24) -> (u24 -> u24, u24):
  return (lambda $a: x, $a)

# We can remove the annotations. It won't be type-checked,
# but its type will be `Any -> Any`.
def channel(x):
  return (lambda $a: x, $a)

# Instead, we can use the `unchecked` keyword.
# The annotated type will be considered the truth, regardless of being correct or not.
def unchecked channel(x: u24) -> (u24 -> u24, u24):
  return (lambda $a: x, $a)
```

The opposite is also possible, we can enable type checking for an unannotated function by using the `checked` keyword before the name of the function in its declaration:

```python
# Despite the inferred type being `List(T) -> List(T)`, the type checker will consider it as `Any -> Any` because it's not annotated.
def checked tail(list):
  match list:
    case List/Nil:
      return List/Nil
    case List/Cons:
      return list.tail

# Error, can't infer the type of this function, despite having type `Any`.
# Not typeable by a Hindley-Milner type system.
checked (scott_concat a b) = (a
  λh λt λcons λnil (cons h (scott_concat t b))
  b
)
```

We can also disable type checking for the entire program by using the `-Ono-type-check` option.

Native HVM definitions are always unchecked.

```python
# This function will be given the type `a -> a`.
hvm native_id -> (a -> a):
  (x x)
```

### Limitations

Currently, the following are not supported by the type checker:

- Superpositions (`{a, b}`, the tuple type with duplication semantics, see [Dups and sups](https://github.com/HigherOrderCO/Bend/blob/main/docs/dups-and-sups.md)).
- Unscoped variables and variable binds (`$a`, `let $a = ...`, see [Scopeless lambdas](https://github.com/HigherOrderCO/Bend/blob/main/docs/using-scopeless-lambdas.md)).
- Expressions not typeable by a Hindley-Milner type system (e.g. self application `λx: x(x)`).

Additionally, the builtin types `Number` and `Integer` can't be used directly in type annotations. They are used internally by the type checker to handle numeric expressions.

```python
# The inferred type will be `Number(a) -> Number(a) -> Number(a)`.
def add(x: _, y: _) -> _:
  return x + y

# The inferred type will be `Integer(a) -> Integer(a) -> Integer(a)`.
def shift(x: _, n: _) -> _:
  return x << n
```


================================================
FILE: docs/using-scopeless-lambdas.md
================================================
# Using scopeless lambdas

Scopeless lambdas are very powerful lambdas that are a side-effect of HVM's internal representation for lambda terms.

Scopeless lambdas are lambdas that have no scope. The variables bound by them can be used outside the lambda's body. They can be created by prefixing a dollar symbol (`$`) to a lambda's variable name.

```py
λ$x $x # The identity function as a scopeless lambda
```

Of course, using scopeless lambdas as a replacement for regular lambdas is kind of pointless. Their real power comes from being able to use the bound variable outside the body:

```py
main = (((λ$x 1) 2), $x)
# $x gets replaced by 2 and the application ((λ$x 1) 2) gets replaced by 1
# Outputs (1, 2)
```
In the imp syntax, scopeless lambdas can be written in the following way:
```py
def main() -> _:
  # This is the equivalent code to the above example
  # Notice that in the imp syntax, you scopeless lambdas are written as `lambda $x: 1` instead of `λ$x 1`.
  f = lambda $x: 1
  return (f(2), $x)
```

Take some time to think about the program above. It is valid, despite `$x` being used outside the lambda's body.

However, scopeless lambdas don't bind across definitions.
```py
def = $x

main = (((λ$x 1) 2), def)
```

The bound variables are local to each term.

## Duplicating scopeless lambdas

We have seen that the variable bound to a scopeless lambda gets set when the lambda is called. But, what happens if we never call `λ$x 1`? What will `$x` get set to then? Here is a program that does that:

```py
main =
	let _ = λ$x 1 # Discard and erase the scopeless lambda
	(2, $x)

# Outputs (2, *)
```

The program outputs `2` as the first item of the tuple, as expected. But the second item is `*`! What is `*`?

`*` (called ERA or eraser) is a special term HVM uses when a value was erased. This is what happened to `$x`. We erased `λ$x 1` when we discarded it, which led to `$x` being erased.

What happens if we call `λ$x 1` with two different values instead? 

Try to answer this with your knowledge of HVM. Will it throw a runtime error? Will it return something unexpected?

```py
main =
	let f = λ$x 1 # Assign the lambda to a variable
	((f 2), ((f 3), $x)) # Return 
Download .txt
gitextract_5jgx8w8i/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       └── checks.yml
├── .gitignore
├── .rustfmt.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── FAQ.md
├── FEATURES.md
├── GUIDE.md
├── LICENSE-APACHE
├── README.md
├── cspell.json
├── docs/
│   ├── builtins.md
│   ├── cli-arguments.md
│   ├── compilation-and-readback.md
│   ├── compiler-options.md
│   ├── defining-data-types.md
│   ├── dups-and-sups.md
│   ├── ffi.md
│   ├── imports.md
│   ├── lazy-definitions.md
│   ├── native-numbers.md
│   ├── pattern-matching.md
│   ├── syntax.md
│   ├── type-checking.md
│   ├── using-scopeless-lambdas.md
│   └── writing-fusing-functions.md
├── examples/
│   ├── bitonic_sort.bend
│   ├── bubble_sort.bend
│   ├── callcc.bend
│   ├── example_fun.bend
│   ├── fib.bend
│   ├── fusing_add.bend
│   ├── fusing_not.bend
│   ├── gen_tree.bend
│   ├── hello_world.bend
│   ├── insertion_sort.bend
│   ├── list.bend
│   ├── parallel_and.bend
│   ├── parallel_sum.bend
│   ├── queue.bend
│   ├── quick_sort.bend
│   └── radix_sort.bend
├── justfile
├── src/
│   ├── diagnostics.rs
│   ├── fun/
│   │   ├── builtins.bend
│   │   ├── builtins.rs
│   │   ├── check/
│   │   │   ├── check_untyped.rs
│   │   │   ├── mod.rs
│   │   │   ├── set_entrypoint.rs
│   │   │   ├── shared_names.rs
│   │   │   ├── type_check.rs
│   │   │   ├── unbound_refs.rs
│   │   │   └── unbound_vars.rs
│   │   ├── display.rs
│   │   ├── load_book.rs
│   │   ├── mod.rs
│   │   ├── net_to_term.rs
│   │   ├── parser.rs
│   │   ├── term_to_net.rs
│   │   └── transform/
│   │       ├── apply_args.rs
│   │       ├── definition_merge.rs
│   │       ├── definition_pruning.rs
│   │       ├── desugar_bend.rs
│   │       ├── desugar_fold.rs
│   │       ├── desugar_match_defs.rs
│   │       ├── desugar_open.rs
│   │       ├── desugar_use.rs
│   │       ├── desugar_with_blocks.rs
│   │       ├── encode_adts.rs
│   │       ├── encode_match_terms.rs
│   │       ├── expand_generated.rs
│   │       ├── expand_main.rs
│   │       ├── fix_match_defs.rs
│   │       ├── fix_match_terms.rs
│   │       ├── float_combinators.rs
│   │       ├── lift_local_defs.rs
│   │       ├── linearize_matches.rs
│   │       ├── linearize_vars.rs
│   │       ├── mod.rs
│   │       ├── resolve_refs.rs
│   │       ├── resolve_type_ctrs.rs
│   │       ├── resugar_list.rs
│   │       ├── resugar_string.rs
│   │       └── unique_names.rs
│   ├── hvm/
│   │   ├── add_recursive_priority.rs
│   │   ├── check_net_size.rs
│   │   ├── eta_reduce.rs
│   │   ├── inline.rs
│   │   ├── mod.rs
│   │   ├── mutual_recursion.message
│   │   ├── mutual_recursion.rs
│   │   └── prune.rs
│   ├── imp/
│   │   ├── gen_map_get.rs
│   │   ├── mod.rs
│   │   ├── order_kwargs.rs
│   │   ├── parser.rs
│   │   └── to_fun.rs
│   ├── imports/
│   │   ├── book.rs
│   │   ├── loader.rs
│   │   ├── mod.rs
│   │   └── packages.rs
│   ├── lib.rs
│   ├── main.rs
│   ├── net/
│   │   ├── hvm_to_net.rs
│   │   └── mod.rs
│   └── utils.rs
└── tests/
    ├── golden_tests/
    │   ├── check_file/
    │   │   ├── fail_type_bad_rec_fn_adt.bend
    │   │   ├── non_exaustive_limit.bend
    │   │   └── type_err_match_arm.bend
    │   ├── cli/
    │   │   ├── compile_all.args
    │   │   ├── compile_all.bend
    │   │   ├── compile_inline.args
    │   │   ├── compile_inline.bend
    │   │   ├── compile_no_opts.args
    │   │   ├── compile_no_opts.bend
    │   │   ├── compile_pre_reduce.args
    │   │   ├── compile_pre_reduce.bend
    │   │   ├── compile_strict_loop.args
    │   │   ├── compile_strict_loop.bend
    │   │   ├── compile_wrong_opt.args
    │   │   ├── compile_wrong_opt.bend
    │   │   ├── custom_hvm_bin.args
    │   │   ├── custom_hvm_bin.bend
    │   │   ├── debug_list_map.args
    │   │   ├── debug_list_map.bend
    │   │   ├── debug_u60_to_nat.args
    │   │   ├── debug_u60_to_nat.bend
    │   │   ├── desugar_bool_scott.args
    │   │   ├── desugar_bool_scott.bend
    │   │   ├── desugar_float_combinators.args
    │   │   ├── desugar_float_combinators.bend
    │   │   ├── desugar_linearize_matches.args
    │   │   ├── desugar_linearize_matches.bend
    │   │   ├── desugar_linearize_matches_alt.args
    │   │   ├── desugar_linearize_matches_alt.bend
    │   │   ├── desugar_merge.args
    │   │   ├── desugar_merge.bend
    │   │   ├── desugar_pretty.args
    │   │   ├── desugar_pretty.bend
    │   │   ├── desugar_prune.args
    │   │   ├── desugar_prune.bend
    │   │   ├── gen_hvm_no_eta_by_default.args
    │   │   ├── gen_hvm_no_eta_by_default.bend
    │   │   ├── input_file_not_found.args
    │   │   ├── input_file_not_found.bend
    │   │   ├── net_size_too_large.args
    │   │   ├── net_size_too_large.bend
    │   │   ├── no_check_net_size.args
    │   │   ├── no_check_net_size.bend
    │   │   ├── run_add.args
    │   │   ├── run_add.bend
    │   │   ├── run_pretty.args
    │   │   ├── run_pretty.bend
    │   │   ├── tuple_readback.args
    │   │   ├── tuple_readback.bend
    │   │   ├── warn_and_err.args
    │   │   └── warn_and_err.bend
    │   ├── compile_entrypoint/
    │   │   └── foo.bend
    │   ├── compile_file/
    │   │   ├── 360_no_scope.bend
    │   │   ├── add_args.bend
    │   │   ├── addition.bend
    │   │   ├── addition_const.bend
    │   │   ├── ask_outside_do.bend
    │   │   ├── church_one.bend
    │   │   ├── church_zero.bend
    │   │   ├── complicated_dup.bend
    │   │   ├── crlf.bend
    │   │   ├── cyclic_global_lam.bend
    │   │   ├── def_pat_unscoped.bend
    │   │   ├── dup_apply.bend
    │   │   ├── dup_global_lam.bend
    │   │   ├── elif.bend
    │   │   ├── elif_fun.bend
    │   │   ├── elif_no_else.bend
    │   │   ├── erased_dup.bend
    │   │   ├── error_data_def_name.bend
    │   │   ├── error_messages.bend
    │   │   ├── f24_oper.bend
    │   │   ├── fst_snd.bend
    │   │   ├── global_lam.bend
    │   │   ├── i24_oper.bend
    │   │   ├── id.bend
    │   │   ├── infer_dup.bend
    │   │   ├── inlining.bend
    │   │   ├── just_a_name.bend
    │   │   ├── just_data.bend
    │   │   ├── just_paren.bend
    │   │   ├── just_rule_paren.bend
    │   │   ├── let_substitution.bend
    │   │   ├── let_tup.bend
    │   │   ├── lets.bend
    │   │   ├── long_name.bend
    │   │   ├── match.bend
    │   │   ├── mismatched_ask_statements.bend
    │   │   ├── missing_adt_eq.bend
    │   │   ├── missing_ctrs.bend
    │   │   ├── missing_pat.bend
    │   │   ├── names_starting_with_keywords.bend
    │   │   ├── nested_ctr_wrong_arity.bend
    │   │   ├── nested_let.bend
    │   │   ├── number_too_large.bend
    │   │   ├── nums.bend
    │   │   ├── op2.bend
    │   │   ├── redex_order.bend
    │   │   ├── redex_order_recursive.bend
    │   │   ├── ref_to_main.bend
    │   │   ├── ref_to_ref.bend
    │   │   ├── repeated_bind_rule.bend
    │   │   ├── simple_tup.bend
    │   │   ├── switch_all_patterns.bend
    │   │   ├── switch_in_switch_arg.bend
    │   │   ├── switch_incomplete.bend
    │   │   ├── switch_unscoped_lambda.bend
    │   │   ├── top_level_name_slashslash.bend
    │   │   ├── tup.bend
    │   │   ├── tup_add.bend
    │   │   ├── unbound_unscoped_var.bend
    │   │   ├── unbound_var.bend
    │   │   ├── unbound_var_scope.bend
    │   │   ├── unbound_with_tup_pattern.bend
    │   │   ├── underscore.bend
    │   │   ├── unexpected_top_char.bend
    │   │   ├── unscoped_dup_use.bend
    │   │   ├── unscoped_supercombinator.bend
    │   │   ├── unused_let.bend
    │   │   ├── unused_unscoped_bind.bend
    │   │   ├── variable_name_double_underscore.bend
    │   │   ├── vicious_circles.bend
    │   │   ├── warn_and_err.bend
    │   │   ├── with_clause_parse_err.bend
    │   │   ├── wrong_ctr_arity.bend
    │   │   ├── wrong_ctr_var_arity.bend
    │   │   ├── wrong_nums.bend
    │   │   └── wrong_unicode_escape.bend
    │   ├── compile_file_o_all/
    │   │   ├── addition.bend
    │   │   ├── addition_var_fst.bend
    │   │   ├── adt_option_and.bend
    │   │   ├── adt_string.bend
    │   │   ├── and.bend
    │   │   ├── bad_parens_making_erased_let.bend
    │   │   ├── bool.bend
    │   │   ├── cyclic_dup.bend
    │   │   ├── double_main.bend
    │   │   ├── eta_chain.bend
    │   │   ├── ex0.bend
    │   │   ├── ex2.bend
    │   │   ├── example.bend
    │   │   ├── exp.bend
    │   │   ├── expr.bend
    │   │   ├── extracted_match_pred.bend
    │   │   ├── fst.bend
    │   │   ├── fst_fst.bend
    │   │   ├── hvm1_main.bend
    │   │   ├── inline_app.bend
    │   │   ├── inlining.bend
    │   │   ├── linearize_match.bend
    │   │   ├── list_merge_sort.bend
    │   │   ├── list_reverse.bend
    │   │   ├── match_adt_non_exhaustive.bend
    │   │   ├── match_dup_and_reconstruction.bend
    │   │   ├── match_mult_linearization.bend
    │   │   ├── match_num_explicit_bind.bend
    │   │   ├── match_tup.bend
    │   │   ├── merge_definitions.bend
    │   │   ├── non_exhaustive_and.bend
    │   │   ├── non_exhaustive_different_types.bend
    │   │   ├── non_exhaustive_pattern.bend
    │   │   ├── non_exhaustive_tree.bend
    │   │   ├── num_pattern_with_var.bend
    │   │   ├── recursive_combinator_inactive.bend
    │   │   ├── repeated_name_trucation.bend
    │   │   ├── scrutinee_reconstruction.bend
    │   │   ├── self_ref.bend
    │   │   ├── snd.bend
    │   │   ├── spacing.bend
    │   │   ├── spacing2.bend
    │   │   ├── str.bend
    │   │   ├── sum_predicates.bend
    │   │   ├── tagged_dup.bend
    │   │   ├── tagged_lam.bend
    │   │   ├── tagged_sup.bend
    │   │   ├── unapplied_eta.bend
    │   │   ├── unscoped_eta.bend
    │   │   ├── var_shadows_ref.bend
    │   │   └── weekday.bend
    │   ├── compile_file_o_no_all/
    │   │   ├── bitonic_sort.bend
    │   │   ├── list_reverse.bend
    │   │   ├── redex_order.bend
    │   │   └── sum_tree.bend
    │   ├── compile_long/
    │   │   ├── huge_tree.bend
    │   │   └── long_str_file.bend
    │   ├── desugar_file/
    │   │   ├── ask_branch.bend
    │   │   ├── bind_syntax.bend
    │   │   ├── combinators.bend
    │   │   ├── deref_loop.bend
    │   │   ├── dup_linearization.bend
    │   │   ├── local_def_shadow.bend
    │   │   ├── main_aux.bend
    │   │   ├── mapper_syntax.bend
    │   │   ├── switch_with_use.bend
    │   │   ├── tree_syntax.bend
    │   │   ├── use_id.bend
    │   │   ├── use_shadow.bend
    │   │   └── used_once_names.bend
    │   ├── encode_pattern_match/
    │   │   ├── adt_tup_era.bend
    │   │   ├── and3.bend
    │   │   ├── bool.bend
    │   │   ├── bool_tup.bend
    │   │   ├── box.bend
    │   │   ├── common.bend
    │   │   ├── concat.bend
    │   │   ├── concat_def.bend
    │   │   ├── def_tups.bend
    │   │   ├── definition_merge.bend
    │   │   ├── expr.bend
    │   │   ├── flatten_era_pat.bend
    │   │   ├── full_map.bend
    │   │   ├── is_some_some.bend
    │   │   ├── list_merge_sort.bend
    │   │   ├── list_str_encoding_undeclared_fn.bend
    │   │   ├── list_str_encoding_undeclared_map.bend
    │   │   ├── match_adt_unscoped_in_arm.bend
    │   │   ├── match_adt_unscoped_lambda.bend
    │   │   ├── match_adt_unscoped_var.bend
    │   │   ├── match_auto_linearization.bend
    │   │   ├── match_bind.bend
    │   │   ├── match_num_adt_tup_parser.bend
    │   │   ├── match_num_pred.bend
    │   │   ├── match_syntax.bend
    │   │   ├── merge_recursive.bend
    │   │   ├── no_patterns.bend
    │   │   ├── non_matching_fst_arg.bend
    │   │   ├── ntup_sum.bend
    │   │   ├── pattern_match_encoding.bend
    │   │   ├── switch_in_switch_arg.bend
    │   │   ├── var_only.bend
    │   │   └── weekday.bend
    │   ├── hangs/
    │   │   ├── bad_dup_interaction.bend
    │   │   └── recursive_with_unscoped.bend
    │   ├── import_system/
    │   │   ├── import_ctr_syntax.bend
    │   │   ├── import_main.bend
    │   │   ├── import_main2.bend
    │   │   ├── import_main3.bend
    │   │   ├── import_type.bend
    │   │   ├── import_types.bend
    │   │   ├── imports.bend
    │   │   ├── imports_alias.bend
    │   │   ├── imports_alias_shadow.bend
    │   │   ├── imports_conflict.bend
    │   │   ├── imports_file_and_dir.bend
    │   │   ├── imports_file_and_dir_conflict.bend
    │   │   ├── imports_shadow.bend
    │   │   ├── imports_shadow2.bend
    │   │   └── lib/
    │   │       ├── MyOption.bend
    │   │       ├── a/
    │   │       │   └── b.bend
    │   │       ├── a.bend
    │   │       ├── bool_xor.bend
    │   │       ├── ctr_type.bend
    │   │       ├── defs.bend
    │   │       ├── file_and_dir/
    │   │       │   ├── w.bend
    │   │       │   └── y.bend
    │   │       ├── file_and_dir.bend
    │   │       ├── folder/
    │   │       │   ├── import_entry3.bend
    │   │       │   └── myFun.bend
    │   │       ├── import_entry.bend
    │   │       ├── import_entry2.bend
    │   │       ├── myFun.bend
    │   │       ├── nums.bend
    │   │       └── types.bend
    │   ├── io/
    │   │   ├── eof.txt
    │   │   ├── load.bend
    │   │   ├── load.txt
    │   │   ├── load_fail.bend
    │   │   ├── read_line_eof.bend
    │   │   ├── store.bend
    │   │   ├── store.txt
    │   │   ├── store_fail.bend
    │   │   └── utf8.bend
    │   ├── linear_readback/
    │   │   └── church_mul.bend
    │   ├── mutual_recursion/
    │   │   ├── a_b_c.bend
    │   │   ├── len.bend
    │   │   ├── merged.bend
    │   │   ├── multiple.bend
    │   │   └── odd_even.bend
    │   ├── parse_file/
    │   │   ├── bad_floating.bend
    │   │   ├── bend_missing_else.bend
    │   │   ├── era.bend
    │   │   ├── fold_missing_case.bend
    │   │   ├── fun_def.bend
    │   │   ├── fun_def_name.bend
    │   │   ├── if_missing_else.bend
    │   │   ├── imp_map.bend
    │   │   ├── imp_program.bend
    │   │   ├── match_missing_case.bend
    │   │   ├── multi_line_comment.bend
    │   │   ├── redefinition_builtin.bend
    │   │   ├── redefinition_ctr_with_fun.bend
    │   │   ├── redefinition_fun_imp.bend
    │   │   ├── redefinition_imp_fun.bend
    │   │   ├── redefinition_type_with_object.bend
    │   │   ├── redefinition_with_def_between.bend
    │   │   ├── redefinition_with_object_between.bend
    │   │   ├── redefinition_with_type_between.bend
    │   │   ├── repeated_adt_name.bend
    │   │   ├── repeated_datatype_name.bend
    │   │   ├── scape_chars.bend
    │   │   ├── strange_pattern.bend
    │   │   ├── tab.bend
    │   │   ├── tup_with_signed.bend
    │   │   ├── tuple_assign.bend
    │   │   ├── tuple_commas.bend
    │   │   └── tuple_need_parens.bend
    │   ├── prelude/
    │   │   ├── applies_function_to_map.bend
    │   │   ├── get_values_from_map.bend
    │   │   ├── lists_to_map.bend
    │   │   ├── map_checked_test.bend
    │   │   ├── map_contains_test.bend
    │   │   └── set_node_when_empty.bend
    │   ├── readback_hvm/
    │   │   ├── addition.bend
    │   │   ├── bad_net.bend
    │   │   ├── bad_net1.bend
    │   │   ├── bad_net3.bend
    │   │   ├── complicated_dup.bend
    │   │   ├── fst_snd.bend
    │   │   ├── id.bend
    │   │   ├── invalid_op2_op2.bend
    │   │   ├── match.bend
    │   │   ├── nested_let.bend
    │   │   ├── nested_tup.bend
    │   │   ├── number.bend
    │   │   ├── simple_tup.bend
    │   │   └── tup_add.bend
    │   ├── run_entrypoint/
    │   │   └── foo.bend
    │   ├── run_file/
    │   │   ├── 360_no_scope.bend
    │   │   ├── addition.bend
    │   │   ├── adt_match.bend
    │   │   ├── adt_match_wrong_tag.bend
    │   │   ├── adt_option_and.bend
    │   │   ├── adt_wrong_tag.bend
    │   │   ├── and.bend
    │   │   ├── basic_num_ops.bend
    │   │   ├── bend_fold.bend
    │   │   ├── bitonic_sort.bend
    │   │   ├── bitonic_sort_lam.bend
    │   │   ├── box.bend
    │   │   ├── branch_statements_assignment.bend
    │   │   ├── callcc.bend
    │   │   ├── chars.bend
    │   │   ├── chars_forall.bend
    │   │   ├── chars_lambda.bend
    │   │   ├── checked_scott_encoding.bend
    │   │   ├── comprehension.bend
    │   │   ├── def_bool_num.bend
    │   │   ├── def_num_bool.bend
    │   │   ├── def_tups.bend
    │   │   ├── do_block_mixed.bend
    │   │   ├── dup_global_lam.bend
    │   │   ├── empty.bend
    │   │   ├── encode_decode_utf8.bend
    │   │   ├── erased_side_effect.bend
    │   │   ├── escape_sequences.bend
    │   │   ├── eta.bend
    │   │   ├── example.bend
    │   │   ├── exp.bend
    │   │   ├── expand_main_combinator.bend
    │   │   ├── expand_main_list.bend
    │   │   ├── extracted_match_pred.bend
    │   │   ├── filter_bool_id.bend
    │   │   ├── floating_numbers.bend
    │   │   ├── fold_with_state.bend
    │   │   ├── guide_bend_7tree.bend
    │   │   ├── guide_bend_sequential.bend
    │   │   ├── guide_bend_sum_tree.bend
    │   │   ├── guide_bitonic_sort.bend
    │   │   ├── guide_circle_area.bend
    │   │   ├── guide_distance_4args.bend
    │   │   ├── guide_distance_obj.bend
    │   │   ├── guide_distance_tup.bend
    │   │   ├── guide_enumerate.bend
    │   │   ├── guide_if_age.bend
    │   │   ├── guide_is_even_num.bend
    │   │   ├── guide_is_even_str.bend
    │   │   ├── guide_list_ctrs.bend
    │   │   ├── guide_list_match.bend
    │   │   ├── guide_list_sugar.bend
    │   │   ├── guide_mul2_inline.bend
    │   │   ├── guide_mul2_rec.bend
    │   │   ├── guide_shader_dummy.bend
    │   │   ├── guide_sum.bend
    │   │   ├── hvm_def_cast.bend
    │   │   ├── hvm_def_two_defs.bend
    │   │   ├── id_underscore.bend
    │   │   ├── imp_empty_literals.bend
    │   │   ├── imp_use_statement.bend
    │   │   ├── kind_compiled_tree_sum.bend
    │   │   ├── lam_op2.bend
    │   │   ├── lam_op2_nested.bend
    │   │   ├── let_tup_readback.bend
    │   │   ├── linearize_match.bend
    │   │   ├── list_resugar.bend
    │   │   ├── list_reverse.bend
    │   │   ├── list_reverse_imp.bend
    │   │   ├── list_take.bend
    │   │   ├── list_to_tree.bend
    │   │   ├── mapper_syntax.bend
    │   │   ├── match.bend
    │   │   ├── match_builtins.bend
    │   │   ├── match_mult_linearization.bend
    │   │   ├── match_num_adt_tup_parser.bend
    │   │   ├── match_num_explicit_bind.bend
    │   │   ├── match_num_num_to_char.bend
    │   │   ├── match_num_succ_complex.bend
    │   │   ├── match_str.bend
    │   │   ├── match_sup.bend
    │   │   ├── match_vars.bend
    │   │   ├── math.bend
    │   │   ├── merge_sort.bend
    │   │   ├── mixed_syntax.bend
    │   │   ├── names_hyphen.bend
    │   │   ├── names_hyphen_toplevel.bend
    │   │   ├── nat_add.bend
    │   │   ├── nat_add_num.bend
    │   │   ├── nested_list_and_string.bend
    │   │   ├── nested_map_get.bend
    │   │   ├── nested_map_set.bend
    │   │   ├── nested_str.bend
    │   │   ├── num_cast.bend
    │   │   ├── num_match_missing_var.bend
    │   │   ├── num_pred.bend
    │   │   ├── open.bend
    │   │   ├── open_object.bend
    │   │   ├── open_too_many_ctrs.bend
    │   │   ├── open_undefined_type.bend
    │   │   ├── ops.bend
    │   │   ├── override_list_ctr.bend
    │   │   ├── override_str_ctr.bend
    │   │   ├── pred.bend
    │   │   ├── queue.bend
    │   │   ├── radix_sort_ctr.bend
    │   │   ├── readback_hvm1_main.bend
    │   │   ├── readback_list_other_ctr.bend
    │   │   ├── readback_num_ops.bend
    │   │   ├── recursive_bind.bend
    │   │   ├── recursive_combinator.bend
    │   │   ├── recursive_combinator_nested.bend
    │   │   ├── recursive_match_native.bend
    │   │   ├── ref_resolution.bend
    │   │   ├── repeated_name_truncation.bend
    │   │   ├── scopeless_discard.bend
    │   │   ├── str_concat.bend
    │   │   ├── str_inc.bend
    │   │   ├── str_inc_eta.bend
    │   │   ├── str_len.bend
    │   │   ├── strict_monad_fn.bend
    │   │   ├── sum_tree.bend
    │   │   ├── sup_app.bend
    │   │   ├── sup_reconstruction.bend
    │   │   ├── superposed_is_even.bend
    │   │   ├── tagged_lam.bend
    │   │   ├── tree_to_list.bend
    │   │   ├── tup_list_strings.bend
    │   │   ├── tup_reconstruction.bend
    │   │   ├── tuple_eta.bend
    │   │   ├── tuple_rots.bend
    │   │   ├── unaplied_str.bend
    │   │   ├── unbound_wrap.bend
    │   │   ├── unscoped_never_used.bend
    │   │   ├── unused_dup_var.bend
    │   │   ├── unused_main_var.bend
    │   │   ├── world.bend
    │   │   └── wrong_string.bend
    │   ├── run_lazy/
    │   │   ├── addition.bend
    │   │   ├── adt_match.bend
    │   │   ├── adt_match_wrong_tag.bend
    │   │   ├── adt_option_and.bend
    │   │   ├── adt_wrong_tag.bend
    │   │   ├── and.bend
    │   │   ├── bitonic_sort.bend
    │   │   ├── bitonic_sort_lam.bend
    │   │   ├── box.bend
    │   │   ├── box2.bend
    │   │   ├── callcc.bend
    │   │   ├── chars.bend
    │   │   ├── def_tups.bend
    │   │   ├── dup_global_lam.bend
    │   │   ├── eta.bend
    │   │   ├── example.bend
    │   │   ├── exp.bend
    │   │   ├── extracted_match_pred.bend
    │   │   ├── field_vectorization.bend
    │   │   ├── lam_op2.bend
    │   │   ├── lam_op2_nested.bend
    │   │   ├── let_tup_readback.bend
    │   │   ├── linearize_match.bend
    │   │   ├── list_resugar.bend
    │   │   ├── list_reverse.bend
    │   │   ├── list_take.bend
    │   │   ├── list_to_tree.bend
    │   │   ├── match.bend
    │   │   ├── match_builtins.bend
    │   │   ├── match_mult_linearization.bend
    │   │   ├── match_num_explicit_bind.bend
    │   │   ├── merge_sort.bend
    │   │   ├── nested_list_and_string.bend
    │   │   ├── nested_str.bend
    │   │   ├── num_pred.bend
    │   │   ├── queue.bend
    │   │   ├── radix_sort_ctr.bend
    │   │   ├── recursive_match_native.bend
    │   │   ├── scopeless_discard.bend
    │   │   ├── str_concat.bend
    │   │   ├── str_inc.bend
    │   │   ├── str_inc_eta.bend
    │   │   ├── str_len.bend
    │   │   ├── sum_tree.bend
    │   │   ├── sup_app.bend
    │   │   ├── sup_reconstruction.bend
    │   │   ├── superposed_is_even.bend
    │   │   ├── tagged_lam.bend
    │   │   ├── tup_reconstruction.bend
    │   │   ├── tuple_rots.bend
    │   │   ├── unaplied_str.bend
    │   │   ├── unused_dup_var.bend
    │   │   ├── world.bend
    │   │   └── wrong_string.bend
    │   ├── scott_triggers_unused/
    │   │   └── test.bend
    │   └── simplify_matches/
    │       ├── adt_tup_era.bend
    │       ├── already_flat.bend
    │       ├── bits_dec.bend
    │       ├── complex_with_case.bend
    │       ├── double_unwrap_box.bend
    │       ├── double_unwrap_maybe.bend
    │       ├── flatten_with_terminal.bend
    │       ├── irrefutable_case.bend
    │       ├── linearize_match_all.bend
    │       ├── match_str.bend
    │       ├── nested.bend
    │       ├── nested2.bend
    │       ├── nested_0ary.bend
    │       ├── redundant_with_era.bend
    │       └── wrong_fn_arity.bend
    ├── golden_tests.rs
    └── snapshots/
        ├── check_file__fail_type_bad_rec_fn_adt.bend.snap
        ├── check_file__non_exaustive_limit.bend.snap
        ├── check_file__type_err_match_arm.bend.snap
        ├── cli__compile_all.bend.snap
        ├── cli__compile_inline.bend.snap
        ├── cli__compile_no_opts.bend.snap
        ├── cli__compile_pre_reduce.bend.snap
        ├── cli__compile_strict_loop.bend.snap
        ├── cli__compile_wrong_opt.bend.snap
        ├── cli__custom_hvm_bin.bend.snap
        ├── cli__debug_list_map.bend.snap
        ├── cli__debug_u60_to_nat.bend.snap
        ├── cli__desugar_bool_scott.bend.snap
        ├── cli__desugar_float_combinators.bend.snap
        ├── cli__desugar_linearize_matches.bend.snap
        ├── cli__desugar_linearize_matches_alt.bend.snap
        ├── cli__desugar_merge.bend.snap
        ├── cli__desugar_pretty.bend.snap
        ├── cli__desugar_prune.bend.snap
        ├── cli__gen_hvm_no_eta_by_default.bend.snap
        ├── cli__input_file_not_found.bend.snap
        ├── cli__net_size_too_large.bend.snap
        ├── cli__no_check_net_size.bend.snap
        ├── cli__run_add.bend.snap
        ├── cli__run_pretty.bend.snap
        ├── cli__tuple_readback.bend.snap
        ├── cli__warn_and_err.bend.snap
        ├── compile_entrypoint__foo.bend.snap
        ├── compile_file__360_no_scope.bend.snap
        ├── compile_file__add_args.bend.snap
        ├── compile_file__addition.bend.snap
        ├── compile_file__addition_const.bend.snap
        ├── compile_file__ask_outside_do.bend.snap
        ├── compile_file__church_one.bend.snap
        ├── compile_file__church_zero.bend.snap
        ├── compile_file__complicated_dup.bend.snap
        ├── compile_file__crlf.bend.snap
        ├── compile_file__cyclic_global_lam.bend.snap
        ├── compile_file__def_pat_unscoped.bend.snap
        ├── compile_file__dup_apply.bend.snap
        ├── compile_file__dup_global_lam.bend.snap
        ├── compile_file__elif.bend.snap
        ├── compile_file__elif_fun.bend.snap
        ├── compile_file__elif_no_else.bend.snap
        ├── compile_file__erased_dup.bend.snap
        ├── compile_file__error_data_def_name.bend.snap
        ├── compile_file__error_messages.bend.snap
        ├── compile_file__f24_oper.bend.snap
        ├── compile_file__fst_snd.bend.snap
        ├── compile_file__global_lam.bend.snap
        ├── compile_file__i24_oper.bend.snap
        ├── compile_file__id.bend.snap
        ├── compile_file__infer_dup.bend.snap
        ├── compile_file__inlining.bend.snap
        ├── compile_file__just_a_name.bend.snap
        ├── compile_file__just_data.bend.snap
        ├── compile_file__just_paren.bend.snap
        ├── compile_file__just_rule_paren.bend.snap
        ├── compile_file__let_substitution.bend.snap
        ├── compile_file__let_tup.bend.snap
        ├── compile_file__lets.bend.snap
        ├── compile_file__long_name.bend.snap
        ├── compile_file__match.bend.snap
        ├── compile_file__mismatched_ask_statements.bend.snap
        ├── compile_file__missing_adt_eq.bend.snap
        ├── compile_file__missing_ctrs.bend.snap
        ├── compile_file__missing_pat.bend.snap
        ├── compile_file__names_starting_with_keywords.bend.snap
        ├── compile_file__nested_ctr_wrong_arity.bend.snap
        ├── compile_file__nested_let.bend.snap
        ├── compile_file__number_too_large.bend.snap
        ├── compile_file__nums.bend.snap
        ├── compile_file__op2.bend.snap
        ├── compile_file__redex_order.bend.snap
        ├── compile_file__redex_order_recursive.bend.snap
        ├── compile_file__ref_to_main.bend.snap
        ├── compile_file__ref_to_ref.bend.snap
        ├── compile_file__repeated_bind_rule.bend.snap
        ├── compile_file__simple_tup.bend.snap
        ├── compile_file__switch_all_patterns.bend.snap
        ├── compile_file__switch_in_switch_arg.bend.snap
        ├── compile_file__switch_incomplete.bend.snap
        ├── compile_file__switch_unscoped_lambda.bend.snap
        ├── compile_file__top_level_name_slashslash.bend.snap
        ├── compile_file__tup.bend.snap
        ├── compile_file__tup_add.bend.snap
        ├── compile_file__unbound_unscoped_var.bend.snap
        ├── compile_file__unbound_var.bend.snap
        ├── compile_file__unbound_var_scope.bend.snap
        ├── compile_file__unbound_with_tup_pattern.bend.snap
        ├── compile_file__underscore.bend.snap
        ├── compile_file__unexpected_top_char.bend.snap
        ├── compile_file__unscoped_dup_use.bend.snap
        ├── compile_file__unscoped_supercombinator.bend.snap
        ├── compile_file__unused_let.bend.snap
        ├── compile_file__unused_unscoped_bind.bend.snap
        ├── compile_file__variable_name_double_underscore.bend.snap
        ├── compile_file__vicious_circles.bend.snap
        ├── compile_file__warn_and_err.bend.snap
        ├── compile_file__with_clause_parse_err.bend.snap
        ├── compile_file__wrong_ctr_arity.bend.snap
        ├── compile_file__wrong_ctr_var_arity.bend.snap
        ├── compile_file__wrong_nums.bend.snap
        ├── compile_file__wrong_unicode_escape.bend.snap
        ├── compile_file_o_all__addition.bend.snap
        ├── compile_file_o_all__addition_var_fst.bend.snap
        ├── compile_file_o_all__adt_option_and.bend.snap
        ├── compile_file_o_all__adt_string.bend.snap
        ├── compile_file_o_all__and.bend.snap
        ├── compile_file_o_all__bad_parens_making_erased_let.bend.snap
        ├── compile_file_o_all__bool.bend.snap
        ├── compile_file_o_all__cyclic_dup.bend.snap
        ├── compile_file_o_all__double_main.bend.snap
        ├── compile_file_o_all__eta_chain.bend.snap
        ├── compile_file_o_all__ex0.bend.snap
        ├── compile_file_o_all__ex2.bend.snap
        ├── compile_file_o_all__example.bend.snap
        ├── compile_file_o_all__exp.bend.snap
        ├── compile_file_o_all__expr.bend.snap
        ├── compile_file_o_all__extracted_match_pred.bend.snap
        ├── compile_file_o_all__fst.bend.snap
        ├── compile_file_o_all__fst_fst.bend.snap
        ├── compile_file_o_all__hvm1_main.bend.snap
        ├── compile_file_o_all__inline_app.bend.snap
        ├── compile_file_o_all__inlining.bend.snap
        ├── compile_file_o_all__linearize_match.bend.snap
        ├── compile_file_o_all__list_merge_sort.bend.snap
        ├── compile_file_o_all__list_reverse.bend.snap
        ├── compile_file_o_all__match_adt_non_exhaustive.bend.snap
        ├── compile_file_o_all__match_dup_and_reconstruction.bend.snap
        ├── compile_file_o_all__match_mult_linearization.bend.snap
        ├── compile_file_o_all__match_num_explicit_bind.bend.snap
        ├── compile_file_o_all__match_tup.bend.snap
        ├── compile_file_o_all__merge_definitions.bend.snap
        ├── compile_file_o_all__non_exhaustive_and.bend.snap
        ├── compile_file_o_all__non_exhaustive_different_types.bend.snap
        ├── compile_file_o_all__non_exhaustive_pattern.bend.snap
        ├── compile_file_o_all__non_exhaustive_tree.bend.snap
        ├── compile_file_o_all__num_pattern_with_var.bend.snap
        ├── compile_file_o_all__recursive_combinator_inactive.bend.snap
        ├── compile_file_o_all__repeated_name_trucation.bend.snap
        ├── compile_file_o_all__scrutinee_reconstruction.bend.snap
        ├── compile_file_o_all__self_ref.bend.snap
        ├── compile_file_o_all__snd.bend.snap
        ├── compile_file_o_all__spacing.bend.snap
        ├── compile_file_o_all__spacing2.bend.snap
        ├── compile_file_o_all__str.bend.snap
        ├── compile_file_o_all__sum_predicates.bend.snap
        ├── compile_file_o_all__tagged_dup.bend.snap
        ├── compile_file_o_all__tagged_lam.bend.snap
        ├── compile_file_o_all__tagged_sup.bend.snap
        ├── compile_file_o_all__unapplied_eta.bend.snap
        ├── compile_file_o_all__unscoped_eta.bend.snap
        ├── compile_file_o_all__var_shadows_ref.bend.snap
        ├── compile_file_o_all__weekday.bend.snap
        ├── compile_file_o_no_all__bitonic_sort.bend.snap
        ├── compile_file_o_no_all__list_reverse.bend.snap
        ├── compile_file_o_no_all__redex_order.bend.snap
        ├── compile_file_o_no_all__sum_tree.bend.snap
        ├── compile_long__huge_tree.bend.snap
        ├── compile_long__long_str_file.bend.snap
        ├── desugar_file__ask_branch.bend.snap
        ├── desugar_file__bind_syntax.bend.snap
        ├── desugar_file__combinators.bend.snap
        ├── desugar_file__deref_loop.bend.snap
        ├── desugar_file__dup_linearization.bend.snap
        ├── desugar_file__local_def_shadow.bend.snap
        ├── desugar_file__main_aux.bend.snap
        ├── desugar_file__mapper_syntax.bend.snap
        ├── desugar_file__switch_with_use.bend.snap
        ├── desugar_file__tree_syntax.bend.snap
        ├── desugar_file__use_id.bend.snap
        ├── desugar_file__use_shadow.bend.snap
        ├── desugar_file__used_once_names.bend.snap
        ├── encode_pattern_match__adt_tup_era.bend.snap
        ├── encode_pattern_match__and3.bend.snap
        ├── encode_pattern_match__bool.bend.snap
        ├── encode_pattern_match__bool_tup.bend.snap
        ├── encode_pattern_match__box.bend.snap
        ├── encode_pattern_match__common.bend.snap
        ├── encode_pattern_match__concat.bend.snap
        ├── encode_pattern_match__concat_def.bend.snap
        ├── encode_pattern_match__def_tups.bend.snap
        ├── encode_pattern_match__definition_merge.bend.snap
        ├── encode_pattern_match__expr.bend.snap
        ├── encode_pattern_match__flatten_era_pat.bend.snap
        ├── encode_pattern_match__full_map.bend.snap
        ├── encode_pattern_match__is_some_some.bend.snap
        ├── encode_pattern_match__list_merge_sort.bend.snap
        ├── encode_pattern_match__list_str_encoding_undeclared_fn.bend.snap
        ├── encode_pattern_match__list_str_encoding_undeclared_map.bend.snap
        ├── encode_pattern_match__match_adt_unscoped_in_arm.bend.snap
        ├── encode_pattern_match__match_adt_unscoped_lambda.bend.snap
        ├── encode_pattern_match__match_adt_unscoped_var.bend.snap
        ├── encode_pattern_match__match_auto_linearization.bend.snap
        ├── encode_pattern_match__match_bind.bend.snap
        ├── encode_pattern_match__match_num_adt_tup_parser.bend.snap
        ├── encode_pattern_match__match_num_pred.bend.snap
        ├── encode_pattern_match__match_syntax.bend.snap
        ├── encode_pattern_match__merge_recursive.bend.snap
        ├── encode_pattern_match__no_patterns.bend.snap
        ├── encode_pattern_match__non_matching_fst_arg.bend.snap
        ├── encode_pattern_match__ntup_sum.bend.snap
        ├── encode_pattern_match__pattern_match_encoding.bend.snap
        ├── encode_pattern_match__switch_in_switch_arg.bend.snap
        ├── encode_pattern_match__var_only.bend.snap
        ├── encode_pattern_match__weekday.bend.snap
        ├── examples__bitonic_sort.bend.snap
        ├── examples__bubble_sort.bend.snap
        ├── examples__callcc.bend.snap
        ├── examples__example_fun.bend.snap
        ├── examples__fib.bend.snap
        ├── examples__fusing_add.bend.snap
        ├── examples__fusing_not.bend.snap
        ├── examples__gen_tree.bend.snap
        ├── examples__hello_world.bend.snap
        ├── examples__insertion_sort.bend.snap
        ├── examples__list.bend.snap
        ├── examples__parallel_and.bend.snap
        ├── examples__parallel_hello_world.bend.snap
        ├── examples__parallel_sum.bend.snap
        ├── examples__queue.bend.snap
        ├── examples__quick_sort.bend.snap
        ├── examples__radix_sort.bend.snap
        ├── import_system__import_ctr_syntax.bend.snap
        ├── import_system__import_main.bend.snap
        ├── import_system__import_main2.bend.snap
        ├── import_system__import_main3.bend.snap
        ├── import_system__import_type.bend.snap
        ├── import_system__import_types.bend.snap
        ├── import_system__imports.bend.snap
        ├── import_system__imports_alias.bend.snap
        ├── import_system__imports_alias_shadow.bend.snap
        ├── import_system__imports_conflict.bend.snap
        ├── import_system__imports_file_and_dir.bend.snap
        ├── import_system__imports_file_and_dir_conflict.bend.snap
        ├── import_system__imports_shadow.bend.snap
        ├── import_system__imports_shadow2.bend.snap
        ├── io__load.bend.snap
        ├── io__load_fail.bend.snap
        ├── io__read_line_eof.bend.snap
        ├── io__store.bend.snap
        ├── io__store_fail.bend.snap
        ├── io__utf8.bend.snap
        ├── linear_readback__church_mul.bend.snap
        ├── mutual_recursion__a_b_c.bend.snap
        ├── mutual_recursion__len.bend.snap
        ├── mutual_recursion__merged.bend.snap
        ├── mutual_recursion__multiple.bend.snap
        ├── mutual_recursion__odd_even.bend.snap
        ├── parse_file__bad_floating.bend.snap
        ├── parse_file__bend_missing_else.bend.snap
        ├── parse_file__era.bend.snap
        ├── parse_file__fold_missing_case.bend.snap
        ├── parse_file__fun_def.bend.snap
        ├── parse_file__fun_def_name.bend.snap
        ├── parse_file__if_missing_else.bend.snap
        ├── parse_file__imp_map.bend.snap
        ├── parse_file__imp_program.bend.snap
        ├── parse_file__match_missing_case.bend.snap
        ├── parse_file__multi_line_comment.bend.snap
        ├── parse_file__redefinition_builtin.bend.snap
        ├── parse_file__redefinition_ctr_with_fun.bend.snap
        ├── parse_file__redefinition_fun_imp.bend.snap
        ├── parse_file__redefinition_imp_fun.bend.snap
        ├── parse_file__redefinition_type_with_object.bend.snap
        ├── parse_file__redefinition_with_def_between.bend.snap
        ├── parse_file__redefinition_with_object_between.bend.snap
        ├── parse_file__redefinition_with_type_between.bend.snap
        ├── parse_file__repeated_adt_name.bend.snap
        ├── parse_file__repeated_datatype_name.bend.snap
        ├── parse_file__scape_chars.bend.snap
        ├── parse_file__strange_pattern.bend.snap
        ├── parse_file__tab.bend.snap
        ├── parse_file__tup_with_signed.bend.snap
        ├── parse_file__tuple_assign.bend.snap
        ├── parse_file__tuple_commas.bend.snap
        ├── parse_file__tuple_need_parens.bend.snap
        ├── prelude__applies_function_to_map.bend.snap
        ├── prelude__get_values_from_map.bend.snap
        ├── prelude__lists_to_map.bend.snap
        ├── prelude__map_checked_test.bend.snap
        ├── prelude__map_contains_test.bend.snap
        ├── prelude__set_node_when_empty.bend.snap
        ├── readback_hvm__addition.bend.snap
        ├── readback_hvm__bad_net.bend.snap
        ├── readback_hvm__bad_net1.bend.snap
        ├── readback_hvm__bad_net3.bend.snap
        ├── readback_hvm__complicated_dup.bend.snap
        ├── readback_hvm__fst_snd.bend.snap
        ├── readback_hvm__id.bend.snap
        ├── readback_hvm__invalid_op2_op2.bend.snap
        ├── readback_hvm__match.bend.snap
        ├── readback_hvm__nested_let.bend.snap
        ├── readback_hvm__nested_tup.bend.snap
        ├── readback_hvm__number.bend.snap
        ├── readback_hvm__simple_tup.bend.snap
        ├── readback_hvm__tup_add.bend.snap
        ├── run_file__360_no_scope.bend.snap
        ├── run_file__addition.bend.snap
        ├── run_file__adt_match.bend.snap
        ├── run_file__adt_match_wrong_tag.bend.snap
        ├── run_file__adt_option_and.bend.snap
        ├── run_file__adt_wrong_tag.bend.snap
        ├── run_file__and.bend.snap
        ├── run_file__basic_num_ops.bend.snap
        ├── run_file__bend_fold.bend.snap
        ├── run_file__bitonic_sort.bend.snap
        ├── run_file__bitonic_sort_lam.bend.snap
        ├── run_file__box.bend.snap
        ├── run_file__branch_statements_assignment.bend.snap
        ├── run_file__callcc.bend.snap
        ├── run_file__chars.bend.snap
        ├── run_file__chars_forall.bend.snap
        ├── run_file__chars_lambda.bend.snap
        ├── run_file__checked_scott_encoding.bend.snap
        ├── run_file__comprehension.bend.snap
        ├── run_file__def_bool_num.bend.snap
        ├── run_file__def_num_bool.bend.snap
        ├── run_file__def_tups.bend.snap
        ├── run_file__do_block_mixed.bend.snap
        ├── run_file__dup_global_lam.bend.snap
        ├── run_file__empty.bend.snap
        ├── run_file__encode_decode_utf8.bend.snap
        ├── run_file__erased_side_effect.bend.snap
        ├── run_file__escape_sequences.bend.snap
        ├── run_file__eta.bend.snap
        ├── run_file__example.bend.snap
        ├── run_file__exp.bend.snap
        ├── run_file__expand_main_combinator.bend.snap
        ├── run_file__expand_main_list.bend.snap
        ├── run_file__extracted_match_pred.bend.snap
        ├── run_file__filter_bool_id.bend.snap
        ├── run_file__floating_numbers.bend.snap
        ├── run_file__fold_with_state.bend.snap
        ├── run_file__guide_bend_7tree.bend.snap
        ├── run_file__guide_bend_sequential.bend.snap
        ├── run_file__guide_bend_sum_tree.bend.snap
        ├── run_file__guide_bitonic_sort.bend.snap
        ├── run_file__guide_circle_area.bend.snap
        ├── run_file__guide_distance_4args.bend.snap
        ├── run_file__guide_distance_obj.bend.snap
        ├── run_file__guide_distance_tup.bend.snap
        ├── run_file__guide_enumerate.bend.snap
        ├── run_file__guide_if_age.bend.snap
        ├── run_file__guide_is_even_num.bend.snap
        ├── run_file__guide_is_even_str.bend.snap
        ├── run_file__guide_list_ctrs.bend.snap
        ├── run_file__guide_list_match.bend.snap
        ├── run_file__guide_list_sugar.bend.snap
        ├── run_file__guide_mul2_inline.bend.snap
        ├── run_file__guide_mul2_rec.bend.snap
        ├── run_file__guide_shader_dummy.bend.snap
        ├── run_file__guide_sum.bend.snap
        ├── run_file__hvm_def_cast.bend.snap
        ├── run_file__hvm_def_two_defs.bend.snap
        ├── run_file__id_underscore.bend.snap
        ├── run_file__imp_empty_literals.bend.snap
        ├── run_file__imp_use_statement.bend.snap
        ├── run_file__kind_compiled_tree_sum.bend.snap
        ├── run_file__lam_op2.bend.snap
        ├── run_file__lam_op2_nested.bend.snap
        ├── run_file__let_tup_readback.bend.snap
        ├── run_file__linearize_match.bend.snap
        ├── run_file__list_resugar.bend.snap
        ├── run_file__list_reverse.bend.snap
        ├── run_file__list_reverse_imp.bend.snap
        ├── run_file__list_take.bend.snap
        ├── run_file__list_to_tree.bend.snap
        ├── run_file__mapper_syntax.bend.snap
        ├── run_file__match.bend.snap
        ├── run_file__match_builtins.bend.snap
        ├── run_file__match_mult_linearization.bend.snap
        ├── run_file__match_num_adt_tup_parser.bend.snap
        ├── run_file__match_num_explicit_bind.bend.snap
        ├── run_file__match_num_num_to_char.bend.snap
        ├── run_file__match_num_succ_complex.bend.snap
        ├── run_file__match_str.bend.snap
        ├── run_file__match_sup.bend.snap
        ├── run_file__match_vars.bend.snap
        ├── run_file__math.bend.snap
        ├── run_file__merge_sort.bend.snap
        ├── run_file__mixed_syntax.bend.snap
        ├── run_file__names_hyphen.bend.snap
        ├── run_file__names_hyphen_toplevel.bend.snap
        ├── run_file__nat_add.bend.snap
        ├── run_file__nat_add_num.bend.snap
        ├── run_file__nested_list_and_string.bend.snap
        ├── run_file__nested_map_get.bend.snap
        ├── run_file__nested_map_set.bend.snap
        ├── run_file__nested_str.bend.snap
        ├── run_file__num_cast.bend.snap
        ├── run_file__num_match_missing_var.bend.snap
        ├── run_file__num_pred.bend.snap
        ├── run_file__open.bend.snap
        ├── run_file__open_object.bend.snap
        ├── run_file__open_too_many_ctrs.bend.snap
        ├── run_file__open_undefined_type.bend.snap
        ├── run_file__ops.bend.snap
        ├── run_file__override_list_ctr.bend.snap
        ├── run_file__override_str_ctr.bend.snap
        ├── run_file__pred.bend.snap
        ├── run_file__queue.bend.snap
        ├── run_file__radix_sort_ctr.bend.snap
        ├── run_file__readback_hvm1_main.bend.snap
        ├── run_file__readback_list_other_ctr.bend.snap
        ├── run_file__readback_num_ops.bend.snap
        ├── run_file__recursive_bind.bend.snap
        ├── run_file__recursive_combinator.bend.snap
        ├── run_file__recursive_combinator_nested.bend.snap
        ├── run_file__recursive_match_native.bend.snap
        ├── run_file__ref_resolution.bend.snap
        ├── run_file__repeated_name_truncation.bend.snap
        ├── run_file__scopeless_discard.bend.snap
        ├── run_file__str_concat.bend.snap
        ├── run_file__str_inc.bend.snap
        ├── run_file__str_inc_eta.bend.snap
        ├── run_file__str_len.bend.snap
        ├── run_file__strict_monad_fn.bend.snap
        ├── run_file__sum_tree.bend.snap
        ├── run_file__sup_app.bend.snap
        ├── run_file__sup_reconstruction.bend.snap
        ├── run_file__superposed_is_even.bend.snap
        ├── run_file__tagged_lam.bend.snap
        ├── run_file__tree_to_list.bend.snap
        ├── run_file__tup_list_strings.bend.snap
        ├── run_file__tup_reconstruction.bend.snap
        ├── run_file__tuple_eta.bend.snap
        ├── run_file__tuple_rots.bend.snap
        ├── run_file__unaplied_str.bend.snap
        ├── run_file__unbound_wrap.bend.snap
        ├── run_file__unscoped_never_used.bend.snap
        ├── run_file__unused_dup_var.bend.snap
        ├── run_file__unused_main_var.bend.snap
        ├── run_file__world.bend.snap
        ├── run_file__wrong_string.bend.snap
        ├── scott_triggers_unused__test.bend.snap
        ├── simplify_matches__adt_tup_era.bend.snap
        ├── simplify_matches__already_flat.bend.snap
        ├── simplify_matches__bits_dec.bend.snap
        ├── simplify_matches__complex_with_case.bend.snap
        ├── simplify_matches__double_unwrap_box.bend.snap
        ├── simplify_matches__double_unwrap_maybe.bend.snap
        ├── simplify_matches__flatten_with_terminal.bend.snap
        ├── simplify_matches__irrefutable_case.bend.snap
        ├── simplify_matches__linearize_match_all.bend.snap
        ├── simplify_matches__match_str.bend.snap
        ├── simplify_matches__nested.bend.snap
        ├── simplify_matches__nested2.bend.snap
        ├── simplify_matches__nested_0ary.bend.snap
        ├── simplify_matches__redundant_with_era.bend.snap
        └── simplify_matches__wrong_fn_arity.bend.snap
Download .txt
SYMBOL INDEX (863 symbols across 59 files)

FILE: src/diagnostics.rs
  constant ERR_INDENT_SIZE (line 10) | pub const ERR_INDENT_SIZE: usize = 2;
  type Diagnostics (line 13) | pub struct Diagnostics {
    method new (line 72) | pub fn new(config: DiagnosticsConfig) -> Self {
    method add_parsing_error (line 76) | pub fn add_parsing_error(&mut self, err: impl std::fmt::Display, sourc...
    method add_book_error (line 80) | pub fn add_book_error(&mut self, err: impl std::fmt::Display) {
    method add_function_error (line 84) | pub fn add_function_error(&mut self, err: impl std::fmt::Display, name...
    method add_inet_error (line 93) | pub fn add_inet_error(&mut self, err: impl std::fmt::Display, def_name...
    method add_function_warning (line 97) | pub fn add_function_warning(
    method add_book_warning (line 113) | pub fn add_book_warning(&mut self, warn: impl std::fmt::Display, warn_...
    method add_diagnostic (line 118) | pub fn add_diagnostic(
    method take_rule_err (line 129) | pub fn take_rule_err<T, E: std::fmt::Display>(
    method take_inet_err (line 143) | pub fn take_inet_err<T, E: std::fmt::Display>(
    method has_severity (line 157) | pub fn has_severity(&self, severity: Severity) -> bool {
    method has_errors (line 161) | pub fn has_errors(&self) -> bool {
    method fatal (line 168) | pub fn fatal<T>(&mut self, t: T) -> Result<T, Diagnostics> {
    method display_with_severity (line 177) | pub fn display_with_severity(&self, severity: Severity) -> impl std::f...
    method display_only_messages (line 279) | pub fn display_only_messages(&self) -> impl std::fmt::Display + '_ {
    method from (line 302) | fn from(value: String) -> Self {
    method from (line 319) | fn from(value: ParseError) -> Self {
  type DiagnosticsConfig (line 19) | pub struct DiagnosticsConfig {
    method new (line 331) | pub fn new(severity: Severity, verbose: bool) -> Self {
    method warning_severity (line 346) | pub fn warning_severity(&self, warn: WarningType) -> Severity {
  type Diagnostic (line 32) | pub struct Diagnostic {
    method display_with_origin (line 375) | pub fn display_with_origin<'a>(&'a self, origin: &'a DiagnosticOrigin)...
  type DiagnosticOrigin (line 39) | pub enum DiagnosticOrigin {
  type Severity (line 53) | pub enum Severity {
  type WarningType (line 60) | pub enum WarningType {
  method fmt (line 290) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
  method default (line 361) | fn default() -> Self {
  method fmt (line 369) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
  type TextLocation (line 399) | pub struct TextLocation {
    method new (line 405) | pub fn new(line: usize, char: usize) -> Self {
    method from_byte_loc (line 410) | pub fn from_byte_loc(code: &str, loc: usize) -> Self {
  type TextSpan (line 430) | pub struct TextSpan {
    method new (line 436) | pub fn new(start: TextLocation, end: TextLocation) -> Self {
    method from_byte_span (line 441) | pub fn from_byte_span(code: &str, span: Range<usize>) -> Self {

FILE: src/fun/builtins.rs
  constant BUILTINS (line 7) | const BUILTINS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
  constant LIST (line 9) | pub const LIST: &str = "List";
  constant LCONS (line 10) | pub const LCONS: &str = "List/Cons";
  constant LNIL (line 11) | pub const LNIL: &str = "List/Nil";
  constant LCONS_TAG (line 12) | pub const LCONS_TAG: u32 = 1;
  constant LNIL_TAG_REF (line 13) | pub const LNIL_TAG_REF: &str = "List/Nil/tag";
  constant LCONS_TAG_REF (line 14) | pub const LCONS_TAG_REF: &str = "List/Cons/tag";
  constant HEAD (line 16) | pub const HEAD: &str = "head";
  constant TAIL (line 17) | pub const TAIL: &str = "tail";
  constant STRING (line 19) | pub const STRING: &str = "String";
  constant SCONS (line 20) | pub const SCONS: &str = "String/Cons";
  constant SNIL (line 21) | pub const SNIL: &str = "String/Nil";
  constant SCONS_TAG (line 22) | pub const SCONS_TAG: u32 = 1;
  constant SNIL_TAG_REF (line 23) | pub const SNIL_TAG_REF: &str = "String/Nil/tag";
  constant SCONS_TAG_REF (line 24) | pub const SCONS_TAG_REF: &str = "String/Cons/tag";
  constant NAT (line 26) | pub const NAT: &str = "Nat";
  constant NAT_SUCC (line 27) | pub const NAT_SUCC: &str = "Nat/Succ";
  constant NAT_ZERO (line 28) | pub const NAT_ZERO: &str = "Nat/Zero";
  constant NAT_SUCC_TAG (line 29) | pub const NAT_SUCC_TAG: u32 = 0;
  constant TREE (line 31) | pub const TREE: &str = "Tree";
  constant TREE_NODE (line 32) | pub const TREE_NODE: &str = "Tree/Node";
  constant TREE_LEAF (line 33) | pub const TREE_LEAF: &str = "Tree/Leaf";
  constant MAP (line 35) | pub const MAP: &str = "Map";
  constant MAP_NODE (line 36) | pub const MAP_NODE: &str = "Map/Node";
  constant MAP_LEAF (line 37) | pub const MAP_LEAF: &str = "Map/Leaf";
  constant IO (line 39) | pub const IO: &str = "IO";
  constant IO_DONE (line 40) | pub const IO_DONE: &str = "IO/Done";
  constant IO_CALL (line 41) | pub const IO_CALL: &str = "IO/Call";
  constant BUILTIN_CTRS (line 43) | pub const BUILTIN_CTRS: &[&str] =
  constant BUILTIN_TYPES (line 46) | pub const BUILTIN_TYPES: &[&str] = &[LIST, STRING, NAT, TREE, MAP, IO];
  method builtins (line 49) | pub fn builtins() -> Self {
  method encode_builtins (line 57) | pub fn encode_builtins(&mut self) {
  method encode_builtins (line 68) | fn encode_builtins(&mut self) {
  method encode_list (line 88) | fn encode_list(elements: Vec<Term>) -> Term {
  method encode_str (line 95) | pub fn encode_str(val: &str) -> Term {
  method encode_nat (line 101) | pub fn encode_nat(val: u32) -> Term {
  method encode_builtins (line 107) | pub fn encode_builtins(&mut self) {
  method encode_list (line 119) | fn encode_list(elements: Vec<Pattern>) -> Pattern {
  method encode_str (line 128) | fn encode_str(str: &str) -> Pattern {

FILE: src/fun/check/check_untyped.rs
  function check_untyped_terms (line 9) | pub fn check_untyped_terms(&mut self) -> Result<(), Diagnostics> {
  method check_untyped_terms (line 24) | fn check_untyped_terms(&self) -> Result<(), String> {
  method check_untyped_patterns (line 59) | fn check_untyped_patterns(&self) -> Result<(), String> {

FILE: src/fun/check/set_entrypoint.rs
  type EntryErr (line 8) | pub enum EntryErr {
    method fmt (line 73) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function set_entrypoint (line 15) | pub fn set_entrypoint(&mut self) {
  function validate_entry_point (line 55) | fn validate_entry_point(entry: &Definition) -> Result<Name, EntryErr> {
  method get_possible_entry_points (line 64) | fn get_possible_entry_points(&self) -> (Option<&Definition>, Option<&Def...

FILE: src/fun/check/shared_names.rs
  type RepeatedTopLevelNameErr (line 6) | pub struct RepeatedTopLevelNameErr {
    method fmt (line 88) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function check_shared_names (line 15) | pub fn check_shared_names(&mut self) {
  type NameKind (line 37) | enum NameKind {
  type NameInfo (line 44) | struct NameInfo<'a>(IndexMap<&'a Name, Vec<NameKind>>);
  function add_name (line 47) | fn add_name(&mut self, name: &'a Name, kind: NameKind) {
  function into_errs (line 51) | fn into_errs(self) -> Vec<RepeatedTopLevelNameErr> {
  method fmt (line 78) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

FILE: src/fun/check/type_check.rs
  function type_check (line 13) | pub fn type_check(&mut self) -> Result<(), Diagnostics> {
  type ProgramTypes (line 24) | type ProgramTypes = HashMap<Name, Scheme>;
  type Scheme (line 28) | struct Scheme(Vec<Name>, Type);
    method free_type_vars (line 85) | fn free_type_vars(&self) -> BTreeSet<Name> {
    method subst (line 91) | fn subst(&self, subst: &Subst) -> Scheme {
    method instantiate (line 102) | fn instantiate(&self, var_gen: &mut VarGen) -> Type {
  type Subst (line 32) | struct Subst(BTreeMap<Name, Type>);
    method compose (line 113) | fn compose(mut self, other: Subst) -> Subst {
    method fmt (line 778) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type TypeEnv (line 36) | struct TypeEnv(BTreeMap<Name, Scheme>);
    method free_type_vars (line 121) | fn free_type_vars(&self) -> BTreeSet<Name> {
    method subst (line 130) | fn subst(&self, subst: &Subst) -> TypeEnv {
    method insert (line 135) | fn insert(&mut self, name: Name, scheme: Scheme) {
    method add_binds (line 139) | fn add_binds<'a>(
    method pop_binds (line 153) | fn pop_binds(&mut self, old_bnd: Vec<(Name, Option<Scheme>)>) {
  type VarGen (line 40) | struct VarGen(usize);
    method fresh (line 163) | fn fresh(&mut self) -> Type {
    method fresh_name (line 168) | fn fresh_name(&mut self) -> Name {
  type RecGroups (line 43) | struct RecGroups(Vec<Vec<Name>>);
    method from_book (line 176) | fn from_book(book: &Book) -> RecGroups {
  method free_type_vars (line 48) | fn free_type_vars(&self) -> BTreeSet<Name> {
  method subst (line 58) | fn subst(&self, subst: &Subst) -> Type {
  method generalize (line 76) | fn generalize(&self, env: &TypeEnv) -> Scheme {
  function infer_book (line 273) | fn infer_book(book: &Book, diags: &mut Diagnostics) -> Result<ProgramTyp...
  function infer_group (line 304) | fn infer_group(
  function infer (line 368) | fn infer(
  function instantiate_adt (line 560) | fn instantiate_adt(adt: &Adt, var_gen: &mut VarGen) -> Result<(Subst, Ty...
  function infer_match_cases (line 568) | fn infer_match_cases(
  function unify_fields (line 603) | fn unify_fields<'a>(ts: impl Iterator<Item = (&'a Type, &'a Type)>, ctx:...
  function unify_term (line 612) | fn unify_term(t1: &Type, t2: &Type, ctx: &Term) -> Result<(Type, Subst),...
  function unify (line 619) | fn unify(t1: &Type, t2: &Type) -> Result<(Type, Subst), String> {
  function specialize (line 704) | fn specialize(inf: &Type, ann: &Type) -> Result<Type, String> {

FILE: src/fun/check/unbound_refs.rs
  function check_unbound_refs (line 9) | pub fn check_unbound_refs(&mut self) -> Result<(), Diagnostics> {
  method check_unbound_refs (line 28) | pub fn check_unbound_refs(&self, book: &Book, unbounds: &mut HashSet<Nam...

FILE: src/fun/check/unbound_vars.rs
  type UnboundVarErr (line 9) | pub enum UnboundVarErr {
    method fmt (line 106) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function check_unbound_vars (line 16) | pub fn check_unbound_vars(&mut self) -> Result<(), Diagnostics> {
  method check_unbound_vars (line 37) | pub fn check_unbound_vars<'a>(
  function check_uses (line 54) | pub fn check_uses<'a>(
  function check_global_binds (line 88) | pub fn check_global_binds(pat: &Pattern, globals: &mut HashMap<Name, (us...
  function scope_contains (line 101) | fn scope_contains(nam: &Name, scope: &[Option<&Name>]) -> bool {

FILE: src/fun/display.rs
  type DisplayFn (line 7) | pub struct DisplayFn<F: Fn(&mut fmt::Formatter) -> fmt::Result>(pub F);
  function fmt (line 10) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type DisplayJoin (line 15) | pub struct DisplayJoin<F, S>(pub F, pub S);
  function fmt (line 24) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  function gen_fan_pat_name (line 45) | fn gen_fan_pat_name() -> Name {
  function namegen_reset (line 50) | fn namegen_reset() {
  method fmt (line 55) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method fmt (line 183) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method fmt (line 194) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method display (line 212) | pub fn display<'a>(&'a self, def_name: &'a Name) -> impl fmt::Display + ...
  method fmt (line 223) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method fmt (line 231) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method fmt (line 241) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method display_app (line 247) | fn display_app<'a>(&'a self, tag: &'a Tag) -> impl fmt::Display + 'a {
  method fmt (line 260) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method display_padded (line 284) | pub fn display_padded(&self) -> impl fmt::Display + '_ {
  method fmt (line 295) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method display_arrow (line 320) | pub fn display_arrow(&self) -> impl fmt::Display + '_ {
  function var_as_str (line 332) | fn var_as_str(nam: &Option<Name>) -> &str {
  method display_pretty (line 339) | pub fn display_pretty(&self) -> impl fmt::Display + '_ {
  method display_pretty (line 352) | pub fn display_pretty(&self) -> impl fmt::Display + '_ {
  method display_pretty (line 359) | pub fn display_pretty<'a>(&'a self, def_name: &'a Name) -> impl fmt::Dis...
  method display_def_aux (line 368) | pub fn display_def_aux<'a>(&'a self, def_name: &'a Name, tab: usize) -> ...
  method display_pretty (line 380) | pub fn display_pretty(&self, tab: usize) -> impl fmt::Display + '_ {
  method display_app_pretty (line 557) | fn display_app_pretty<'a>(&'a self, tag: &'a Tag, tab: usize) -> impl fm...

FILE: src/fun/load_book.rs
  function load_file_to_book (line 14) | pub fn load_file_to_book(
  function load_to_book (line 31) | pub fn load_to_book(
  function do_parse_book (line 42) | pub fn do_parse_book(code: &str, origin: &Path, mut book: ParseBook) -> ...

FILE: src/fun/mod.rs
  type Ctx (line 29) | pub struct Ctx<'book> {
  function new (line 35) | pub fn new(book: &mut Book, diagnostics_cfg: DiagnosticsConfig) -> Ctx {
  type Book (line 42) | pub struct Book {
    method hvm_entrypoint (line 1226) | pub fn hvm_entrypoint(&self) -> &str {
  type Definitions (line 62) | pub type Definitions = IndexMap<Name, Definition>;
  type HvmDefinitions (line 63) | pub type HvmDefinitions = IndexMap<Name, HvmDefinition>;
  type Adts (line 64) | pub type Adts = IndexMap<Name, Adt>;
  type Constructors (line 65) | pub type Constructors = IndexMap<Name, Name>;
  type Definition (line 69) | pub struct Definition {
    method new_gen (line 1089) | pub fn new_gen(name: Name, rules: Vec<Rule>, source: Source, check: bo...
    method is_builtin (line 1095) | pub fn is_builtin(&self) -> bool {
    method arity (line 1099) | pub fn arity(&self) -> usize {
    method assert_no_pattern_matching_rules (line 1104) | pub fn assert_no_pattern_matching_rules(&self) {
    method rule (line 1110) | pub fn rule(&self) -> &Rule {
    method rule_mut (line 1116) | pub fn rule_mut(&mut self) -> &mut Rule {
  type Source (line 78) | pub struct Source {
    method is_builtin (line 1235) | pub fn is_builtin(&self) -> bool {
    method is_local (line 1239) | pub fn is_local(&self) -> bool {
    method from_file_span (line 1243) | pub fn from_file_span(file: &Name, txt: &str, span: Range<usize>, buil...
  type SourceKind (line 85) | pub enum SourceKind {
  type HvmDefinition (line 100) | pub struct HvmDefinition {
  type Type (line 108) | pub enum Type {
    method subst_ctr (line 1126) | pub fn subst_ctr(&mut self, from: &Name, to: &Name) {
    method children (line 1147) | pub fn children(&self) -> impl Iterator<Item = &Type> {
    method children_mut (line 1159) | pub fn children_mut(&mut self) -> impl Iterator<Item = &mut Type> {
  type Rule (line 125) | pub struct Rule {
    method arity (line 1083) | pub fn arity(&self) -> usize {
  type Term (line 131) | pub enum Term {
    method lam (line 493) | pub fn lam(pat: Pattern, bod: Term) -> Self {
    method tagged_lam (line 498) | pub fn tagged_lam(tag: Tag, pat: Pattern, bod: Term) -> Self {
    method rfold_lams (line 505) | pub fn rfold_lams(term: Term, pats: impl DoubleEndedIterator<Item = Op...
    method var_or_era (line 509) | pub fn var_or_era(nam: Option<Name>) -> Self {
    method app (line 517) | pub fn app(fun: Term, arg: Term) -> Self {
    method tagged_app (line 521) | pub fn tagged_app(tag: Tag, fun: Term, arg: Term) -> Self {
    method call (line 526) | pub fn call(called: Term, args: impl IntoIterator<Item = Term>) -> Self {
    method tagged_call (line 530) | pub fn tagged_call(tag: Tag, called: Term, args: impl IntoIterator<Ite...
    method arg_call (line 535) | pub fn arg_call(fun: Term, arg: Name) -> Self {
    method r#ref (line 539) | pub fn r#ref(name: &str) -> Self {
    method str (line 543) | pub fn str(str: &str) -> Self {
    method sub_num (line 547) | pub fn sub_num(arg: Term, val: Num) -> Term {
    method add_num (line 555) | pub fn add_num(arg: Term, val: Num) -> Term {
    method pattern (line 563) | pub fn pattern(&self) -> Option<&Pattern> {
    method pattern_mut (line 570) | pub fn pattern_mut(&mut self) -> Option<&mut Pattern> {
    method children (line 578) | pub fn children(&self) -> impl DoubleEndedIterator<Item = &Term> + Clo...
    method children_mut (line 614) | pub fn children_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut...
    method children_with_binds (line 658) | pub fn children_with_binds(
    method children_mut_with_binds (line 720) | pub fn children_mut_with_binds(
    method subst (line 794) | pub fn subst(&mut self, from: &Name, to: &Term) {
    method subst_ctrs (line 811) | pub fn subst_ctrs(&mut self, from: &Name, to: &Name) {
    method subst_type_ctrs (line 838) | pub fn subst_type_ctrs(&mut self, from: &Name, to: &Name) {
    method subst_unscoped (line 858) | pub fn subst_unscoped(&mut self, from: &Name, to: &Term) {
    method free_vars (line 876) | pub fn free_vars(&self) -> IndexMap<Name, u64> {
    method unscoped_vars (line 902) | pub fn unscoped_vars(&self) -> (IndexSet<Name>, IndexSet<Name>) {
    method has_unscoped (line 935) | pub fn has_unscoped(&self) -> bool {
  type MatchRule (line 239) | pub type MatchRule = (Option<Name>, Vec<Option<Name>>, Term);
  type FanKind (line 242) | pub enum FanKind {
  type Op (line 248) | pub enum Op {
  type Num (line 272) | pub enum Num {
    method is_zero (line 954) | pub fn is_zero(&self) -> bool {
    method to_bits (line 962) | pub fn to_bits(&self) -> u32 {
    method from_bits (line 970) | pub fn from_bits(bits: u32) -> Self {
  type Pattern (line 279) | pub enum Pattern {
    method from (line 484) | fn from(value: Option<Name>) -> Self {
    method binds (line 995) | pub fn binds(&self) -> impl DoubleEndedIterator<Item = &Option<Name>> ...
    method binds_mut (line 1002) | pub fn binds_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Op...
    method children (line 1017) | pub fn children(&self) -> impl DoubleEndedIterator<Item = &Pattern> + ...
    method children_mut (line 1025) | pub fn children_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut...
    method iter (line 1035) | pub fn iter(&self) -> impl DoubleEndedIterator<Item = &Pattern> + Clone {
    method is_wildcard (line 1045) | pub fn is_wildcard(&self) -> bool {
    method to_term (line 1049) | pub fn to_term(&self) -> Term {
    method has_unscoped (line 1064) | pub fn has_unscoped(&self) -> bool {
    method has_nested (line 1072) | pub fn has_nested(&self) -> bool {
  type Tag (line 291) | pub enum Tag {
    method adt_name (line 385) | pub fn adt_name(name: &Name) -> Self {
  type Adt (line 301) | pub struct Adt {
  type AdtCtr (line 309) | pub struct AdtCtr {
  type CtrField (line 316) | pub struct CtrField {
  type Name (line 323) | pub struct Name(GlobalString);
    method eq (line 328) | fn eq(&self, other: &str) -> bool {
    method eq (line 334) | fn eq(&self, other: &&str) -> bool {
    method eq (line 340) | fn eq(&self, other: &Option<Name>) -> bool {
    method eq (line 356) | fn eq(&self, other: &Option<&Name>) -> bool {
    method new (line 1173) | pub fn new<'a, V: Into<Cow<'a, str>>>(value: V) -> Name {
    method is_generated (line 1177) | pub fn is_generated(&self) -> bool {
    method def_name_from_generated (line 1182) | pub fn def_name_from_generated(&self) -> Name {
    method from (line 1200) | fn from(value: u64) -> Self {
    method from (line 1206) | fn from(value: u32) -> Self {
    method as_ref (line 1220) | fn as_ref(&self) -> &str {
  function eq (line 350) | fn eq(&self, other: &Name) -> bool {
  function eq (line 366) | fn eq(&self, other: &Name) -> bool {
  function num_to_name (line 371) | pub fn num_to_name(mut num: u64) -> String {
  method clone (line 391) | fn clone(&self) -> Self {
  method drop (line 448) | fn drop(&mut self) {
  method hash (line 981) | fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
  method eq (line 987) | fn eq(&self, other: &Self) -> bool {
  method default (line 1194) | fn default() -> Self {
  type Target (line 1212) | type Target = str;
  method deref (line 1214) | fn deref(&self) -> &Self::Target {
  method default (line 1252) | fn default() -> Self {
  function num_to_from_bits (line 1258) | fn num_to_from_bits() {

FILE: src/fun/net_to_term.rs
  function net_to_term (line 11) | pub fn net_to_term(
  type Scope (line 62) | type Scope = BTreeSet<NodeId>;
  type Reader (line 64) | pub struct Reader<'a> {
  function read_term (line 80) | fn read_term(&mut self, next: Port) -> Term {
  function read_con (line 108) | fn read_con(&mut self, next: Port, label: Option<BendLab>) -> Term {
  function read_fan (line 143) | fn read_fan(&mut self, next: Port, kind: CtrKind) -> Term {
  function read_opr (line 211) | fn read_opr(&mut self, next: Port) -> Term {
  function read_swi (line 424) | fn read_swi(&mut self, next: Port) -> Term {
  function decay_or_get_ports (line 512) | fn decay_or_get_ports(&mut self, node: NodeId) -> Result<Term, (Term, Te...
  function error (line 540) | pub fn error(&mut self, error: ReadbackError) {
  function report_errors (line 544) | pub fn report_errors(&mut self, diagnostics: &mut Diagnostics) {
  function is_tup (line 566) | fn is_tup(&self, node: NodeId) -> bool {
  function num_from_bits_with_type (line 602) | fn num_from_bits_with_type(val: u32, typ: u32) -> Term {
  type Split (line 616) | struct Split {
  method default (line 625) | fn default() -> Self {
  method insert_split (line 647) | fn insert_split(&mut self, split: &mut Split, threshold: usize) -> Optio...
  type NameGen (line 676) | pub struct NameGen {
    method var_name (line 683) | fn var_name(&mut self, var_port: Port) -> Name {
    method decl_name (line 692) | fn decl_name(&mut self, net: &INet, var_port: Port) -> Option<Name> {
    method unique (line 699) | pub fn unique(&mut self) -> Name {
  type ReadbackError (line 709) | pub enum ReadbackError {
    method hash (line 725) | fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
    method fmt (line 731) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  method eq (line 717) | fn eq(&self, other: &Self) -> bool {
  method collect_unscoped (line 748) | pub fn collect_unscoped(&self, unscoped: &mut HashSet<Name>, scope: &mut...
  method apply_unscoped (line 781) | pub fn apply_unscoped(&mut self, unscoped: &HashSet<Name>) {
  method apply_unscoped (line 799) | fn apply_unscoped(&mut self, unscoped: &HashSet<Name>) {

FILE: src/fun/parser.rs
  type FunDefinition (line 16) | type FunDefinition = super::Definition;
  type ImpDefinition (line 17) | type ImpDefinition = crate::imp::Definition;
  type ParseBook (line 21) | pub struct ParseBook {
    method contains_def (line 45) | pub fn contains_def(&self, name: &Name) -> bool {
    method contains_builtin_def (line 49) | pub fn contains_builtin_def(&self, name: &Name) -> Option<bool> {
  type ParseResult (line 59) | pub type ParseResult<T> = std::result::Result<T, ParseError>;
  type FunParser (line 61) | pub struct FunParser<'i> {
  function new (line 69) | pub fn new(file: Name, input: &'a str, builtin: bool) -> Self {
  function parse_book (line 75) | pub fn parse_book(&mut self, default_book: ParseBook) -> ParseResult<Par...
  function parse_type_def (line 192) | fn parse_type_def(&mut self) -> ParseResult<Adt> {
  function parse_type_ctr (line 226) | fn parse_type_ctr(&mut self, type_name: &Name, type_vars: &[Name]) -> Pa...
  function parse_type_ctr_field (line 256) | fn parse_type_ctr_field(&mut self) -> ParseResult<CtrField> {
  function parse_fun_def (line 276) | fn parse_fun_def(&mut self) -> ParseResult<FunDefinition> {
  function parse_def_sig (line 325) | fn parse_def_sig(&mut self) -> ParseResult<(Name, Vec<Name>, bool, Type)> {
  function parse_def_sig_arg (line 347) | fn parse_def_sig_arg(&mut self) -> ParseResult<(Name, Type)> {
  function parse_checked (line 362) | fn parse_checked(&mut self, default: bool) -> bool {
  function parse_from_import (line 372) | fn parse_from_import(&mut self) -> ParseResult<Import> {
  function parse_import (line 400) | fn parse_import(&mut self) -> ParseResult<Vec<Import>> {
  function parse_rule_lhs (line 426) | fn parse_rule_lhs(&mut self) -> ParseResult<(Name, Vec<Pattern>)> {
  function parse_rule (line 447) | fn parse_rule(&mut self) -> ParseResult<(Name, Rule)> {
  function starts_with_rule (line 459) | fn starts_with_rule(&mut self, expected_name: &Name) -> bool {
  function parse_pattern (line 482) | fn parse_pattern(&mut self, simple: bool) -> ParseResult<Pattern> {
  function parse_term (line 576) | pub fn parse_term(&mut self) -> ParseResult<Term> {
  function parse_name_or_era (line 961) | fn parse_name_or_era(&mut self) -> ParseResult<Option<Name>> {
  function parse_tag (line 978) | fn parse_tag(&mut self) -> ParseResult<(Option<Tag>, impl FnOnce(&mut Se...
  function parse_match_arg (line 1001) | fn parse_match_arg(&mut self) -> ParseResult<(Option<Name>, Term)> {
  function parse_named_arg (line 1019) | fn parse_named_arg(&mut self) -> ParseResult<(Option<Name>, Term)> {
  function parse_with_clause (line 1032) | fn parse_with_clause(&mut self) -> ParseResult<(Vec<Option<Name>>, Vec<T...
  function parse_match_arm (line 1043) | fn parse_match_arm(&mut self) -> ParseResult<MatchRule> {
  function parse_type_term (line 1052) | fn parse_type_term(&mut self) -> ParseResult<Type> {
  function parse_type_atom (line 1064) | fn parse_type_atom(&mut self) -> ParseResult<Type> {
  function add_fun_def (line 1121) | fn add_fun_def(&mut self, def: FunDefinition, book: &mut ParseBook, span...
  function add_imp_def (line 1127) | fn add_imp_def(
  function add_hvm (line 1138) | fn add_hvm(&mut self, def: HvmDefinition, book: &mut ParseBook, span: Ra...
  function add_type_def (line 1144) | fn add_type_def(&mut self, adt: Adt, book: &mut ParseBook, span: Range<u...
  function check_top_level_redefinition (line 1163) | fn check_top_level_redefinition(
  function check_type_redefinition (line 1184) | fn check_type_redefinition(
  function input (line 1199) | fn input(&mut self) -> &'a str {
  function index (line 1203) | fn index(&mut self) -> &mut usize {
  function expected (line 1210) | fn expected<T>(&mut self, exp: &str) -> ParseResult<T> {
  function expected_and (line 1219) | fn expected_and<T>(&mut self, exp: &str, msg: &str) -> ParseResult<T> {
  function consume (line 1228) | fn consume(&mut self, text: &str) -> ParseResult<()> {
  function skip_trivia (line 1238) | fn skip_trivia(&mut self) {
  function is_name_char (line 1277) | pub fn is_name_char(c: char) -> bool {
  function is_num_char (line 1281) | pub fn is_num_char(c: char) -> bool {
  function make_fn_type (line 1285) | pub fn make_fn_type(args: Vec<Type>, ret: Type) -> Type {
  function make_ctr_type (line 1289) | pub fn make_ctr_type(type_name: Name, fields: &[Type], vars: &[Name]) ->...
  type Indent (line 1296) | pub enum Indent {
    method new (line 1302) | pub fn new(val: isize) -> Self {
    method enter_level (line 1306) | pub fn enter_level(&mut self) {
    method exit_level (line 1312) | pub fn exit_level(&mut self) {
  type ParserCommons (line 1321) | pub trait ParserCommons<'a>: Parser<'a> {
    method labelled (line 1322) | fn labelled<T>(&mut self, parser: impl Fn(&mut Self) -> ParseResult<T>...
    method parse_restricted_name (line 1329) | fn parse_restricted_name(&mut self, kind: &str) -> ParseResult<Name> {
    method parse_top_level_name (line 1348) | fn parse_top_level_name(&mut self) -> ParseResult<Name> {
    method parse_var_name (line 1352) | fn parse_var_name(&mut self) -> ParseResult<Name> {
    method parse_name_maybe_alias (line 1356) | fn parse_name_maybe_alias(&mut self, label: &str) -> ParseResult<(Name...
    method parse_import_name (line 1368) | fn parse_import_name(&mut self, label: &str) -> ParseResult<(Name, Opt...
    method consume_exactly (line 1375) | fn consume_exactly(&mut self, text: &str) -> ParseResult<()> {
    method consume_new_line (line 1384) | fn consume_new_line(&mut self) -> ParseResult<()> {
    method advance_newlines (line 1391) | fn advance_newlines(&mut self) -> ParseResult<Indent> {
    method advance_trivia_inline (line 1409) | fn advance_trivia_inline(&mut self) -> ParseResult<isize> {
    method skip_trivia_inline (line 1461) | fn skip_trivia_inline(&mut self) -> ParseResult<()> {
    method expected_spanned (line 1466) | fn expected_spanned<T>(&mut self, exp: &str, span: Range<usize>) -> Pa...
    method expected_spanned_and (line 1474) | fn expected_spanned_and<T>(&mut self, exp: &str, msg: &str, span: Rang...
    method err_msg_spanned (line 1485) | fn err_msg_spanned<T>(&mut self, msg: &str, span: Range<usize>) -> Par...
    method with_ctx (line 1493) | fn with_ctx<T>(&mut self, res: Result<T, impl std::fmt::Display>, span...
    method try_consume (line 1502) | fn try_consume(&mut self, text: &str) -> bool {
    method try_consume_exactly (line 1513) | fn try_consume_exactly(&mut self, text: &str) -> bool {
    method try_parse_keyword (line 1522) | fn try_parse_keyword(&mut self, keyword: &str) -> bool {
    method parse_keyword (line 1531) | fn parse_keyword(&mut self, keyword: &str) -> ParseResult<()> {
    method starts_with_keyword (line 1544) | fn starts_with_keyword(&mut self, keyword: &str) -> bool {
    method list_like (line 1563) | fn list_like<T>(
    method try_parse_oper (line 1600) | fn try_parse_oper(&mut self) -> Option<Op> {
    method peek_oper (line 1641) | fn peek_oper(&mut self) -> Option<Op> {
    method parse_u32 (line 1682) | fn parse_u32(&mut self) -> ParseResult<u32> {
    method u32_with_radix (line 1706) | fn u32_with_radix(&mut self, radix: Radix) -> ParseResult<u32> {
    method parse_number (line 1718) | fn parse_number(&mut self) -> ParseResult<Num> {
    method num_range_err (line 1770) | fn num_range_err<T>(&mut self, ini_idx: usize, typ: &str) -> ParseResu...
    method parse_quoted_symbol (line 1778) | fn parse_quoted_symbol(&mut self) -> ParseResult<u32> {
    method check_repeated_ctr_fields (line 1803) | fn check_repeated_ctr_fields(
    method redefinition_of_function_msg (line 1819) | fn redefinition_of_function_msg(builtin: bool, function_name: &str) ->...
    method redefinition_of_hvm_msg (line 1827) | fn redefinition_of_hvm_msg(builtin: bool, function_name: &str) -> Stri...
    method redefinition_of_constructor_msg (line 1835) | fn redefinition_of_constructor_msg(constructor_name: &str) -> String {
    method redefinition_of_type_msg (line 1843) | fn redefinition_of_type_msg(type_name: &str) -> String {
  type Radix (line 1853) | pub enum Radix {
    method to_f32 (line 1860) | fn to_f32(self) -> f32 {
    method fmt (line 1870) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

FILE: src/fun/term_to_net.rs
  type ViciousCycleErr (line 16) | pub struct ViciousCycleErr;
  function book_to_hvm (line 18) | pub fn book_to_hvm(book: &Book, diags: &mut Diagnostics) -> Result<(hvm:...
  function term_to_hvm (line 55) | pub fn term_to_hvm(term: &Term, labels: &mut Labels) -> Result<Net, Stri...
  type EncodeTermState (line 82) | struct EncodeTermState<'t, 'l> {
  function count_nodes (line 92) | fn count_nodes(tree: &Tree) -> usize {
  type Place (line 99) | enum Place<'t> {
  function encode_term (line 111) | fn encode_term(&mut self, term: &'t Term, up: Place<'t>) {
  function encode_le_ge_opers (line 251) | fn encode_le_ge_opers(&mut self, opr: &Op, up: Place<'t>, node: Place<'t...
  function encode_pat (line 265) | fn encode_pat(&mut self, pat: &Pattern, up: Place<'t>) {
  function link (line 278) | fn link(&mut self, a: Place<'t>, b: Place<'t>) {
  function new_ctr (line 305) | fn new_ctr(&mut self, kind: CtrKind) -> (Place<'t>, Place<'t>, Place<'t>) {
  function new_opr (line 321) | fn new_opr(&mut self) -> (Place<'t>, Place<'t>, Place<'t>) {
  function make_node_list (line 332) | fn make_node_list(
  function new_wire (line 348) | fn new_wire(&mut self) -> usize {
  function fan_kind (line 354) | fn fan_kind(&mut self, fan: &FanKind, tag: &crate::fun::Tag) -> CtrKind {
  function link_var (line 363) | fn link_var(&mut self, global: bool, name: &Name, place: Place<'t>) {
  type Labels (line 377) | pub struct Labels {
    type Output (line 391) | type Output = LabelGenerator;
    method index (line 393) | fn index(&self, fan: FanKind) -> &Self::Output {
    method index_mut (line 402) | fn index_mut(&mut self, fan: FanKind) -> &mut Self::Output {
  type LabelGenerator (line 384) | pub struct LabelGenerator {
    method generate (line 413) | fn generate(&mut self, tag: &crate::fun::Tag) -> Option<u16> {
    method to_tag (line 433) | pub fn to_tag(&self, label: Option<u16>) -> crate::fun::Tag {
    method finish (line 450) | fn finish(&mut self) {
  method to_native_tag (line 457) | fn to_native_tag(self) -> hvm::hvm::Tag {
  function flip_sym (line 482) | fn flip_sym(tag: hvm::hvm::Tag) -> hvm::hvm::Tag {

FILE: src/fun/transform/apply_args.rs
  function apply_args (line 17) | pub fn apply_args(&mut self, args: Option<Vec<Term>>) -> Result<(), Diag...

FILE: src/fun/transform/definition_merge.rs
  constant MERGE_SEPARATOR (line 9) | pub const MERGE_SEPARATOR: &str = "__M_";
  method merge_definitions (line 17) | pub fn merge_definitions(&mut self) {
  method merge (line 24) | fn merge(&mut self, defs: impl Iterator<Item = Name>) {
  method collect_terms (line 67) | fn collect_terms(&mut self, def_entries: impl Iterator<Item = Name>) -> ...
  method update_refs (line 79) | fn update_refs(&mut self, name_map: &BTreeMap<Name, Name>) {
  method subst_ref_to_ref (line 97) | pub fn subst_ref_to_ref(term: &mut Term, ref_map: &BTreeMap<Name, Name>)...

FILE: src/fun/transform/definition_pruning.rs
  type Used (line 10) | enum Used {
  type Definitions (line 19) | type Definitions = HashMap<Name, Used>;
  function prune (line 26) | pub fn prune(&mut self, prune_all: bool) {
  method find_used_definitions_from_term (line 113) | fn find_used_definitions_from_term(&self, term: &Term, used: Used, uses:...
  method find_used_definitions_from_hvm_net (line 138) | fn find_used_definitions_from_hvm_net(&self, net: &Net, used: Used, uses...
  method insert_used (line 161) | fn insert_used(&self, def_name: &Name, used: Used, uses: &mut Definition...

FILE: src/fun/transform/desugar_bend.rs
  constant RECURSIVE_KW (line 8) | pub const RECURSIVE_KW: &str = "fork";
  constant NEW_FN_SEP (line 9) | const NEW_FN_SEP: &str = "__bend";
  function desugar_bend (line 12) | pub fn desugar_bend(&mut self) -> Result<(), Diagnostics> {
  method desugar_bend (line 33) | fn desugar_bend(

FILE: src/fun/transform/desugar_fold.rs
  function desugar_fold (line 30) | pub fn desugar_fold(&mut self) -> Result<(), Diagnostics> {
  type DesugarFoldCtx (line 58) | struct DesugarFoldCtx<'a> {
  method desugar_fold (line 69) | fn desugar_fold(&mut self, ctx: &mut DesugarFoldCtx<'_>) -> Result<(), S...
  method call_recursive (line 145) | fn call_recursive(&mut self, def_name: &Name, recursive: &HashSet<Name>,...

FILE: src/fun/transform/desugar_match_defs.rs
  type DesugarMatchDefErr (line 9) | pub enum DesugarMatchDefErr {
    method fmt (line 637) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function desugar_match_defs (line 19) | pub fn desugar_match_defs(&mut self) -> Result<(), Diagnostics> {
  method desugar_match_def (line 50) | pub fn desugar_match_def(&mut self, ctrs: &Constructors, adts: &Adts) ->...
  function desugar_inner_match_defs (line 83) | fn desugar_inner_match_defs(
  function fix_repeated_binds (line 112) | fn fix_repeated_binds(rules: &mut [Rule]) -> Vec<DesugarMatchDefErr> {
  function simplify_rule_match (line 151) | fn simplify_rule_match(
  function irrefutable_fst_row_rule (line 179) | fn irrefutable_fst_row_rule(args: Vec<Name>, rule: Rule, idx: usize, use...
  function var_rule (line 205) | fn var_rule(
  function fan_rule (line 255) | fn fan_rule(
  function num_rule (line 309) | fn num_rule(
  function fast_pred_access (line 422) | fn fast_pred_access(body: &mut Term, cur_num: u32, var: &Name, pred_var:...
  function switch_rule (line 490) | fn switch_rule(
  type Type (line 572) | pub enum Type {
    method infer_from_def_arg (line 585) | fn infer_from_def_arg(
    method fmt (line 625) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  method to_type (line 609) | fn to_type(&self, ctrs: &Constructors) -> Type {

FILE: src/fun/transform/desugar_open.rs
  function desugar_open (line 8) | pub fn desugar_open(&mut self) -> Result<(), Diagnostics> {
  method desugar_open (line 22) | fn desugar_open(&mut self, adts: &Adts) -> Result<(), String> {

FILE: src/fun/transform/desugar_use.rs
  method desugar_use (line 17) | pub fn desugar_use(&mut self) {
  method desugar_ctr_use (line 26) | pub fn desugar_ctr_use(&mut self) {
  method desugar_use (line 36) | pub fn desugar_use(&mut self) {
  method desugar_ctr_use (line 49) | pub fn desugar_ctr_use(&mut self) {

FILE: src/fun/transform/desugar_with_blocks.rs
  function desugar_with_blocks (line 10) | pub fn desugar_with_blocks(&mut self) -> Result<(), Diagnostics> {
  method desugar_with_blocks (line 26) | pub fn desugar_with_blocks(
  method defer (line 70) | fn defer(self) -> Term {

FILE: src/fun/transform/encode_adts.rs
  method encode_adts (line 8) | pub fn encode_adts(&mut self, adt_encoding: AdtEncoding) {
  function encode_ctr_scott (line 39) | fn encode_ctr_scott<'a>(
  function encode_ctr_num_scott (line 50) | fn encode_ctr_num_scott<'a>(ctr_args: impl DoubleEndedIterator<Item = &'...
  function encode_num_scott_tag (line 61) | fn encode_num_scott_tag(tag: u32, ctr_name: &Name, source: Source) -> De...

FILE: src/fun/transform/encode_match_terms.rs
  method encode_matches (line 13) | pub fn encode_matches(&mut self, adt_encoding: AdtEncoding) {
  method encode_matches (line 23) | pub fn encode_matches(&mut self, adt_encoding: AdtEncoding) {
  function encode_match (line 47) | fn encode_match(arg: Term, rules: Vec<MatchRule>, adt_encoding: AdtEncod...
  function encode_switch (line 97) | fn encode_switch(arg: Term, pred: Option<Name>, mut rules: Vec<Term>) ->...

FILE: src/fun/transform/expand_generated.rs
  method expand_generated (line 11) | pub fn expand_generated(&mut self, book: &Book, recursive_defs: &Recursi...
  type DepGraph (line 26) | type DepGraph = HashMap<Name, HashSet<Name>>;
  type Cycles (line 27) | type Cycles = Vec<Vec<Name>>;
  type RecursiveDefs (line 28) | type RecursiveDefs = BTreeSet<Name>;
  method recursive_defs (line 31) | pub fn recursive_defs(&self) -> RecursiveDefs {
  function cycles (line 47) | fn cycles(deps: &DepGraph) -> Cycles {
  function find_cycles (line 59) | fn find_cycles(deps: &DepGraph, nam: &Name, visited: &mut HashSet<Name>,...
  function book_def_deps (line 86) | fn book_def_deps(book: &Book) -> DepGraph {
  function def_deps (line 90) | fn def_deps(def: &crate::fun::Definition) -> HashSet<Name> {

FILE: src/fun/transform/expand_main.rs
  method expand_main (line 10) | pub fn expand_main(&mut self) {
  method expand_ref_return (line 38) | fn expand_ref_return(&mut self, book: &Book, seen: &mut Vec<Name>, globa...
  method expand_floated_combinators (line 104) | fn expand_floated_combinators(&mut self, book: &Book) {
  method multi_arg_app (line 118) | fn multi_arg_app(&mut self) -> (&mut Term, Vec<&mut Term>) {
  method rename_unscoped (line 138) | fn rename_unscoped(&mut self, unscoped_count: &mut usize, unscoped_map: ...
  method rename_unscoped (line 153) | fn rename_unscoped(&mut self, unscoped_count: &mut usize, unscoped_map: ...
  function rename_unscoped (line 169) | fn rename_unscoped(nam: &mut Name, unscoped_count: &mut usize, unscoped_...

FILE: src/fun/transform/fix_match_defs.rs
  function fix_match_defs (line 10) | pub fn fix_match_defs(&mut self) -> Result<(), Diagnostics> {
  method fix_match_defs (line 29) | fn fix_match_defs(&mut self, def_arity: usize, ctrs: &Constructors, adts...
  method fix_match_defs (line 48) | fn fix_match_defs(&mut self, ctrs: &Constructors, adts: &Adts, errs: &mu...
  method resolve_pat (line 68) | fn resolve_pat(&mut self, ctrs: &Constructors) {
  method check_good_ctr (line 80) | fn check_good_ctr(&self, ctrs: &Constructors, adts: &Adts, errs: &mut Ve...

FILE: src/fun/transform/fix_match_terms.rs
  type FixMatchErr (line 8) | enum FixMatchErr {
    method fmt (line 281) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function fix_match_terms (line 48) | pub fn fix_match_terms(&mut self) -> Result<(), Diagnostics> {
  method fix_match_terms (line 86) | fn fix_match_terms(&mut self, ctrs: &Constructors, adts: &Adts) -> Vec<F...
  method fix_match (line 145) | fn fix_match(&mut self, errs: &mut Vec<FixMatchErr>, ctrs: &Constructors...
  function fixed_match_arms (line 214) | fn fixed_match_arms<'a>(
  function match_field (line 270) | fn match_field(arg: &Name, field: &Name) -> Name {
  function rebuild_ctr (line 274) | fn rebuild_ctr(arg: &Name, ctr: &Name, fields: &[CtrField]) -> Term {

FILE: src/fun/transform/float_combinators.rs
  constant NAME_SEP (line 7) | pub const NAME_SEP: &str = "__C";
  method float_combinators (line 33) | pub fn float_combinators(&mut self, max_size: usize) {
  type FloatCombinatorsCtx (line 59) | struct FloatCombinatorsCtx<'b> {
  function new (line 69) | fn new(book: &'b Book, max_size: usize) -> Self {
  function reset (line 80) | fn reset(&mut self) {
  method float_combinators (line 88) | fn float_combinators(
  method float (line 121) | fn float(
  method is_safe (line 150) | fn is_safe(&self, ctx: &mut FloatCombinatorsCtx) -> bool {
  method is_safe_lambda (line 192) | fn is_safe_lambda(&self, ctx: &mut FloatCombinatorsCtx) -> bool {
  method has_unscoped_diff (line 208) | pub fn has_unscoped_diff(&self) -> bool {
  method is_combinator (line 213) | fn is_combinator(&self) -> bool {
  method base_size (line 217) | fn base_size(&self) -> usize {
  method size (line 245) | fn size(&self) -> usize {
  method float_children_mut (line 252) | pub fn float_children_mut(&mut self) -> impl Iterator<Item = &mut Term> {
  method size (line 299) | fn size(&self) -> usize {

FILE: src/fun/transform/lift_local_defs.rs
  method lift_local_defs (line 11) | pub fn lift_local_defs(&mut self) {
  method binds (line 24) | pub fn binds(&self) -> impl DoubleEndedIterator<Item = &Option<Name>> + ...
  method lift_local_defs (line 30) | pub fn lift_local_defs(
  function gen_use (line 67) | fn gen_use(
  function apply_closure (line 101) | fn apply_closure(rules: &mut [Rule], fvs: &BTreeSet<Name>) {

FILE: src/fun/transform/linearize_matches.rs
  method linearize_match_binds (line 26) | pub fn linearize_match_binds(&mut self) {
  method linearize_match_binds (line 38) | pub fn linearize_match_binds(&mut self) {
  method linearize_match_binds_go (line 42) | fn linearize_match_binds_go(&mut self, mut bind_terms: Vec<Term>) {
  method linearize_binds_single_match (line 83) | fn linearize_binds_single_match(&mut self, mut bind_terms: Vec<Term>) {
  method wrap_with_bind_terms (line 163) | fn wrap_with_bind_terms(
  function fixed_and_linearized_terms (line 207) | fn fixed_and_linearized_terms(used_in_arg: HashSet<Name>, bind_terms: Ve...
  function binds_fixed_by_dependency (line 235) | fn binds_fixed_by_dependency(used_in_arg: HashSet<Name>, bind_terms: &[T...
  function update_with_clause (line 341) | fn update_with_clause(
  method linearize_matches (line 363) | pub fn linearize_matches(&mut self) {
  method linearize_matches (line 373) | fn linearize_matches(&mut self) {
  function lift_match_vars (line 393) | pub fn lift_match_vars(match_term: &mut Term) -> &mut Term {
  function get_match_reference (line 463) | fn get_match_reference(mut match_term: &mut Term) -> &mut Term {
  method linearize_match_with (line 477) | pub fn linearize_match_with(&mut self) {
  method linearize_match_with (line 487) | fn linearize_match_with(&mut self) {

FILE: src/fun/transform/linearize_vars.rs
  method linearize_vars (line 20) | pub fn linearize_vars(&mut self) {
  method linearize_vars (line 28) | pub fn linearize_vars(&mut self) {
  function term_to_linear (line 33) | fn term_to_linear(term: &mut Term, var_uses: &mut HashMap<Name, u64>) {
  function get_var_uses (line 95) | fn get_var_uses(nam: Option<&Name>, var_uses: &HashMap<Name, u64>) -> u64 {
  function duplicate_pat (line 99) | fn duplicate_pat(nam: &Name, uses: u64) -> Box<Pattern> {
  function dup_name (line 107) | fn dup_name(nam: &Name, uses: u64) -> Name {
  method children_mut_with_binds_mut (line 118) | pub fn children_mut_with_binds_mut(

FILE: src/fun/transform/resolve_refs.rs
  type ReferencedMainErr (line 9) | pub struct ReferencedMainErr;
  function resolve_refs (line 20) | pub fn resolve_refs(&mut self) -> Result<(), Diagnostics> {
  method resolve_refs (line 42) | pub fn resolve_refs<'a>(
  function push_scope (line 96) | fn push_scope<'a>(name: Option<&'a Name>, scope: &mut HashMap<&'a Name, ...
  function pop_scope (line 103) | fn pop_scope<'a>(name: Option<&'a Name>, scope: &mut HashMap<&'a Name, u...
  function is_var_in_scope (line 110) | fn is_var_in_scope<'a>(name: &'a Name, scope: &HashMap<&'a Name, usize>)...

FILE: src/fun/transform/resolve_type_ctrs.rs
  function resolve_type_ctrs (line 9) | pub fn resolve_type_ctrs(&mut self) -> Result<(), Diagnostics> {
  method resolve_type_ctrs (line 33) | pub fn resolve_type_ctrs(&mut self, adts: &Adts) -> Result<(), String> {

FILE: src/fun/transform/resugar_list.rs
  method resugar_lists (line 8) | pub fn resugar_lists(&mut self, adt_encoding: AdtEncoding) {
  method resugar_lists_num_scott (line 16) | fn resugar_lists_num_scott(&mut self) {
  method resugar_lists_scott (line 80) | fn resugar_lists_scott(&mut self) {
  function build_list_num_scott (line 147) | fn build_list_num_scott(term: &mut Term, mut l: Vec<Box<Term>>) -> Resul...
  function build_list_scott (line 209) | fn build_list_scott(term: &mut Term, mut l: Vec<Box<Term>>) -> Result<Ve...

FILE: src/fun/transform/resugar_string.rs
  method resugar_strings (line 8) | pub fn resugar_strings(&mut self, adt_encoding: AdtEncoding) {
  method try_resugar_strings_with (line 16) | fn try_resugar_strings_with(&mut self, extract_fn: fn(&Term) -> Option<(...
  method try_resugar_strings_nil (line 28) | fn try_resugar_strings_nil(&mut self) -> bool {
  method try_resugar_strings_cons (line 33) | fn try_resugar_strings_cons(&mut self, extract_fn: fn(&Term) -> Option<(...
  method try_resugar_strings_cons_with (line 42) | fn try_resugar_strings_cons_with(&self, extract_fn: fn(&Term) -> Option<...
  method try_resugar_strings_cons_common (line 48) | fn try_resugar_strings_cons_common(&self) -> Option<String> {
  method build_strings_common (line 65) | fn build_strings_common(
  method resugar_strings_scott (line 89) | fn resugar_strings_scott(term: &Term) -> Option<(char, &Term)> {
  method resugar_strings_num_scott (line 115) | fn resugar_strings_num_scott(term: &Term) -> Option<(char, &Term)> {
  method extract_strings_common (line 142) | fn extract_strings_common(term: &Term) -> Option<(char, &Term)> {

FILE: src/fun/transform/unique_names.rs
  method make_var_names_unique (line 13) | pub fn make_var_names_unique(&mut self) {
  method make_var_names_unique (line 21) | pub fn make_var_names_unique(&mut self) {
  type VarId (line 26) | type VarId = u64;
  type UniqueNameGenerator (line 29) | pub struct UniqueNameGenerator {
    method unique_names_in_term (line 36) | pub fn unique_names_in_term(&mut self, term: &mut Term) {
    method push (line 169) | fn push(&mut self, nam: Option<&Name>) {
    method pop (line 180) | fn pop(&mut self, nam: Option<&Name>) -> Option<Name> {
    method use_var (line 192) | fn use_var(&self, nam: &Name) -> Name {

FILE: src/hvm/add_recursive_priority.rs
  function add_recursive_priority (line 6) | pub fn add_recursive_priority(book: &mut Book) {
  function add_priority_next_in_cycle (line 23) | fn add_priority_next_in_cycle(net: &mut Net, nxt: &String) {
  type DepGraph (line 57) | type DepGraph = HashMap<String, HashSet<String>>;
  type Cycles (line 58) | type Cycles = Vec<Vec<String>>;
  function cycles (line 61) | pub fn cycles(deps: &DepGraph) -> Cycles {
  function find_cycles (line 73) | fn find_cycles(
  function dependencies (line 104) | fn dependencies(net: &Net) -> HashSet<String> {
  function dependencies_tree (line 114) | fn dependencies_tree(tree: &Tree, deps: &mut HashSet<String>) {

FILE: src/hvm/check_net_size.rs
  constant MAX_NET_SIZE_C (line 5) | pub const MAX_NET_SIZE_C: usize = 4095;
  constant MAX_NET_SIZE_CUDA (line 6) | pub const MAX_NET_SIZE_CUDA: usize = 64;
  function check_net_sizes (line 8) | pub fn check_net_sizes(
  function count_nodes (line 32) | pub fn count_nodes(net: &Net) -> usize {

FILE: src/hvm/eta_reduce.rs
  function eta_reduce_hvm_net (line 64) | pub fn eta_reduce_hvm_net(net: &mut Net) {
  type NodeType (line 76) | enum NodeType {
  type Phase1 (line 85) | struct Phase1<'a> {
  function walk_tree (line 91) | fn walk_tree(&mut self, tree: &'a Tree) {
  type Phase2 (line 124) | struct Phase2 {
    method reduce_ctr (line 130) | fn reduce_ctr(&mut self, tree: &mut Tree, idx: usize) -> NodeType {
    method reduce_tree (line 156) | fn reduce_tree(&mut self, tree: &mut Tree) -> NodeType {

FILE: src/hvm/inline.rs
  function inline_hvm_book (line 7) | pub fn inline_hvm_book(book: &mut Book) -> Result<HashSet<String>, Strin...
  type InlineState (line 24) | struct InlineState {
    method populate_inlinees (line 29) | fn populate_inlinees(&mut self, book: &Book) -> Result<(), String> {
    method inline_into (line 58) | fn inline_into(&self, tree: &mut Tree) -> bool {
  function should_inline (line 73) | fn should_inline(net: &Net) -> bool {

FILE: src/hvm/mod.rs
  function tree_children (line 11) | pub fn tree_children(tree: &Tree) -> impl DoubleEndedIterator<Item = &Tr...
  function tree_children_mut (line 21) | pub fn tree_children_mut(tree: &mut Tree) -> impl DoubleEndedIterator<It...
  function net_trees (line 31) | pub fn net_trees(net: &Net) -> impl DoubleEndedIterator<Item = &Tree> + ...
  function net_trees_mut (line 35) | pub fn net_trees_mut(net: &mut Net) -> impl DoubleEndedIterator<Item = &...
  function hvm_book_show_pretty (line 39) | pub fn hvm_book_show_pretty(book: &hvm::ast::Book) -> String {

FILE: src/hvm/mutual_recursion.rs
  type Ref (line 11) | type Ref = String;
  type Stack (line 12) | type Stack<T> = Vec<T>;
  type RefSet (line 13) | type RefSet = IndexSet<Ref>;
  type Graph (line 16) | pub struct Graph(IndexMap<Ref, RefSet>);
    method cycles (line 60) | pub fn cycles(&self) -> Vec<Vec<Ref>> {
    method find_cycles (line 74) | fn find_cycles(
    method from (line 120) | fn from(book: &Book) -> Self {
    method new (line 143) | pub fn new() -> Self {
    method add (line 147) | pub fn add(&mut self, r#ref: Ref, dependency: Ref) {
    method get (line 152) | pub fn get(&self, r#ref: &Ref) -> Option<&RefSet> {
  function check_cycles (line 18) | pub fn check_cycles(book: &Book, diagnostics: &mut Diagnostics) -> Resul...
  function show_cycles (line 29) | fn show_cycles(mut cycles: Vec<Vec<Ref>>) -> String {
  function collect_refs (line 107) | fn collect_refs(current: Ref, tree: &Tree, graph: &mut Graph) {
  method fmt (line 158) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function combinations_from_merges (line 163) | fn combinations_from_merges(cycle: Vec<Ref>) -> Vec<Vec<Ref>> {

FILE: src/hvm/prune.rs
  function prune_hvm_book (line 6) | pub fn prune_hvm_book(book: &mut Book, entrypoints: &[String]) {
  type PruneState (line 17) | struct PruneState<'a> {
  function visit_def (line 23) | fn visit_def(&mut self, name: &str) {
  function visit_tree (line 30) | fn visit_tree(&mut self, tree: &Tree) {

FILE: src/imp/gen_map_get.rs
  method gen_map_get (line 10) | pub fn gen_map_get(&mut self) {
  method gen_map_get (line 16) | fn gen_map_get(&mut self, id: &mut usize) {
  type Substitutions (line 149) | type Substitutions = Vec<(Name, Name, Box<Expr>)>;
  method substitute_map_gets (line 152) | fn substitute_map_gets(&mut self, id: &mut usize) -> Substitutions {
  function gen_get (line 215) | fn gen_get(current: &mut Stmt, substitutions: Substitutions) -> Stmt {
  function gen_map_var (line 230) | fn gen_map_var(id: &mut usize) -> Name {

FILE: src/imp/mod.rs
  type Expr (line 10) | pub enum Expr {
  type MatchArm (line 48) | pub struct MatchArm {
  type AssignPattern (line 54) | pub enum AssignPattern {
  type InPlaceOp (line 71) | pub enum InPlaceOp {
    method to_lang_op (line 215) | pub fn to_lang_op(self) -> Op {
  type Stmt (line 83) | pub enum Stmt {
  type Definition (line 205) | pub struct Definition {

FILE: src/imp/order_kwargs.rs
  method order_kwargs (line 10) | pub fn order_kwargs(&mut self, book: &ParseBook) -> Result<(), String> {
  method order_kwargs (line 17) | fn order_kwargs(&mut self, book: &ParseBook, use_map: &mut IndexMap<Name...
  method order_kwargs (line 112) | fn order_kwargs(&mut self, book: &ParseBook, use_map: &mut IndexMap<Name...
  function go_order_kwargs (line 188) | fn go_order_kwargs(
  function get_args_def_or_ctr (line 213) | fn get_args_def_or_ctr(name: &Name, book: &ParseBook, use_map: &IndexMap...

FILE: src/imp/parser.rs
  type ImpParser (line 11) | pub struct ImpParser<'i> {
  function new (line 19) | pub fn new(file: Name, input: &'a str, builtin: bool) -> Self {
  function parse_function_def (line 23) | pub fn parse_function_def(&mut self, indent: Indent) -> ParseResult<(Def...
  function parse_type_def (line 37) | pub fn parse_type_def(&mut self, mut indent: Indent) -> ParseResult<(Adt...
  function parse_object (line 81) | pub fn parse_object(&mut self, indent: Indent) -> ParseResult<(Adt, Inde...
  function parse_hvm (line 127) | pub fn parse_hvm(&mut self) -> ParseResult<(HvmDefinition, Indent)> {
  function parse_type_def_variant (line 155) | fn parse_type_def_variant(&mut self, type_name: &Name, type_vars: &[Name...
  function parse_variant_field (line 174) | fn parse_variant_field(&mut self) -> ParseResult<CtrField> {
  function parse_primary_expr (line 186) | fn parse_primary_expr(&mut self, inline: bool) -> ParseResult<Expr> {
  function call_or_postfix (line 252) | fn call_or_postfix(&mut self, inline: bool) -> ParseResult<Expr> {
  function parse_map_or_sup (line 322) | fn parse_map_or_sup(&mut self) -> ParseResult<Expr> {
  function parse_map_init (line 339) | fn parse_map_init(&mut self, head: Expr) -> ParseResult<Expr> {
  function parse_sup (line 352) | fn parse_sup(&mut self, head: Expr) -> ParseResult<Expr> {
  function parse_tree_node (line 359) | fn parse_tree_node(&mut self) -> ParseResult<Expr> {
  function parse_tree_leaf (line 369) | fn parse_tree_leaf(&mut self, inline: bool) -> ParseResult<Expr> {
  function data_kwarg (line 375) | fn data_kwarg(&mut self) -> ParseResult<(Name, Expr)> {
  function parse_map_entry (line 383) | fn parse_map_entry(&mut self) -> ParseResult<(Expr, Expr)> {
  function parse_list_or_comprehension (line 390) | fn parse_list_or_comprehension(&mut self) -> ParseResult<Expr> {
  function parse_expr (line 431) | fn parse_expr(&mut self, inline: bool, tup: bool) -> ParseResult<Expr> {
  function parse_named_arg (line 472) | fn parse_named_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
  function parse_infix_expr (line 491) | fn parse_infix_expr(&mut self, prec: usize, inline: bool) -> ParseResult...
  function consume_indent_at_most (line 521) | fn consume_indent_at_most(&mut self, expected: Indent) -> ParseResult<In...
  function consume_indent_exactly (line 530) | fn consume_indent_exactly(&mut self, expected: Indent) -> ParseResult<()> {
  function parse_statement (line 540) | fn parse_statement(&mut self, indent: &mut Indent) -> ParseResult<(Stmt,...
  function parse_assign (line 572) | fn parse_assign(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, In...
  function parse_in_place_op (line 633) | fn parse_in_place_op(&mut self) -> ParseResult<Option<InPlaceOp>> {
  function parse_return (line 665) | fn parse_return(&mut self) -> ParseResult<(Stmt, Indent)> {
  function parse_if (line 680) | fn parse_if(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent...
  function parse_match (line 746) | fn parse_match(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Ind...
  function parse_match_arg (line 776) | fn parse_match_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
  function parse_with_clause (line 793) | fn parse_with_clause(&mut self) -> ParseResult<(Vec<Option<Name>>, Vec<E...
  function parse_with_arg (line 804) | fn parse_with_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
  function parse_match_case (line 815) | fn parse_match_case(&mut self, indent: &mut Indent) -> ParseResult<(Matc...
  function parse_switch (line 837) | fn parse_switch(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, In...
  function parse_switch_case (line 888) | fn parse_switch_case(&mut self, indent: &mut Indent) -> ParseResult<(Opt...
  function parse_fold (line 918) | fn parse_fold(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Inde...
  function parse_bend (line 955) | fn parse_bend(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Inde...
  function parse_with (line 1022) | fn parse_with(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Inde...
  function parse_assign_pattern (line 1050) | fn parse_assign_pattern(&mut self) -> ParseResult<AssignPattern> {
  function parse_primary_assign_pattern (line 1082) | fn parse_primary_assign_pattern(&mut self) -> ParseResult<AssignPattern> {
  function parse_open (line 1105) | fn parse_open(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Inde...
  function parse_use (line 1128) | fn parse_use(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Inden...
  function parse_local_def (line 1151) | fn parse_local_def(&mut self, indent: &mut Indent) -> ParseResult<(Stmt,...
  function parse_type_expr (line 1161) | fn parse_type_expr(&mut self) -> ParseResult<Type> {
  function parse_def_aux (line 1233) | fn parse_def_aux(&mut self, mut indent: Indent) -> ParseResult<(Definiti...
  function parse_def_arg (line 1286) | fn parse_def_arg(&mut self) -> ParseResult<(Name, Option<Type>)> {
  function parse_return_type (line 1297) | fn parse_return_type(&mut self) -> ParseResult<Option<Type>> {
  function expected_indent (line 1305) | fn expected_indent<T>(&mut self, expected: Indent, got: Indent) -> Parse...
  function input (line 1334) | fn input(&mut self) -> &'a str {
  function index (line 1338) | fn index(&mut self) -> &mut usize {
  function expected (line 1345) | fn expected<T>(&mut self, exp: &str) -> ParseResult<T> {
  function consume (line 1354) | fn consume(&mut self, text: &str) -> ParseResult<()> {
  function skip_trivia (line 1364) | fn skip_trivia(&mut self) {
  method precedence (line 1387) | fn precedence(&self) -> usize {
  method max_precedence (line 1409) | fn max_precedence() -> usize {

FILE: src/imp/to_fun.rs
  method to_fun (line 14) | pub fn to_fun(mut self) -> Result<Book, Diagnostics> {
  method to_fun (line 32) | pub fn to_fun(self) -> Result<fun::Definition, Diagnostics> {
  method into_fun (line 67) | pub fn into_fun(self) -> fun::Pattern {
  type StmtToFun (line 86) | enum StmtToFun {
  function take (line 91) | fn take(t: Stmt) -> Result<(bool, Option<fun::Pattern>, fun::Term), Stri...
  function wrap (line 98) | fn wrap(nxt: Option<fun::Pattern>, term: fun::Term, ask: bool) -> StmtTo...
  method into_fun (line 107) | fn into_fun(self) -> Result<StmtToFun, String> {
  method to_fun (line 375) | pub fn to_fun(self) -> fun::Term {
  function map_init (line 463) | fn map_init(entries: Vec<(Expr, Expr)>) -> fun::Term {
  function wrap_nxt_assign_stmt (line 474) | fn wrap_nxt_assign_stmt(

FILE: src/imports/book.rs
  method load_imports (line 28) | pub fn load_imports(
  method apply_imports (line 55) | fn apply_imports(
  method load_packages (line 68) | fn load_packages(
  method apply_import_binds (line 116) | fn apply_import_binds(&mut self, main_imports: Option<&ImportsMap>, pkgs...
  method apply_adts (line 165) | fn apply_adts(&mut self, src: &Name, main_imports: &ImportsMap) {
  method apply_defs (line 234) | fn apply_defs(&mut self, src: &Name, main_imports: &ImportsMap) {
  method top_level_names (line 253) | pub fn top_level_names(&self) -> impl Iterator<Item = &Name> {
  method add_imported_adt (line 263) | fn add_imported_adt(&mut self, nam: Name, adt: Adt, diag: &mut Diagnosti...
  method add_imported_def (line 286) | fn add_imported_def(&mut self, def: Definition, diag: &mut Diagnostics) {
  method add_imported_hvm_def (line 292) | fn add_imported_hvm_def(&mut self, def: HvmDefinition, diag: &mut Diagno...
  method has_def_conflict (line 298) | fn has_def_conflict(&mut self, name: &Name, diag: &mut Diagnostics) -> b...
  method local_defs_mut (line 312) | fn local_defs_mut(&mut self) -> impl Iterator<Item = (&Name, &mut dyn De...
  type Def (line 321) | trait Def {
    method canonicalize_name (line 322) | fn canonicalize_name(&mut self, src: &Name, main_imports: &ImportsMap,...
    method apply_binds (line 338) | fn apply_binds(&mut self, maybe_constructor: bool, binds: &BindMap);
    method apply_type_binds (line 340) | fn apply_type_binds(&mut self, binds: &BindMap);
    method source (line 342) | fn source(&self) -> &Source;
    method source_mut (line 343) | fn source_mut(&mut self) -> &mut Source;
    method name_mut (line 344) | fn name_mut(&mut self) -> &mut Name;
    method apply_binds (line 348) | fn apply_binds(&mut self, maybe_constructor: bool, binds: &BindMap) {
    method apply_type_binds (line 379) | fn apply_type_binds(&mut self, binds: &BindMap) {
    method source (line 388) | fn source(&self) -> &Source {
    method source_mut (line 392) | fn source_mut(&mut self) -> &mut Source {
    method name_mut (line 396) | fn name_mut(&mut self) -> &mut Name {
    method apply_binds (line 402) | fn apply_binds(&mut self, _maybe_constructor: bool, binds: &BindMap) {
    method apply_type_binds (line 407) | fn apply_type_binds(&mut self, binds: &BindMap) {
    method source (line 493) | fn source(&self) -> &Source {
    method source_mut (line 497) | fn source_mut(&mut self) -> &mut Source {
    method name_mut (line 501) | fn name_mut(&mut self) -> &mut Name {
    method apply_binds (line 508) | fn apply_binds(&mut self, _maybe_constructor: bool, _binds: &BindMap) {}
    method apply_type_binds (line 510) | fn apply_type_binds(&mut self, binds: &BindMap) {
    method source (line 516) | fn source(&self) -> &Source {
    method source_mut (line 520) | fn source_mut(&mut self) -> &mut Source {
    method name_mut (line 524) | fn name_mut(&mut self) -> &mut Name {
    method canonicalize_name (line 528) | fn canonicalize_name(&mut self, src: &Name, main_imports: &ImportsMap,...
  method fold_uses (line 542) | fn fold_uses<'a>(self, map: impl Iterator<Item = (&'a Name, &'a Name)>) ...
  method fold_uses (line 552) | fn fold_uses<'a>(self, map: impl Iterator<Item = (&'a Name, &'a Name)>) ...

FILE: src/imports/loader.rs
  type Sources (line 9) | pub type Sources = IndexMap<Name, String>;
  type PackageLoader (line 12) | pub trait PackageLoader {
    method load (line 36) | fn load(&mut self, import: &mut Import) -> Result<Sources, String>;
    method load (line 156) | fn load(&mut self, import: &mut Import) -> Result<Sources, String> {
  type DefaultLoader (line 40) | pub struct DefaultLoader {
    method new (line 47) | pub fn new(local_path: &Path) -> Self {
    method read_file (line 53) | fn read_file(&mut self, path: &Path, file_path: &str, src: &mut Source...
    method read_file_in_folder (line 72) | fn read_file_in_folder(
    method read_path (line 89) | fn read_path(
    method is_loaded (line 148) | fn is_loaded(&self, name: &Name) -> bool {
  constant BEND_PATH (line 153) | pub const BEND_PATH: &[&str] = &[""];
  function normalize_path (line 184) | pub fn normalize_path(path: &Path) -> PathBuf {

FILE: src/imports/mod.rs
  type BindMap (line 15) | pub type BindMap = IndexMap<Name, Name>;
  type ImportCtx (line 18) | pub struct ImportCtx {
    method add_import (line 27) | pub fn add_import(&mut self, import: Import) {
    method to_imports (line 31) | pub fn to_imports(self) -> Vec<Import> {
    method sources (line 35) | pub fn sources(&self) -> Vec<&Name> {
  type Import (line 50) | pub struct Import {
    method new (line 58) | pub fn new(path: Name, imp_type: ImportType, relative: bool) -> Self {
  type ImportType (line 64) | pub enum ImportType {
  method fmt (line 71) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type BoundSource (line 81) | pub enum BoundSource {
  type ImportsMap (line 90) | struct ImportsMap {
    method contains_source (line 95) | pub fn contains_source(&self, s: &Name) -> bool {
    method add_bind (line 99) | fn add_bind(&mut self, src: &str, bind: Name, diag: &mut Diagnostics) {
    method add_aliased_bind (line 108) | fn add_aliased_bind(&mut self, src: &Name, sub: &Name, alias: Option<&...
    method add_binds (line 114) | fn add_binds(&mut self, names: &IndexSet<Name>, src: &Name, diag: &mut...
    method add_file_nested_binds (line 122) | fn add_file_nested_binds(
    method add_nested_binds (line 141) | fn add_nested_binds<'a>(

FILE: src/imports/packages.rs
  type Packages (line 10) | pub struct Packages {
    method new (line 21) | pub fn new(book: ParseBook) -> Self {
    method load_imports (line 31) | pub fn load_imports(
    method load_imports_go (line 54) | fn load_imports_go(
    method load_binds (line 91) | fn load_binds(&mut self, idx: usize, diag: &mut Diagnostics) {
    method add_aliased_bind (line 209) | fn add_aliased_bind(
    method add_file_from_dir (line 227) | fn add_file_from_dir(
    method add_glob_from_dir (line 244) | fn add_glob_from_dir(&self, pkgs: &IndexMap<Name, Name>, map: &mut Imp...
    method unique_top_level_names (line 251) | fn unique_top_level_names(&self, src: &Name) -> IndexSet<Name> {

FILE: src/lib.rs
  constant ENTRY_POINT (line 28) | pub const ENTRY_POINT: &str = "main";
  constant HVM1_ENTRY_POINT (line 29) | pub const HVM1_ENTRY_POINT: &str = "Main";
  constant HVM_OUTPUT_END_MARKER (line 30) | pub const HVM_OUTPUT_END_MARKER: &str = "Result: ";
  function check_book (line 32) | pub fn check_book(
  function compile_book (line 42) | pub fn compile_book(
  function desugar_book (line 83) | pub fn desugar_book(
  function type_check_book (line 172) | pub fn type_check_book(ctx: &mut Ctx) -> Result<(), Diagnostics> {
  function run_book (line 179) | pub fn run_book(
  function readback_hvm_net (line 203) | pub fn readback_hvm_net(
  function run_hvm (line 222) | fn run_hvm(book: &::hvm::ast::Book, cmd: &str, run_opts: &RunOpts) -> Re...
  function parse_hvm_output (line 246) | fn parse_hvm_output(out: &str) -> Result<(::hvm::ast::Net, String), Stri...
  function filter_hvm_output (line 264) | fn filter_hvm_output(
  type RunOpts (line 313) | pub struct RunOpts {
  method default (line 320) | fn default() -> Self {
  type OptLevel (line 326) | pub enum OptLevel {
    method enabled (line 334) | pub fn enabled(&self) -> bool {
    method is_extra (line 338) | pub fn is_extra(&self) -> bool {
  type CompilerTarget (line 344) | pub enum CompilerTarget {
  type CompileOpts (line 351) | pub struct CompileOpts {
    method set_all (line 386) | pub fn set_all(self) -> Self {
    method set_no_all (line 403) | pub fn set_no_all(self) -> Self {
    method check_for_strict (line 418) | pub fn check_for_strict(&self) {
  method default (line 435) | fn default() -> Self {
  type AdtEncoding (line 452) | pub enum AdtEncoding {
    method fmt (line 458) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type CompileResult (line 466) | pub struct CompileResult {
  function maybe_grow (line 472) | fn maybe_grow<R, F>(f: F) -> R

FILE: src/main.rs
  type Cli (line 17) | struct Cli {
  type Mode (line 32) | enum Mode {
  type RunArgs (line 86) | struct RunArgs {
  type GenArgs (line 113) | struct GenArgs {
  type CliRunOpts (line 131) | struct CliRunOpts {
  type CliWarnOpts (line 141) | struct CliWarnOpts {
  type OptArgs (line 171) | pub enum OptArgs {
  function compile_opts_from_cli (line 195) | fn compile_opts_from_cli(args: &Vec<OptArgs>, compiler_target: CompilerT...
  type WarningArgs (line 234) | pub enum WarningArgs {
  function main (line 246) | fn main() -> ExitCode {
  function execute_cli_mode (line 259) | fn execute_cli_mode(mut cli: Cli) -> Result<(), Diagnostics> {
  function set_warning_cfg_from_cli (line 407) | fn set_warning_cfg_from_cli(mut cfg: DiagnosticsConfig, warn_opts: CliWa...

FILE: src/net/hvm_to_net.rs
  function hvm_to_net (line 8) | pub fn hvm_to_net(net: &Net) -> INet {
  function hvm_to_inodes (line 13) | fn hvm_to_inodes(net: &Net) -> INodes {
  function new_var (line 36) | fn new_var(n_vars: &mut NodeId) -> String {
  function tree_to_inodes (line 43) | fn tree_to_inodes(tree: &Tree, tree_root: String, net_root: &str, n_vars...
  function inodes_to_inet (line 112) | fn inodes_to_inet(inodes: &INodes) -> INet {

FILE: src/net/mod.rs
  type BendLab (line 4) | pub type BendLab = u16;
  type INet (line 9) | pub struct INet {
    method new (line 75) | pub fn new() -> Self {
    method new_node (line 80) | pub fn new_node(&mut self, kind: NodeKind) -> NodeId {
    method node (line 88) | pub fn node(&self, node: NodeId) -> &Node {
    method enter_port (line 93) | pub fn enter_port(&self, port: Port) -> Port {
    method link (line 98) | pub fn link(&mut self, a: Port, b: Port) {
    method set (line 104) | pub fn set(&mut self, src: Port, dst: Port) {
  type Node (line 14) | pub struct Node {
    method new (line 118) | pub fn new(main: Port, aux1: Port, aux2: Port, kind: NodeKind) -> Self {
    method port (line 122) | pub fn port(&self, slot: SlotId) -> Port {
    method port_mut (line 131) | pub fn port_mut(&mut self, slot: SlotId) -> &mut Port {
  type Port (line 22) | pub struct Port(pub NodeId, pub SlotId);
    method node_id (line 143) | pub fn node_id(self) -> NodeId {
    method slot (line 148) | pub fn slot(self) -> SlotId {
  type NodeKind (line 25) | pub enum NodeKind {
  type CtrKind (line 43) | pub enum CtrKind {
    method to_lab (line 50) | pub fn to_lab(self) -> BendLab {
  type NodeId (line 63) | pub type NodeId = u64;
  type SlotId (line 64) | pub type SlotId = u64;
  constant ROOT (line 67) | pub const ROOT: Port = Port(0, 1);
  constant TAG_WIDTH (line 68) | pub const TAG_WIDTH: u32 = 4;
  constant TAG (line 69) | pub const TAG: u32 = u64::BITS - TAG_WIDTH;
  constant LABEL_MASK (line 70) | pub const LABEL_MASK: u64 = (1 << TAG) - 1;
  constant TAG_MASK (line 71) | pub const TAG_MASK: u64 = !LABEL_MASK;
  method default (line 110) | fn default() -> Self {
  type INodes (line 157) | pub type INodes = Vec<INode>;
  type INode (line 160) | pub struct INode {

FILE: tests/golden_tests.rs
  constant TESTS_PATH (line 40) | const TESTS_PATH: &str = "/tests/golden_tests/";
  type RunFn (line 42) | type RunFn = dyn Fn(&str, &Path) -> Result<String, Diagnostics>;
  function parse_book_single_file (line 44) | pub fn parse_book_single_file(code: &str, origin: &Path) -> Result<Book,...
  function run_single_golden_test (line 48) | fn run_single_golden_test(path: &Path, run: &[&RunFn]) -> Result<(), Str...
  function run_golden_test_dir (line 78) | fn run_golden_test_dir(test_name: &str, run: &RunFn) {
  function run_golden_test_dir_multiple (line 82) | fn run_golden_test_dir_multiple(test_name: &str, run: &[&RunFn]) {
  function compile_file (line 114) | fn compile_file() {
  function compile_file_o_all (line 127) | fn compile_file_o_all() {
  function compile_file_o_no_all (line 144) | fn compile_file_o_no_all() {
  function linear_readback (line 156) | fn linear_readback() {
  function run_file (line 179) | fn run_file() {
  function import_system (line 206) | fn import_system() {
  function readback_hvm (line 231) | fn readback_hvm() {
  function simplify_matches (line 245) | fn simplify_matches() {
  function encode_pattern_match (line 286) | fn encode_pattern_match() {
  function parse_file (line 326) | fn parse_file() {
  function check_file (line 341) | fn check_file() {
  function desugar_file (line 356) | fn desugar_file() {
  function hangs (line 372) | fn hangs() {
  function compile_entrypoint (line 398) | fn compile_entrypoint() {
  function run_entrypoint (line 411) | fn run_entrypoint() {
  function cli (line 427) | fn cli() {
  function mutual_recursion (line 448) | fn mutual_recursion() {
  function io (line 461) | fn io() {
  function prelude (line 476) | fn prelude() {
  function examples (line 491) | fn examples() -> Result<(), Diagnostics> {
  function scott_triggers_unused (line 527) | fn scott_triggers_unused() {
  function compile_long (line 542) | fn compile_long() {
Condensed preview — 1098 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,096K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 1738,
    "preview": "name: Bug report\ndescription: Create a report to help us improve.\nbody:\n - type: markdown\n   attributes: \n     value: |\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 220,
    "preview": "blank_issues_enabled: false\ncontact_links: \n    - name: HVM Related Issues\n      url: https://github.com/HigherOrderCO/H"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 605,
    "preview": "---\nname: Feature request\nabout: Suggest a feature that you think should be added.\ntitle: ''\nlabels: ''\nassignees: ''\n\n-"
  },
  {
    "path": ".github/workflows/checks.yml",
    "chars": 1919,
    "preview": "name: Checks\n\non:\n  pull_request:\n  merge_group:\n  push:\n    branches:\n      - main\n\njobs:\n  check:\n    runs-on: ubuntu-"
  },
  {
    "path": ".gitignore",
    "chars": 45,
    "preview": "/target\n*.snap.new\n.out.hvm\n.DS_Store\n.vscode"
  },
  {
    "path": ".rustfmt.toml",
    "chars": 211,
    "preview": "edition = \"2021\"\nmax_width = 110\n# won't add \\r\\n on windows machines, better on diffs\nnewline_style = \"Unix\"\nuse_small_"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 14716,
    "preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2153,
    "preview": "# Contributing to Bend\n\nThank you for considering contributing to Bend!\n\n## How to Contribute\n\n### Reporting bugs\n\n1. **"
  },
  {
    "path": "Cargo.toml",
    "chars": 730,
    "preview": "[package]\nname = \"bend-lang\"\ndescription = \"A high-level, massively parallel programming language\"\nlicense = \"Apache-2.0"
  },
  {
    "path": "FAQ.md",
    "chars": 3366,
    "preview": "# Known Issues and Frequently Asked Questions\n\n## Installation and Setup\n\n### Can I run this on Windows?\n- We're still w"
  },
  {
    "path": "FEATURES.md",
    "chars": 14687,
    "preview": "## Features\n\nBend offers two flavors of syntax, the user-friendly python-like syntax \"Imp\" (the default) and the core ML"
  },
  {
    "path": "GUIDE.md",
    "chars": 26063,
    "preview": "# Bend in X minutes - the ultimate guide!\n\nBend is a high-level, massively parallel programming language. That means it\n"
  },
  {
    "path": "LICENSE-APACHE",
    "chars": 10771,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 9089,
    "preview": "<h1 >Bend</h1>\n<p>A high-level, massively parallel programming language</p>\n\n## Index\n1. [Introduction](#introduction)\n2"
  },
  {
    "path": "cspell.json",
    "chars": 2064,
    "preview": "{\n  \"version\": \"0.2\",\n  \"language\": \"en\",\n  \"words\": [\n    \"anni\",\n    \"annihilations\",\n    \"arities\",\n    \"arity\",\n    "
  },
  {
    "path": "docs/builtins.md",
    "chars": 18447,
    "preview": "> this is a WIP based on [Builtins.bend](https://github.com/HigherOrderCO/Bend/blob/main/src/fun/builtins.bend).\n\n# Buil"
  },
  {
    "path": "docs/cli-arguments.md",
    "chars": 1202,
    "preview": "# CLI arguments\n\nIt's possible to pass arguments to a program executed with `bend run`:\n\n```sh\nbend run <Path to program"
  },
  {
    "path": "docs/compilation-and-readback.md",
    "chars": 5507,
    "preview": "# Compilation and readback\n\nHow are terms compiled to interaction net nodes?\n\nHVM has a bunch of useful nodes to write I"
  },
  {
    "path": "docs/compiler-options.md",
    "chars": 7874,
    "preview": "# Options\n\n| flag                                                                     | Default       | What it does?   "
  },
  {
    "path": "docs/defining-data-types.md",
    "chars": 1462,
    "preview": "# Defining data types\n\nIt is possible to easily define complex data types using the `type` keyword.\n\n```py\n# A Boolean i"
  },
  {
    "path": "docs/dups-and-sups.md",
    "chars": 2589,
    "preview": "# Dups and sups\n\nTerm duplication is done automatically when a variable is used more than once. But it's possible to man"
  },
  {
    "path": "docs/ffi.md",
    "chars": 7891,
    "preview": "# Dynamically linked libraries and foreign functions\n\nWe can add new IO functions to Bend during runtime by loading dyna"
  },
  {
    "path": "docs/imports.md",
    "chars": 4771,
    "preview": "# Import System\n\n## Case Sensitivity\nAll import paths are case-sensitive. Ensure that the case used in import statements"
  },
  {
    "path": "docs/lazy-definitions.md",
    "chars": 3051,
    "preview": "# Making recursive definitions lazy\n\nIn strict-mode, some types of recursive terms will unroll indefinitely.\n\nThis is a "
  },
  {
    "path": "docs/native-numbers.md",
    "chars": 6253,
    "preview": "# Native numbers\n\nCurrently Bend supports 3 types of native numbers for fast numeric operations (compared to lambda-enco"
  },
  {
    "path": "docs/pattern-matching.md",
    "chars": 5670,
    "preview": "# Pattern Matching\n\nSwitches on many numbers are compiled to sequences of simple switch expressions:\n```py\n  # These two"
  },
  {
    "path": "docs/syntax.md",
    "chars": 36018,
    "preview": "# Syntax\n\nThis file provides a reference of each possible syntax of bend programming language.\n\nClick [here](#imp-syntax"
  },
  {
    "path": "docs/type-checking.md",
    "chars": 5031,
    "preview": "# Type Checking\n\nBend has a type checker with optional typing support based on a Hindley Milner type system.\n\nPrograms c"
  },
  {
    "path": "docs/using-scopeless-lambdas.md",
    "chars": 3922,
    "preview": "# Using scopeless lambdas\n\nScopeless lambdas are very powerful lambdas that are a side-effect of HVM's internal represen"
  },
  {
    "path": "docs/writing-fusing-functions.md",
    "chars": 6204,
    "preview": "# Writing fusing functions\n## Church encoding\nChurch Encoding is a way to encode common datatypes as λ-calculus terms. F"
  },
  {
    "path": "examples/bitonic_sort.bend",
    "chars": 1557,
    "preview": "# Implements bitonic sort on a list of numbers encoded as a tree of pairs.\n# https://en.wikipedia.org/wiki/Bitonic_sorte"
  },
  {
    "path": "examples/bubble_sort.bend",
    "chars": 1045,
    "preview": "# Sorts a list\ndef sort(xs: List(u24)) -> List(u24):\n  match xs:\n    case List/Nil: \n      return List/Nil\n    case List"
  },
  {
    "path": "examples/callcc.bend",
    "chars": 654,
    "preview": "# This program is an example that shows how scopeless lambdas can be used.\n\nSeq (a: A) (b: B) : A = a\n\n# Create a progra"
  },
  {
    "path": "examples/example_fun.bend",
    "chars": 5324,
    "preview": "# Example of some things you can do with the 'fun' syntax\n\n# Define functions like this:\n# By default they accept and re"
  },
  {
    "path": "examples/fib.bend",
    "chars": 1236,
    "preview": "# Program to calculate fibonacci numbers.\n\n# Calculates fibonacci numbers recursively.\n# Although branching recursion is"
  },
  {
    "path": "examples/fusing_add.bend",
    "chars": 455,
    "preview": "# Example of fusing functions with Scott-encoded numbers.\n\nzero = λs λz z\nsucc = λpred λs λz (s pred) # Creates a Scott "
  },
  {
    "path": "examples/fusing_not.bend",
    "chars": 620,
    "preview": "# Example of a boolean 'not' function that fuses inifinitely through composition..\n\ntrue  : a -> b -> a = λt λf t\nfalse "
  },
  {
    "path": "examples/gen_tree.bend",
    "chars": 406,
    "preview": "# Generates a tree with numbers in the nodes using 'bend'\ntype MyTree(t):\n  Node { val: t, ~left: MyTree(t), ~right: MyT"
  },
  {
    "path": "examples/hello_world.bend",
    "chars": 89,
    "preview": "def main() -> IO(u24):\n  with IO:\n    * <- IO/print(\"Hello, world!\\n\")\n    return wrap(0)"
  },
  {
    "path": "examples/insertion_sort.bend",
    "chars": 1015,
    "preview": "def insertion_sort(xs: List(u24)) -> List(u24):\n  match xs:\n    case List/Nil:\n      return List/Nil\n    case List/Cons:"
  },
  {
    "path": "examples/list.bend",
    "chars": 4815,
    "preview": "##############################\n# Author: Ematth, 2024\n##############################\n### Singly-Linked List Type Definit"
  },
  {
    "path": "examples/parallel_and.bend",
    "chars": 625,
    "preview": "# This program allocates a tree with True at the leaves then parallel ANDs them.\ntype Bool:\n  True\n  False\n\ndef and(a: B"
  },
  {
    "path": "examples/parallel_sum.bend",
    "chars": 774,
    "preview": "# A very simple example of a massively parallel program\n# Creates a tree with numbers and then sums all values in parall"
  },
  {
    "path": "examples/queue.bend",
    "chars": 462,
    "preview": "# A cool trick involving unscoped lambdas\n# Implements constant-time queues with just lambdas\n\n# Qnew : Queue a\nQnew: _ "
  },
  {
    "path": "examples/quick_sort.bend",
    "chars": 1391,
    "preview": "type MyTree t = Leaf | (Node ~(lft: (MyTree t)) (val: t) ~(rgt: (MyTree t)))\n\n# Parallel QuickSort\n(Sort) : (List u24) -"
  },
  {
    "path": "examples/radix_sort.bend",
    "chars": 3068,
    "preview": "type MyMap:\n  Free\n  Used\n  Both { ~a: MyMap, ~b: MyMap }\n\ntype Arr(t):\n  Null\n  Leaf { a: t }\n  Node { ~a: Arr(t), ~b: "
  },
  {
    "path": "justfile",
    "chars": 563,
    "preview": "# To use this, first run `cargo install just`\n# Then run the install subcommand: `just install`\n# Running `just` is equi"
  },
  {
    "path": "src/diagnostics.rs",
    "chars": 14371,
    "preview": "use TSPL::ParseError;\n\nuse crate::fun::{display::DisplayFn, Name, Source};\nuse std::{\n  collections::BTreeMap,\n  fmt::{D"
  },
  {
    "path": "src/fun/builtins.bend",
    "chars": 28219,
    "preview": "type String:\n  Nil\n  Cons { head: u24, ~tail: String }\n\ntype List(T):\n  Nil\n  Cons { head: T, ~tail: List(T) }\n\n#{ Retur"
  },
  {
    "path": "src/fun/builtins.rs",
    "chars": 3950,
    "preview": "use super::{\n  parser::{FunParser, ParseBook},\n  Book, Name, Num, Pattern, Term,\n};\nuse crate::maybe_grow;\n\nconst BUILTI"
  },
  {
    "path": "src/fun/check/check_untyped.rs",
    "chars": 2536,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Ctx, FanKind, Pattern, Tag, Term},\n  maybe_grow,\n};\n\nimpl Ctx<'_> {\n  /"
  },
  {
    "path": "src/fun/check/mod.rs",
    "chars": 133,
    "preview": "pub mod check_untyped;\npub mod set_entrypoint;\npub mod shared_names;\npub mod type_check;\npub mod unbound_refs;\npub mod u"
  },
  {
    "path": "src/fun/check/set_entrypoint.rs",
    "chars": 2707,
    "preview": "use crate::{\n  diagnostics::WarningType,\n  fun::{Book, Ctx, Definition, Name},\n  ENTRY_POINT, HVM1_ENTRY_POINT,\n};\n\n#[de"
  },
  {
    "path": "src/fun/check/shared_names.rs",
    "chars": 2410,
    "preview": "use crate::fun::{Ctx, Name};\nuse indexmap::IndexMap;\nuse std::fmt::Display;\n\n#[derive(Debug, Clone)]\npub struct Repeated"
  },
  {
    "path": "src/fun/check/type_check.rs",
    "chars": 28272,
    "preview": "//! Optional Hindley-Milner-like type system.\n//!\n//! Based on https://github.com/developedby/algorithm-w-rs\n//! and htt"
  },
  {
    "path": "src/fun/check/unbound_refs.rs",
    "chars": 1043,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Book, Ctx, Name, Term},\n  maybe_grow,\n};\nuse std::collections::HashSet;"
  },
  {
    "path": "src/fun/check/unbound_vars.rs",
    "chars": 4264,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{transform::desugar_bend, Ctx, Name, Pattern, Term},\n  maybe_grow,\n};\nus"
  },
  {
    "path": "src/fun/display.rs",
    "chars": 18740,
    "preview": "use super::{Book, Definition, FanKind, Name, Num, Op, Pattern, Rule, Tag, Term, Type};\nuse crate::maybe_grow;\nuse std::{"
  },
  {
    "path": "src/fun/load_book.rs",
    "chars": 1645,
    "preview": "use super::{\n  parser::{FunParser, ParseBook},\n  Book, Name, Source, SourceKind,\n};\nuse crate::{\n  diagnostics::{Diagnos"
  },
  {
    "path": "src/fun/mod.rs",
    "chars": 36695,
    "preview": "use crate::{\n  diagnostics::{Diagnostics, DiagnosticsConfig, TextSpan},\n  imports::Import,\n  maybe_grow, multi_iterator,"
  },
  {
    "path": "src/fun/net_to_term.rs",
    "chars": 27535,
    "preview": "use crate::{\n  diagnostics::{DiagnosticOrigin, Diagnostics, Severity},\n  fun::{term_to_net::Labels, Book, FanKind, Name,"
  },
  {
    "path": "src/fun/parser.rs",
    "chars": 58084,
    "preview": "use crate::{\n  fun::{\n    display::DisplayFn, Adt, AdtCtr, Adts, Constructors, CtrField, FanKind, HvmDefinition, HvmDefi"
  },
  {
    "path": "src/fun/term_to_net.rs",
    "chars": 16720,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{num_to_name, Book, FanKind, Name, Op, Pattern, Term},\n  hvm::{net_trees"
  },
  {
    "path": "src/fun/transform/apply_args.rs",
    "chars": 1652,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Ctx, Pattern, Rule, Term},\n};\n\nimpl Ctx<'_> {\n  /// Applies the argumen"
  },
  {
    "path": "src/fun/transform/definition_merge.rs",
    "chars": 4080,
    "preview": "use crate::{\n  fun::{Book, Definition, Name, Rule, Term},\n  maybe_grow,\n};\nuse indexmap::{IndexMap, IndexSet};\nuse itert"
  },
  {
    "path": "src/fun/transform/definition_pruning.rs",
    "chars": 6139,
    "preview": "use crate::{\n  diagnostics::WarningType,\n  fun::{Book, Ctx, Name, SourceKind, Term},\n  maybe_grow,\n};\nuse hvm::ast::{Net"
  },
  {
    "path": "src/fun/transform/desugar_bend.rs",
    "chars": 3491,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Ctx, Definition, Name, Rule, Source, Term},\n  maybe_grow,\n};\nuse indexm"
  },
  {
    "path": "src/fun/transform/desugar_fold.rs",
    "chars": 5328,
    "preview": "use std::collections::HashSet;\n\nuse crate::{\n  diagnostics::Diagnostics,\n  fun::{Adts, Constructors, Ctx, Definition, Na"
  },
  {
    "path": "src/fun/transform/desugar_match_defs.rs",
    "chars": 22068,
    "preview": "use crate::{\n  diagnostics::{Diagnostics, WarningType},\n  fun::{builtins, Adts, Constructors, Ctx, Definition, FanKind, "
  },
  {
    "path": "src/fun/transform/desugar_open.rs",
    "chars": 1680,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Adts, Ctx, Term},\n  maybe_grow,\n};\n\nimpl Ctx<'_> {\n  pub fn desugar_ope"
  },
  {
    "path": "src/fun/transform/desugar_use.rs",
    "chars": 1316,
    "preview": "use crate::{\n  fun::{Book, Term},\n  maybe_grow,\n};\n\nimpl Book {\n  /// Inline copies of the declared bind in the `use` ex"
  },
  {
    "path": "src/fun/transform/desugar_with_blocks.rs",
    "chars": 2620,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Ctx, Name, Pattern, Term},\n  maybe_grow,\n};\nuse std::collections::HashS"
  },
  {
    "path": "src/fun/transform/encode_adts.rs",
    "chars": 2362,
    "preview": "use crate::{\n  fun::{Book, Definition, Name, Num, Pattern, Rule, Source, Term},\n  AdtEncoding,\n};\n\nimpl Book {\n  /// Def"
  },
  {
    "path": "src/fun/transform/encode_match_terms.rs",
    "chars": 4121,
    "preview": "use crate::{\n  fun::{Book, MatchRule, Name, Pattern, Term},\n  maybe_grow, AdtEncoding,\n};\n\nimpl Book {\n  /// Encodes pat"
  },
  {
    "path": "src/fun/transform/expand_generated.rs",
    "chars": 2817,
    "preview": "use std::collections::{BTreeSet, HashMap, HashSet};\n\nuse crate::{\n  fun::{Book, Name, Term},\n  maybe_grow,\n};\n\n/// Deref"
  },
  {
    "path": "src/fun/transform/expand_main.rs",
    "chars": 5924,
    "preview": "use crate::{\n  fun::{Book, Name, Pattern, Term},\n  maybe_grow,\n};\nuse std::collections::HashMap;\n\nimpl Book {\n  /// Expa"
  },
  {
    "path": "src/fun/transform/fix_match_defs.rs",
    "chars": 2973,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Adts, Constructors, Ctx, Pattern, Rule, Term},\n};\n\nimpl Ctx<'_> {\n  ///"
  },
  {
    "path": "src/fun/transform/fix_match_terms.rs",
    "chars": 11289,
    "preview": "use crate::{\n  diagnostics::{Diagnostics, WarningType, ERR_INDENT_SIZE},\n  fun::{Adts, Constructors, CtrField, Ctx, Matc"
  },
  {
    "path": "src/fun/transform/float_combinators.rs",
    "chars": 9668,
    "preview": "use crate::{\n  fun::{Book, Definition, Name, Pattern, Rule, Source, Term},\n  maybe_grow, multi_iterator,\n};\nuse std::col"
  },
  {
    "path": "src/fun/transform/lift_local_defs.rs",
    "chars": 3000,
    "preview": "use std::collections::BTreeSet;\n\nuse indexmap::IndexMap;\n\nuse crate::{\n  fun::{Book, Definition, Name, Pattern, Rule, Te"
  },
  {
    "path": "src/fun/transform/linearize_matches.rs",
    "chars": 16378,
    "preview": "use crate::{\n  fun::{Book, Name, Pattern, Term},\n  maybe_grow,\n};\nuse std::collections::{BTreeSet, HashMap, HashSet, Vec"
  },
  {
    "path": "src/fun/transform/linearize_vars.rs",
    "chars": 5877,
    "preview": "use crate::{\n  fun::{Book, FanKind, Name, Pattern, Tag, Term},\n  maybe_grow, multi_iterator,\n};\nuse std::collections::Ha"
  },
  {
    "path": "src/fun/transform/mod.rs",
    "chars": 583,
    "preview": "pub mod apply_args;\npub mod definition_merge;\npub mod definition_pruning;\npub mod desugar_bend;\npub mod desugar_fold;\npu"
  },
  {
    "path": "src/fun/transform/resolve_refs.rs",
    "chars": 3521,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Ctx, Name, Pattern, Term},\n  maybe_grow,\n};\nuse std::collections::{Hash"
  },
  {
    "path": "src/fun/transform/resolve_type_ctrs.rs",
    "chars": 1922,
    "preview": "use crate::{\n  diagnostics::Diagnostics,\n  fun::{Adts, Ctx, Type},\n  maybe_grow,\n};\n\nimpl Ctx<'_> {\n  /// Resolves type "
  },
  {
    "path": "src/fun/transform/resugar_list.rs",
    "chars": 9947,
    "preview": "use crate::{\n  fun::{builtins, Pattern, Tag, Term},\n  maybe_grow, AdtEncoding,\n};\n\nimpl Term {\n  /// Converts lambda-enc"
  },
  {
    "path": "src/fun/transform/resugar_string.rs",
    "chars": 6421,
    "preview": "use crate::{\n  fun::{builtins, Name, Num, Pattern, Tag, Term},\n  maybe_grow, AdtEncoding,\n};\n\nimpl Term {\n  /// Converts"
  },
  {
    "path": "src/fun/transform/unique_names.rs",
    "chars": 5713,
    "preview": "// Pass to give all variables in a definition unique names.\n\nuse crate::{\n  fun::{Book, Name, Term},\n  maybe_grow,\n};\nus"
  },
  {
    "path": "src/hvm/add_recursive_priority.rs",
    "chars": 3318,
    "preview": "use super::tree_children;\nuse crate::maybe_grow;\nuse hvm::ast::{Book, Net, Tree};\nuse std::collections::{HashMap, HashSe"
  },
  {
    "path": "src/hvm/check_net_size.rs",
    "chars": 1383,
    "preview": "use super::tree_children;\nuse crate::{diagnostics::Diagnostics, fun::Name, CompilerTarget};\nuse hvm::ast::{Book, Net, Tr"
  },
  {
    "path": "src/hvm/eta_reduce.rs",
    "chars": 4997,
    "preview": "//! Carries out simple eta-reduction, to reduce the amount of rewrites at\n//! runtime.\n//!\n//! ### Eta-equivalence\n//!\n/"
  },
  {
    "path": "src/hvm/inline.rs",
    "chars": 2209,
    "preview": "use super::{net_trees_mut, tree_children, tree_children_mut};\nuse crate::maybe_grow;\nuse core::ops::BitOr;\nuse hvm::ast:"
  },
  {
    "path": "src/hvm/mod.rs",
    "chars": 1860,
    "preview": "use crate::multi_iterator;\nuse hvm::ast::{Net, Tree};\n\npub mod add_recursive_priority;\npub mod check_net_size;\npub mod e"
  },
  {
    "path": "src/hvm/mutual_recursion.message",
    "chars": 1315,
    "preview": "\u001b[1mThe following functions contain recursive cycles incompatible with HVM's strict evaluation:\u001b[0m\n{cycles}\n\nThe greedy"
  },
  {
    "path": "src/hvm/mutual_recursion.rs",
    "chars": 5015,
    "preview": "use super::tree_children;\nuse crate::{\n  diagnostics::{Diagnostics, WarningType, ERR_INDENT_SIZE},\n  fun::transform::def"
  },
  {
    "path": "src/hvm/prune.rs",
    "chars": 952,
    "preview": "use super::{net_trees, tree_children};\nuse crate::maybe_grow;\nuse hvm::ast::{Book, Tree};\nuse std::collections::HashSet;"
  },
  {
    "path": "src/imp/gen_map_get.rs",
    "chars": 7360,
    "preview": "use crate::fun::Name;\n\nuse super::{AssignPattern, Definition, Expr, Stmt};\n\nimpl Definition {\n  /// Generates a map from"
  },
  {
    "path": "src/imp/mod.rs",
    "chars": 4698,
    "preview": "pub mod gen_map_get;\nmod order_kwargs;\npub mod parser;\npub mod to_fun;\n\nuse crate::fun::{Name, Num, Op, Source, Type};\nu"
  },
  {
    "path": "src/imp/order_kwargs.rs",
    "chars": 7344,
    "preview": "use crate::{\n  fun::{parser::ParseBook, Name},\n  imp::{Definition, Expr, Stmt},\n};\nuse indexmap::IndexMap;\n\nimpl Definit"
  },
  {
    "path": "src/imp/parser.rs",
    "chars": 44030,
    "preview": "use crate::{\n  fun::{\n    parser::{is_num_char, make_ctr_type, make_fn_type, Indent, ParseResult, ParserCommons},\n    Ad"
  },
  {
    "path": "src/imp/to_fun.rs",
    "chars": 19111,
    "preview": "use super::{AssignPattern, Definition, Expr, InPlaceOp, Stmt};\nuse crate::{\n  diagnostics::Diagnostics,\n  fun::{\n    sel"
  },
  {
    "path": "src/imports/book.rs",
    "chars": 18485,
    "preview": "use super::{BindMap, ImportsMap, PackageLoader};\nuse crate::{\n  diagnostics::{Diagnostics, DiagnosticsConfig},\n  fun::{\n"
  },
  {
    "path": "src/imports/loader.rs",
    "chars": 6519,
    "preview": "use super::{BoundSource, Import, ImportType};\nuse crate::fun::Name;\nuse indexmap::IndexMap;\nuse std::{\n  collections::Ha"
  },
  {
    "path": "src/imports/mod.rs",
    "chars": 3844,
    "preview": "use crate::{\n  diagnostics::{Diagnostics, WarningType},\n  fun::Name,\n};\nuse indexmap::{IndexMap, IndexSet};\nuse itertool"
  },
  {
    "path": "src/imports/packages.rs",
    "chars": 7928,
    "preview": "use super::{loader::PackageLoader, normalize_path, BoundSource, ImportCtx, ImportType, ImportsMap};\nuse crate::{\n  diagn"
  },
  {
    "path": "src/lib.rs",
    "chars": 12515,
    "preview": "use crate::{\n  fun::{book_to_hvm, net_to_term::net_to_term, term_to_net::Labels, Book, Ctx, Term},\n  hvm::{\n    add_recu"
  },
  {
    "path": "src/main.rs",
    "chars": 13676,
    "preview": "use bend::{\n  check_book, compile_book, desugar_book,\n  diagnostics::{Diagnostics, DiagnosticsConfig, Severity},\n  fun::"
  },
  {
    "path": "src/net/hvm_to_net.rs",
    "chars": 4445,
    "preview": "use super::{INet, INode, INodes, NodeId, NodeKind::*, Port, SlotId, ROOT};\nuse crate::{\n  fun::Name,\n  net::{CtrKind, No"
  },
  {
    "path": "src/net/mod.rs",
    "chars": 3785,
    "preview": "pub mod hvm_to_net;\n\nuse crate::fun::Name;\npub type BendLab = u16;\nuse NodeKind::*;\n\n#[derive(Debug, Clone)]\n/// Net rep"
  },
  {
    "path": "src/utils.rs",
    "chars": 1249,
    "preview": "/// A macro for creating iterators that can have statically known\n/// different types. Useful for iterating over tree ch"
  },
  {
    "path": "tests/golden_tests/check_file/fail_type_bad_rec_fn_adt.bend",
    "chars": 245,
    "preview": "# Should give a type error in Erase when unifying the field of type Unit with the match type of Box \ntype Box:\n  Box {x:"
  },
  {
    "path": "tests/golden_tests/check_file/non_exaustive_limit.bend",
    "chars": 78,
    "preview": "type Foo = A | B | C | D | E | F | G | H\n\nBar Foo/A Foo/A Foo/A = *\n\nmain = *\n"
  },
  {
    "path": "tests/golden_tests/check_file/type_err_match_arm.bend",
    "chars": 191,
    "preview": "type Nat_:\n  Zero\n  Succ {x: Unit, pred: Nat_}\n\ntype Unit:\n  Unit\n\nTest1: Nat_ -> (Nat_, Nat_)\nTest1 = λx match x {\n  Na"
  },
  {
    "path": "tests/golden_tests/cli/compile_all.args",
    "chars": 54,
    "preview": "gen-hvm\ntests/golden_tests/cli/compile_all.bend\n-Oall\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_all.bend",
    "chars": 125,
    "preview": "type Pair\n  = (Pair fst snd)\n\nPair.get f (Pair/Pair fst snd) = (f fst snd)\n\nmain = (Pair.get @x @y (+ x y) (Pair/Pair 40"
  },
  {
    "path": "tests/golden_tests/cli/compile_inline.args",
    "chars": 60,
    "preview": "gen-hvm\ntests/golden_tests/cli/compile_inline.bend\n-Oinline\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_inline.bend",
    "chars": 71,
    "preview": "(Num) = 42\n\n(Era) = *\n\n(RefToRef) = (Era)\n\n(Main) = (Era Num RefToRef)\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_no_opts.args",
    "chars": 127,
    "preview": "gen-hvm\ntests/golden_tests/cli/compile_no_opts.bend\n-Ono-all\n-Ono-eta\n-Ono-prune\n-Ono-float-combinators\n-Ono-merge\n-Ono-"
  },
  {
    "path": "tests/golden_tests/cli/compile_no_opts.bend",
    "chars": 9,
    "preview": "main = *\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_pre_reduce.args",
    "chars": 68,
    "preview": "gen-hvm\ntests/golden_tests/cli/compile_pre_reduce.bend\n-Opre-reduce\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_pre_reduce.bend",
    "chars": 22,
    "preview": "I = (+ 2 3)\n\nmain = *\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_strict_loop.args",
    "chars": 83,
    "preview": "gen-hvm\ntests/golden_tests/cli/compile_strict_loop.bend\n-Ono-all\n-Arecursion-cycle\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_strict_loop.bend",
    "chars": 75,
    "preview": "A = @a match a {\n  List/Cons: (A a.tail)\n  List/Nil: 0\n}\n\nmain = (A [4 4])\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_wrong_opt.args",
    "chars": 60,
    "preview": "gen-hvm\ntests/golden_tests/cli/compile_wrong_opt.bend\n-Ofoo\n"
  },
  {
    "path": "tests/golden_tests/cli/compile_wrong_opt.bend",
    "chars": 9,
    "preview": "main = *\n"
  },
  {
    "path": "tests/golden_tests/cli/custom_hvm_bin.args",
    "chars": 61,
    "preview": "run\ntests/golden_tests/cli/custom_hvm_bin.bend\n--hvm-bin=hvm\n"
  },
  {
    "path": "tests/golden_tests/cli/custom_hvm_bin.bend",
    "chars": 11,
    "preview": "main = @x x"
  },
  {
    "path": "tests/golden_tests/cli/debug_list_map.args",
    "chars": 56,
    "preview": "run\ntests/golden_tests/cli/debug_list_map.bend\n-d\n-L\n-1\n"
  },
  {
    "path": "tests/golden_tests/cli/debug_list_map.bend",
    "chars": 137,
    "preview": "(Map f []) = []\n(Map f (List/Cons head tail)) = (List/Cons (f head) (Map f tail))\n\n(Inc) = @x (+ x 1)\n\n(Main) = (Map Inc"
  },
  {
    "path": "tests/golden_tests/cli/debug_u60_to_nat.args",
    "chars": 54,
    "preview": "run\ntests/golden_tests/cli/debug_u60_to_nat.bend\n-d\n4\n"
  },
  {
    "path": "tests/golden_tests/cli/debug_u60_to_nat.bend",
    "chars": 119,
    "preview": "type Nat_ = (Z) | (S nat)\n\nU60ToNat n = switch n {\n  0: Nat_/Z\n  _: (Nat_/S (U60ToNat n-1))\n}\n\n(Main n) = (U60ToNat n)\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_bool_scott.args",
    "chars": 67,
    "preview": "desugar\ntests/golden_tests/cli/desugar_bool_scott.bend\n-Oadt-scott\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_bool_scott.bend",
    "chars": 49,
    "preview": "type Boolean = True | False\n\nmain = Boolean/True\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_float_combinators.args",
    "chars": 82,
    "preview": "desugar\ntests/golden_tests/cli/desugar_float_combinators.bend\n-Ofloat-combinators\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_float_combinators.bend",
    "chars": 95,
    "preview": "Z =    @s @z z\nS = @x @s @z (s (x s z))\n\nget = @Nat (Nat @x (+ x 1) 0)\n\nmain = (get (S (S Z)))\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_linearize_matches.args",
    "chars": 82,
    "preview": "desugar\ntests/golden_tests/cli/desugar_linearize_matches.bend\n-Olinearize-matches\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_linearize_matches.bend",
    "chars": 40,
    "preview": "main = λa λb λc switch a { 0: b; _: c }\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_linearize_matches_alt.args",
    "chars": 90,
    "preview": "desugar\ntests/golden_tests/cli/desugar_linearize_matches_alt.bend\n-Olinearize-matches-alt\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_linearize_matches_alt.bend",
    "chars": 37,
    "preview": "main = λa λb switch a { 0: b; _: b }\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_merge.args",
    "chars": 58,
    "preview": "desugar\ntests/golden_tests/cli/desugar_merge.bend\n-Omerge\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_merge.bend",
    "chars": 36,
    "preview": "F = @t @f f\nZ = @s @z z\n\nmain = (F)\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_pretty.args",
    "chars": 54,
    "preview": "desugar\ntests/golden_tests/cli/desugar_pretty.bend\n-p\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_pretty.bend",
    "chars": 89,
    "preview": "Foo (a,b) (c,d) = (+ (+ a b) (+ c d))\n\nmain =\n  @(x, y)\n  @{a b c}\n  (+ (+ x y) (+ a b))\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_prune.args",
    "chars": 58,
    "preview": "desugar\ntests/golden_tests/cli/desugar_prune.bend\n-Oprune\n"
  },
  {
    "path": "tests/golden_tests/cli/desugar_prune.bend",
    "chars": 19,
    "preview": "id x = x\n\nmain = *\n"
  },
  {
    "path": "tests/golden_tests/cli/gen_hvm_no_eta_by_default.args",
    "chars": 61,
    "preview": "gen-hvm\ntests/golden_tests/cli/gen_hvm_no_eta_by_default.bend"
  },
  {
    "path": "tests/golden_tests/cli/gen_hvm_no_eta_by_default.bend",
    "chars": 667,
    "preview": "# Eta-reduction of some recursive functions can mess the performance\n# of programs targeting the CUDA runtime.\n\n# So for"
  },
  {
    "path": "tests/golden_tests/cli/input_file_not_found.args",
    "chars": 61,
    "preview": "run\ntests/golden_tests/missing_dir/input_file_not_found.bend\n"
  },
  {
    "path": "tests/golden_tests/cli/input_file_not_found.bend",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/golden_tests/cli/net_size_too_large.args",
    "chars": 72,
    "preview": "gen-hvm\ntests/golden_tests/cli/net_size_too_large.bend\n-Ocheck-net-size\n"
  },
  {
    "path": "tests/golden_tests/cli/net_size_too_large.bend",
    "chars": 2592,
    "preview": "type Map_ = Free | Used | (Both a b)\ntype Arr = Null | (Leaf x) | (Node a b)\n\n(Swap s a b) = switch s {\n  0: (Map_/Both "
  },
  {
    "path": "tests/golden_tests/cli/no_check_net_size.args",
    "chars": 74,
    "preview": "gen-hvm\ntests/golden_tests/cli/no_check_net_size.bend\n-Ono-check-net-size\n"
  },
  {
    "path": "tests/golden_tests/cli/no_check_net_size.bend",
    "chars": 2592,
    "preview": "type Map_ = Free | Used | (Both a b)\ntype Arr = Null | (Leaf x) | (Node a b)\n\n(Swap s a b) = switch s {\n  0: (Map_/Both "
  },
  {
    "path": "tests/golden_tests/cli/run_add.args",
    "chars": 44,
    "preview": "run\ntests/golden_tests/cli/run_add.bend\n3\n6\n"
  },
  {
    "path": "tests/golden_tests/cli/run_add.bend",
    "chars": 19,
    "preview": "main a b = (+ a b)\n"
  },
  {
    "path": "tests/golden_tests/cli/run_pretty.args",
    "chars": 46,
    "preview": "run\ntests/golden_tests/cli/run_pretty.bend\n-p\n"
  },
  {
    "path": "tests/golden_tests/cli/run_pretty.bend",
    "chars": 93,
    "preview": "main a b =\n  switch a {\n    0: switch b {\n      0: \"ba\"\n      _: \"ta\"\n    }\n    _: \"ata\"\n  }\n"
  },
  {
    "path": "tests/golden_tests/cli/tuple_readback.args",
    "chars": 76,
    "preview": "run\ntests/golden_tests/cli/tuple_readback.bend\n-Ono-float-combinators\n-Aall\n"
  },
  {
    "path": "tests/golden_tests/cli/tuple_readback.bend",
    "chars": 178,
    "preview": "# We probably will not be able to handle all these\nmain = (\n  @a (1, a),\n  (1, 2),\n  (*, 2),\n  ($x, @$x *),\n  ((1, @$y $"
  },
  {
    "path": "tests/golden_tests/cli/warn_and_err.args",
    "chars": 49,
    "preview": "gen-hvm\ntests/golden_tests/cli/warn_and_err.bend\n"
  },
  {
    "path": "tests/golden_tests/cli/warn_and_err.bend",
    "chars": 28,
    "preview": "Foo a a = a\n\nMain = (Foo a)\n"
  },
  {
    "path": "tests/golden_tests/compile_entrypoint/foo.bend",
    "chars": 26,
    "preview": "bar = λx x\n\nfoo = (bar 2)\n"
  },
  {
    "path": "tests/golden_tests/compile_file/360_no_scope.bend",
    "chars": 123,
    "preview": "main =\n  let $d = ((@$a $c) 360)\n  let $b = ((@$c $a) $b)\n  let #x{#y($e, $f) #y($g, $h)} = #y(#x{$d $f}, #x{$e, $g})\n  "
  },
  {
    "path": "tests/golden_tests/compile_file/add_args.bend",
    "chars": 40,
    "preview": "add x y = (+ x y)\n\nmain x y = (add x y)\n"
  },
  {
    "path": "tests/golden_tests/compile_file/addition.bend",
    "chars": 27,
    "preview": "main = (λx (+ (+ 1 1) x) 8)"
  },
  {
    "path": "tests/golden_tests/compile_file/addition_const.bend",
    "chars": 14,
    "preview": "main = (+ 1 2)"
  },
  {
    "path": "tests/golden_tests/compile_file/ask_outside_do.bend",
    "chars": 32,
    "preview": "main = ask x = (Result/Ok x); x\n"
  },
  {
    "path": "tests/golden_tests/compile_file/church_one.bend",
    "chars": 58,
    "preview": "main = (λk λs λz let {s0 s1} = s; (s0 ((k s1) z)) λq λw w)"
  },
  {
    "path": "tests/golden_tests/compile_file/church_zero.bend",
    "chars": 14,
    "preview": "main = λs λz z"
  },
  {
    "path": "tests/golden_tests/compile_file/complicated_dup.bend",
    "chars": 75,
    "preview": "main = let {x1 x2} = ($a $b); λy let {y1 y2} = y; (λ$a (y1 x1) λ$b (y2 x2))"
  },
  {
    "path": "tests/golden_tests/compile_file/crlf.bend",
    "chars": 17,
    "preview": "a = 1\r\n\r\nmain = 2"
  },
  {
    "path": "tests/golden_tests/compile_file/cyclic_global_lam.bend",
    "chars": 20,
    "preview": "main = λa ($a λ$a a)"
  },
  {
    "path": "tests/golden_tests/compile_file/def_pat_unscoped.bend",
    "chars": 38,
    "preview": "add $a b = (+ $a b)\n\nmain = (add 9 4)\n"
  },
  {
    "path": "tests/golden_tests/compile_file/dup_apply.bend",
    "chars": 34,
    "preview": "main = λa let {a1 a2} = a; (a1 a2)"
  },
  {
    "path": "tests/golden_tests/compile_file/dup_global_lam.bend",
    "chars": 45,
    "preview": "main = let {x1 x2} = $a; ((λ$a λb b) (x1 x2))"
  },
  {
    "path": "tests/golden_tests/compile_file/elif.bend",
    "chars": 211,
    "preview": "def main:\n  cond1 = 1 == 2\n  cond2 = 2 < 1\n  cond3 = 3 > 2\n  cond4 = 2 == 2\n  if cond1:\n    res = 1\n  elif cond2:\n    re"
  },
  {
    "path": "tests/golden_tests/compile_file/elif_fun.bend",
    "chars": 206,
    "preview": "main =\n  let cond1 = (== 1 2)\n  let cond2 = (< 2 1)\n  let cond3 = (> 3 2)\n  let cond4 = (== 2 2)\n  if cond1 {\n    1\n  } "
  },
  {
    "path": "tests/golden_tests/compile_file/elif_no_else.bend",
    "chars": 64,
    "preview": "def main:\n  if 1 == 1:\n    return 0\n  elif 2 == 2:\n    return 1\n"
  },
  {
    "path": "tests/golden_tests/compile_file/erased_dup.bend",
    "chars": 29,
    "preview": "main = λa let {a1 a2} = a; a2"
  },
  {
    "path": "tests/golden_tests/compile_file/error_data_def_name.bend",
    "chars": 31,
    "preview": "type A = A\nA/A = 0\n\nmain = A/A\n"
  },
  {
    "path": "tests/golden_tests/compile_file/error_messages.bend",
    "chars": 88,
    "preview": "data A = (A)\ndata B = (B)\ndata C = (B)\n\nFoo (C) = *\nFoo (D) = *\n\nFoo2 (E) = *\n\nMain = *\n"
  },
  {
    "path": "tests/golden_tests/compile_file/f24_oper.bend",
    "chars": 48,
    "preview": "main = (/ (* +124.0928 1.24) (+ 0.0 -235.12235))"
  },
  {
    "path": "tests/golden_tests/compile_file/fst_snd.bend",
    "chars": 100,
    "preview": "main = \nlet fst = (@t let (f, *) = t; f);\nlet snd = (@t let (*, s) = t; s);\n(snd (fst ((1, 3), 2)))\n"
  },
  {
    "path": "tests/golden_tests/compile_file/global_lam.bend",
    "chars": 22,
    "preview": "main = ((λ$a λa a) $a)"
  },
  {
    "path": "tests/golden_tests/compile_file/i24_oper.bend",
    "chars": 32,
    "preview": "main = (* (+ +1 -1) (- -12 +14))"
  },
  {
    "path": "tests/golden_tests/compile_file/id.bend",
    "chars": 11,
    "preview": "main = λa a"
  },
  {
    "path": "tests/golden_tests/compile_file/infer_dup.bend",
    "chars": 15,
    "preview": "main = λa (a a)"
  },
  {
    "path": "tests/golden_tests/compile_file/inlining.bend",
    "chars": 71,
    "preview": "(Num) = 42\n\n(Era) = *\n\n(RefToRef) = (Era)\n\n(Main) = (Era Num RefToRef)\n"
  },
  {
    "path": "tests/golden_tests/compile_file/just_a_name.bend",
    "chars": 4,
    "preview": "asdf"
  },
  {
    "path": "tests/golden_tests/compile_file/just_data.bend",
    "chars": 4,
    "preview": "type"
  },
  {
    "path": "tests/golden_tests/compile_file/just_paren.bend",
    "chars": 10,
    "preview": "main = *\n("
  },
  {
    "path": "tests/golden_tests/compile_file/just_rule_paren.bend",
    "chars": 6,
    "preview": "(rule)"
  },
  {
    "path": "tests/golden_tests/compile_file/let_substitution.bend",
    "chars": 26,
    "preview": "main = let x = λa (a a); x"
  },
  {
    "path": "tests/golden_tests/compile_file/let_tup.bend",
    "chars": 38,
    "preview": "main = let tup = (@x@y x, @x@y y); tup"
  },
  {
    "path": "tests/golden_tests/compile_file/lets.bend",
    "chars": 131,
    "preview": "main = \nlet a0 = λx0 x0;\nlet a1 = λx1 x1;\nlet a2 = λx2 x2;\nlet a3 = λx3 x3;\nlet a4 = λx4 x4;\n(a1 (a2 a2) (a3 a3 a3) (a4 "
  },
  {
    "path": "tests/golden_tests/compile_file/long_name.bend",
    "chars": 107,
    "preview": "(WowThis_is_a_very_long_name_no_way_ItFits) = λa a\nmain = λa (WowThis_is_a_very_long_name_no_way_ItFits *)\n"
  },
  {
    "path": "tests/golden_tests/compile_file/match.bend",
    "chars": 55,
    "preview": "main = switch x = (+ 0 1) {\n  0: λt λf t\n  _: λt λf f\n}"
  },
  {
    "path": "tests/golden_tests/compile_file/mismatched_ask_statements.bend",
    "chars": 161,
    "preview": "type Bool:\n  T\n  F\n\ndef main:\n  with IO:\n    match _ = Bool/T:\n      case Bool/T:\n        x <- wrap(0)\n      case Bool/F"
  },
  {
    "path": "tests/golden_tests/compile_file/missing_adt_eq.bend",
    "chars": 8,
    "preview": "type Adt"
  },
  {
    "path": "tests/golden_tests/compile_file/missing_ctrs.bend",
    "chars": 10,
    "preview": "type Adt ="
  }
]

// ... and 898 more files (download for full content)

About this extraction

This page contains the full source code of the HigherOrderCO/Bend GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1098 files (2.8 MB), approximately 798.4k tokens, and a symbol index with 863 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!