Skip to content

Commit 32df937

Browse files
authored
for bindings destructuring support (#867)
Hi, can you please consider attempt to support binding destructuring in `for` bindings. It fixes #774. Basically, it seems that destructuring support is not available because the general destruturing dispatch mechanism is not defined yet at the point when `for` is defined. The idea with this patch is to rename the initial implementation as `for*` and redefine `for` later on after the destructuring dispatch mechanism is available and picked up for free. Thanks Co-authored-by: ikappaki <[email protected]>
1 parent 144dc24 commit 32df937

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
* Added support for explicit cause exception chaining to the `throw` special form (#862)
1212
* Added `basilisp.stacktrace` namespace (#721)
1313
* Added support for `*flush-on-newline*` to flush the `prn` and `println` output stream after the last newline (#865)
14+
* Added support for binding destructuring in `for` bindings (#774)
1415

1516
### Changed
1617
* Cause exceptions arising from compilation issues during macroexpansion will no longer be nested for each level of macroexpansion (#852)

src/basilisp/core.lpy

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3509,12 +3509,12 @@
35093509
For comprehensions consist of a vector of bindings, with optional modifiers, and a
35103510
user specified body in an implicit ``do`` block.
35113511

3512-
Symbol bindings look like standard ``let`` bindings without destructuring. Values
3513-
bound to symbols should be sequences or otherwise seqable. The body of the ``for``
3514-
comprehension will be executed with the given symbol bound to successive values of the
3515-
sequence. If multiple sequences are bound to symbols, iteration will proceed in a
3516-
nested fashion with latest sequences iterated first and earlier sequences iterated
3517-
later (as nested ``for`` loops in procedural languages).
3512+
Symbol bindings look like standard ``let`` bindings. Values bound to symbols should be
3513+
sequences or otherwise seqable. The body of the ``for`` comprehension will be executed
3514+
with the given symbol bound to successive values of the sequence. If multiple sequences
3515+
are bound to symbols, iteration will proceed in a nested fashion with latest sequences
3516+
iterated first and earlier sequences iterated later (as nested ``for`` loops in
3517+
procedural languages).
35183518

35193519
For example, a simple non-nested for comprehension will yield::
35203520

@@ -3554,10 +3554,6 @@
35543554

35553555
(not (even? (count bindings)))
35563556
(throw (ex-info "for expression must have an even number of bindings"
3557-
{:bindings bindings}))
3558-
3559-
(not (symbol? (first bindings)))
3560-
(throw (ex-info "for expression bindings must start with symbol binding"
35613557
{:bindings bindings})))
35623558

35633559
(let [;; Generate the body of a for binding iterator, applying any relevant
@@ -3626,7 +3622,7 @@
36263622
;; (which will be applied to this iterator) and additional
36273623
;; bindings (which will be generated as new, inner iterators).
36283624
groups (split-with (fn [pair]
3629-
(not (symbol? (first pair))))
3625+
(keyword? (first pair)))
36303626
(rest pairs))
36313627
mods (first groups)
36323628
rest-bindings (second groups)

tests/basilisp/test_core_macros.lpy

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,16 @@
438438
(for [x (range 3)
439439
y [:a :b :c]
440440
:while (= y :b)]
441-
[x y]))))))
441+
[x y])))))
442+
443+
(testing "destructuring"
444+
(is (= [[1 15 5 6] [1 15 7 8]
445+
[2 15 5 6] [2 15 7 8]]
446+
(for [{:keys [a]} [{:a 1} {:a 2}]
447+
b [15 16]
448+
:while (= b 15)
449+
[x y] [[5 6] [7 8]]]
450+
[a b x y])))))
442451

443452
(deftest comment-test
444453
(is (= nil (comment 1)))

0 commit comments

Comments
 (0)