mndrix / list_util

Prolog list utility predicates
The Unlicense
11 stars 5 forks source link

Add slice/3 predicate #11

Closed karabut-viktor closed 9 years ago

karabut-viktor commented 10 years ago

Inspired by ruby each_slice function, slice list into chunks with N elements in each chunk.

?- slice([1,2,3,4,5,6,7], 3, Xs). Xs = [[1, 2, 3], [4, 5, 6], [7]].

karabut-viktor commented 10 years ago

I have used this function in my project, think it looks consinstent with take/3 and drop/3 predicates.

mndrix commented 10 years ago

Hi @karabut-viktor Thanks for the pull request. I can see how this predicate could be helpful. I have a couple questions:

Why are there no tests for slice/3 operating "backwards"? The mode description indicates that List and Sliced can both be unbound. Predicates in list_util should operate in all meaningful directions, so it's good to have tests for that. Usually that requires tests like:

'empty forwards' :-
    slice([], 3, L),
    L == [].
'empty backwards' :-
    slice(L,3,[]),
    L == [].

How did you decide to implement slice(List,N,Slices) is det instead of slice(List,N,Slice) is multi. In other words, why return a list of slices instead of iterating each slice on backtracking? The latter seems to have a more natural definition in Prolog, but perhaps it's not as helpful in your use case. For example, why not something like this?

slice(List,N,Slice) :-
    take(List,N,Slice).
slice(List0,N,Slice) :-
    drop(List0,N,List),
    slice(List,N,Slice).

As mentioned in #10, I plan to change the argument order of take/3 and drop/3 so that argument N is first. Since slice/3 always requires an N argument, I'd like to see the same argument order here.

Thanks again. Let me know if anything above is unclear.

mndrix commented 9 years ago

No progress in 9 months. Closing.