Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add zip, zip-with and zip-all functions #15

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Conversation

fraya
Copy link
Member

@fraya fraya commented Nov 4, 2024

No description provided.

@fraya fraya requested a review from cgay November 4, 2024 16:59
Remove links to DRM for 'array', 'deque' and 'string'.

The function operates on two sequences (like :drm:`range`,
`array`, :drm:`list`, `deque` or `string`) and
transforms them in a :drm:`<sequence>` of pairs, each element from
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make these references to the types: :drm:`<range>`, :drm:`<vector>`, :drm:`<list>`, :drm:`<deque>`, or :drm:`<string>`.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it, in a previous commit, but wrong. Thanks.

let b = #('a', 'b');

let zipped = zip(a, b);
format-out("%=", zipped); // Output: #(#(1, 'a'), #(2, 'b'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but I prefer the following style, because it doesn't have the distraction of the format-out call.

let a = #(1, 2);
let b = #('a', 'b');
zip(a, b)
// => #(#(1, 'a'), #(2, 'b'))

:signature:

zip-all (sequences) => (zipped)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zip-all #rest *sequences* => *zipped-sequence*

= map;

define function zip-all
(#rest sequences) => (zipped :: <sequence>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name "sequences" is misleading here since this function will only work with lists. Should it work with sequences in general? (I think so.) Perhaps you can do it by calling forward-iteration-protocol on each sequence directly.

add(zipped, map(head, seqs)))
end
end;
if (empty?(sequences)) #() else recur(sequences, #()) end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a big fan of the iterate macro, which would look something like this:

define function zip-all (#rest lists) => (zipped :: <list>)
  iterate loop (lists = lists, zipped = #())
    if (any?(empty?, lists))
      reverse!(zipped)
    else
      loop(map(tail, lists), pair(map(head, lists)))
    end if
  end iterate
end function

It basically combines the definition of the local method and the initial call to it.

@@ -588,3 +588,29 @@ define method precedes?(elt-1, elt-2, seq :: <sequence>,
not-found;
end block;
end method precedes?;

define function zip
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming is hard, so I won't claim that this is definitely better, but one potential alternative is to call this function zip2 and call zip-all just zip so that it matches other popular languages (Python).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants