{ { "hello," " " "world!" " " " " } }
[ "hello, world! " [ blank? ] slice-when [ >string ] map ] unit-test
-{ "hello" } [ "hello" 0 rotate ] unit-test
-{ "llohe" } [ "hello" 2 rotate ] unit-test
-{ "hello" } [ "hello" dup 0 rotate! ] unit-test
-{ "lohel" } [ "hello" dup 3 rotate! ] unit-test
+{ t }
+[ "abc" sequence>slice slice? ] unit-test
+
+{ "abc" }
+[ "abc" sequence>slice >string ] unit-test
+
+
+{ "hello" } [ "hello" 0 rotate-headwards ] unit-test
+{ "llohe" } [ "hello" 2 rotate-headwards ] unit-test
+{ "hello" } [ "hello" dup 0 rotate-headwards! ] unit-test
+{ "lohel" } [ "hello" dup 3 rotate-headwards! ] unit-test
{ { } } [ { } [ ] map-concat ] unit-test
{ V{ 0 0 1 0 1 2 } } [ 4 iota [ iota ] map-concat ] unit-test
: cut-slice* ( seq n -- before after )
[ head-slice* ] [ tail-slice* ] 2bi ;
-: rotate ( seq n -- seq' )
+: ?<slice> ( from to/f sequence -- slice )
+ over [ nip [ length ] [ ] bi ] unless <slice> ; inline
+
+: sequence>slice ( sequence -- slice )
+ [ drop 0 ] [ length ] [ ] tri <slice> ; inline
+
+: length- ( n sequence -- m ) length swap - ; inline
+
+: rotate-headwards ( seq n -- seq' )
cut prepend ;
-:: rotate! ( seq n -- )
+: rotate-tailwards ( seq n -- seq' )
+ over length- cut prepend ;
+
+:: rotate-headwards! ( seq n -- )
n seq bounds-check length :> end
0 n [ 2dup = ] [
[ seq exchange-unsafe ] [ [ 1 + ] bi@ ] 2bi
] until 3drop ;
: all-rotations ( seq -- seq' )
- dup length iota [ rotate ] with map ;
+ dup length iota [ rotate-headwards ] with map ;
<PRIVATE