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

Remove outer boxing from Options #331

Merged
merged 2 commits into from
May 1, 2021
Merged

Remove outer boxing from Options #331

merged 2 commits into from
May 1, 2021

Conversation

mgeisler
Copy link
Owner

@mgeisler mgeisler commented May 1, 2021

In #219, the type parameter for Options was relaxed to ?Sized, which means that Options<T> can be a dynamically-sized type by using dyn WordSplitter as the type parameter. This allows code to freely assign both boxed and unboxed WordSplitters to the same variable:

let mut dynamic_opt: Box<Options<dyn WordSplitter>>;
dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation));
dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation)));

In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215.

By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed:

let mut dynamic_opt: Options<Box<dyn WordSplitter>>;
dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation));
dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter));

This also used dynamic dispatch at runtime.

Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error:

let mut static_opt: Options<NoHyphenation>;
static_opt = Options::with_splitter(10, NoHyphenation);
static_opt = Options::with_splitter(20, HyphenSplitter);  // <- error!

In order to add a trait for the WrapAlgorithm enum (see #325), we’re now removing the ?Sized bound on the WordSplitter type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch
and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later.

This change seems necessary since we will be adding more type parameters to the Options struct: one for the wrapping algorithm and one for how we find words (splitting by space or by the full Unicode line breaking algorithm).

Since both dynamic and static dispatch remains possible, this change should not fundamentally change the expressive power of the library.

@mgeisler mgeisler force-pushed the remove-outer-boxing branch 6 times, most recently from 0219f0c to 97794aa Compare May 1, 2021 15:52
@mgeisler mgeisler changed the title Remove outer boxing Remove outer boxing from Options May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`,
which means that `Options<T>` can be a dynamically-sized type by using
`dyn WordSplitter` as the type parameter. This allows code to freely
assign both boxed and unboxed `WordSplitter`s to the same variable:

```rust
let mut dynamic_opt: Box<Options<dyn WordSplitter>>;
dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation));
dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation)));
```

In both cases, dynamic dispatch would be used at runtime. This was
called “proper outer boxing” in #219 and #215.

By only boxing the word splitter (so-called “inner boxing”), the outer
layer of indirection can be removed:

```rust
let mut dynamic_opt: Options<Box<dyn WordSplitter>>;
dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation));
dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter));
```

This also used dynamic dispatch at runtime.

Static dispatching was also possible by using a fixed type. Trying to
change the word splitter type is a compile time error:

```rust
let mut static_opt: Options<NoHyphenation>;
static_opt = Options::with_splitter(10, NoHyphenation);
static_opt = Options::with_splitter(20, HyphenSplitter);  // <- error!
```

In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re
now removing the `?Sized` bound on the `WordSplitter` type parameter.
This makes the first block above a compile time error and you must now
choose upfront between boxed and unboxed word splitters. If you choose
a boxed word splitter (second example), then you get dynamic dispatch
and can freely change the word splitter at runtime. If you choose an
unboxed wordsplitter, you get static dispatch and cannot change the
word splitter later.

This change seems necessary since we will be adding more type
parameters to the `Options` struct: one for the wrapping algorithm
used and one for how we find words (splitting by space or by the full
Unicode line breaking algorithm).

Since both dynamic and static dispatch remains possible, this change
should not fundamentally change the expressive power of the library.
@mgeisler mgeisler enabled auto-merge May 1, 2021 17:27
@mgeisler mgeisler merged commit ab57499 into master May 1, 2021
@mgeisler mgeisler deleted the remove-outer-boxing branch May 1, 2021 17:31
@mgeisler mgeisler linked an issue May 2, 2021 that may be closed by this pull request
This was referenced May 30, 2021
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.

Add a trait for finding words
1 participant