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
Combine
trait for string and collection concatenation
#203
Closed
Closed
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
55e9cb4
Initial version of "`Compose` trait" RFC
apoelstra 565a58f
Add trait def for Compose
apoelstra 7efd853
Add note to impl ++ for Vec, DList, etc
apoelstra f01367c
Add `Compose` impl for `Path` and `Iterator` (thanks @olivier-renaud)
apoelstra dd0347a
Update `Vec` and `Bitv` to "all collections"
apoelstra 8de7aef
Rename Compose/compose to Combine/combine
apoelstra bb7070f
Declare precedence of ++ (between bitwise and comparisons)
apoelstra 1132cc0
Update for @huonw's comments -- in particular, remove `Iterator` impl
apoelstra File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
- Start Date: 2014-08-17 | ||
- RFC PR #: (leave this empty) | ||
- Rust Issue #: https://github.com/rust-lang/rust/issues/16541 | ||
|
||
# Summary | ||
|
||
A `Compose` trait is added with a single function `compose` which desugars to | ||
the `++` operator. The `Add` implementation for `String` is replaced by one | ||
for `Compose`. | ||
|
||
# Motivation | ||
|
||
As @huonw mentions in https://github.com/rust-lang/rust/issues/14482, mathematical | ||
convention is that addition is commutative. The stdlib already follows mathematical | ||
convention in some cases (for example, `Zero` requires `Add` and is expected to | ||
be the additive identity; ditto for `One` and `Mul`). | ||
|
||
It is an (often unstated) assumption in many algorithms that `+` is a commutative | ||
operator. Violating this assumption in the stdlib forces programmers to memorize | ||
that `+` means something different in rust than it does everywhere else, and also | ||
risks encouraging abuse of operator overloading. | ||
|
||
There is a postponed proposal regarding having unit tests for Traits which enforce | ||
invariants; commutativity of `+` is an natural one and it would be bad if it was | ||
unenforcable because standard library was violating it. | ||
|
||
# Detailed design | ||
|
||
Currently everything in the stdlib which implements `Add` implements `add` as a | ||
commutative operator, except for strings. Therefore I propose: | ||
- Introduce a `Compose` trait with a `compose` function that sugars to the `++` | ||
operator. | ||
- Implement this on `String` for concatenation. This replaces `Add` for `String`. | ||
- Implement this on `Bitv`, `DList`, `Vec` and any other "linear" collections | ||
where concatenation makes sense. | ||
- Add "must be commutative" to the documentation for `Add`. | ||
- Add "must be associative" to the documentation for `Compose`. | ||
|
||
The signature of `compose` is exactly the same as that for `add` and the other | ||
binary operators: | ||
|
||
````rust | ||
pub trait Compose<RHS,Result> { | ||
/// The method for the `++` operator | ||
fn compose(&self, rhs: &RHS) -> Result; | ||
} | ||
```` | ||
and will be updated alongside the other binary-operation traits as the trait system | ||
is revamped. (For example, adding `ComposeAssign` for in in-place `++=` or making | ||
`Result` an associated item.) | ||
|
||
For those interested in algebraic names, this makes `++` into a semigroup operator. | ||
Users who want an abelian group can then use `Add+Zero+Neg` (or `Add+Zero+Sub`, | ||
this ambiguity should probably be addressed in a later RFC related to fixing the | ||
numeric traits once we have associated items); users who want an arbitrary group | ||
can use `Mul+One+Div`; users who want a monoid can use `Compose+Default`, etc. | ||
|
||
This way nobody is surprised by generic code which sometimes does the Wrong Thing, | ||
but we avoid having a Haskell-like scenario where every category-theoretic object | ||
is supported (with corresponding mental load). We just have a few binary operators | ||
each with simple conventions. | ||
|
||
# Drawbacks | ||
|
||
Code which uses `+` to add strings will need to use `++` instead. | ||
|
||
# Alternatives | ||
|
||
Leave `+` as is. | ||
|
||
# Unresolved questions | ||
|
||
`Compose` should also be used for function compositions, at least for single-argument | ||
functions `T->T`. How would this interact with our current/future coherence rules? | ||
|
||
Where else should `Compose` be used? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "everywhere" isn't really true, since there are other programming languages that use + noncommutatively.