Skip to content

Commit 8b6f29b

Browse files
authored
Added aslice macro (#1249)
Hi, can you please consider patch to introduce the `aslice` macro in `basilisp.core`. It addresses #1248. Thanks --------- Co-authored-by: ikappaki <[email protected]>
1 parent 9869527 commit 8b6f29b

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
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 proxies (#425)
1212
* Added a `:slots` meta flag for `deftype` to disable creation of `__slots__` on created types (#1241)
1313
* Added support for f-strings (#922)
14+
* Added the `aslice` macro to facilitate the use of Python style `array[start:stop:step]` slicing in Basilisp (#1248)
1415

1516
### Changed
1617
* Removed implicit support for single-use iterables in sequences, and introduced `iterator-seq` to expliciltly handle them (#1192)

docs/pyinterop.rst

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,30 @@ Type hints may be applied to :lpy:form:`def` names, function arguments and retur
288288
Python Slicing
289289
--------------
290290

291-
Python slicing lets you extract parts of a sequence (like a list or string) using the syntax ``sequence[start:end:step]``:
291+
Python slicing lets you extract parts of a sequence (like a list or string) using the syntax ``sequence[start:stop:step]``:
292292

293293
.. code-block:: python
294294
295295
coll = [-3, -2, -1, 0, 1, 2, 3]
296296
coll[1:5:2]
297297
# => [-2, 0]
298298
299-
Basilisp does not support slicing syntax directly, but it can be achieved using the :external:py:obj:`slice` operator combined with the :lpy:fn:`basilisp.core/aget` function:
299+
Basilisp provides the :lpy:fn:`basilisp.core/aslice` macro to facilitate this syntax:
300+
301+
.. code-block:: clojure
302+
303+
(def coll #py [-3 -2 -1 0 1 2 3])
304+
(aslice coll 3)
305+
;; => #py [-3 -2 -1]
306+
307+
(aslice coll nil -3)
308+
;; => #py [-3 -2 -1 0]
309+
310+
(aslice coll 1 5 2)
311+
;; => #py [-2 0]
312+
313+
314+
This macro is just a wrapper around Python's :external:py:obj:`slice` operator combined with the :lpy:fn:`basilisp.core/aget` function:
300315

301316
.. code-block:: clojure
302317

src/basilisp/core.lpy

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,7 @@
19491949
(python/len array))
19501950

19511951
(defmacro amap
1952-
"Map ``expr`` over the Python list `array`, returning a new Python list with the
1952+
"Map ``expr`` over the Python list ``array``, returning a new Python list with the
19531953
result.
19541954

19551955
This macro initially binds the symbol named by ``ret`` to a clone of ``array``\\. On
@@ -1977,6 +1977,17 @@
19771977
(recur ~expr (inc ~idx))
19781978
~ret))))
19791979

1980+
(defmacro aslice
1981+
"Get a portion of the Python list ``array`` using a
1982+
Python :external:py:obj:`slice` instance with a single ``stop``
1983+
value, or a combination of ``start`` and ``stop`` and optional
1984+
``step`` values.
1985+
1986+
Equivalent to Python's ``array[start:stop:step]`` extended indexing
1987+
syntax. Use ``nil`` when omitting any of these fields."
1988+
[array & stop-or-start-stop-step]
1989+
`(aget ~array (python/slice ~@stop-or-start-stop-step) ))
1990+
19801991
(defn ^:inline booleans
19811992
"Dummy cast to a Python list of booleans.
19821993

tests/basilisp/test_core_macros.lpy

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,19 @@
385385
(let [l #py [1 2 3]]
386386
(is (= 6 (areduce l idx ret 0 (+ ret (aget l idx)))))))
387387

388+
(deftest aslice-test
389+
(let [l #py [-3 -2 -1 0 1 2 3]]
390+
(is (= #py [-3 -2 -1 0] (aslice l 4)))
391+
(is (= #py [-3 -2 -1 0 1 2 3] (aslice l nil)))
392+
(is (= #py [-3 -2 -1 0 1] (aslice l -2)))
393+
(is (= #py [-1 0] (aslice l 2 4)))
394+
(is (= #py [-3 -2 -1 0] (aslice l nil 4)))
395+
(is (= #py [1 2 3] (aslice l 4 nil)))
396+
(is (= #py [1 2] (aslice l 4 -1)))
397+
(is (= #py [-2 0 2] (aslice l 1 6 2)))
398+
(is (= #py [3 1 -1] (aslice l 6 1 -2)))
399+
(is (= #py [3 1 -1 -3] (aslice l nil nil -2)))))
400+
388401
(defmacro case-with-seq
389402
[]
390403
`(case :val

0 commit comments

Comments
 (0)