[
https://issues.apache.org/jira/browse/MESOS-785?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15590263#comment-15590263
]
Benjamin Mahler commented on MESOS-785:
---------------------------------------
(Some additional context from a discussion awhile back with [~benjaminhindman])
In order to preserve our error composition technique [~benjaminhindman] had
shown me an approach like this:
{code}
Try<T> t;
Try<X> = t.bind(
[=](const T& t) { return t.toX(); }
[=](const Error& error) { return Error("Additional context: " +
error.message); }
);
{code}
We were trying to avoid the issues around error message composition that
currently exist with Future chaining (where the design of .then prevents the
caller from adding additional error message context).
> Extend stout/try to support functional composition
> --------------------------------------------------
>
> Key: MESOS-785
> URL: https://issues.apache.org/jira/browse/MESOS-785
> Project: Mesos
> Issue Type: Improvement
> Components: stout
> Reporter: Ian Downes
> Priority: Minor
> Labels: c++11
>
> Motivating example was fetching a list of URIs where each 'fetch' is actually
> a sequence of operations: fetch the uri to a local file, pass the local file
> on to chmod or extract, and pass on to chown it or the directory. Individual
> operations needn't be asynchronous.
> This can be written using Futures but is potentially confusing when the code
> is actually synchronous.
> {code}
> Future<Nothing> fetch(
> const CommandInfo& commandInfo,
> const string& directory,
> const HDFS& hdfs,
> const Option<string>& frameworks_home,
> const Option<string>& user)
> {
> foreach (const CommandInfo::URI& uri, commandInfo.uris()) {
> bool executable = uri.has_executable() && uri.executable();
> // This code is synchronous!
> Future<string> result =
> _fetch(uri, directory, hdfs, frameworks_home)
> .then(lambda::bind(_chmod, lambda::_1, directory, executable))
> .then(lambda::bind(_extract, lambda::_1, directory, !executable))
> .then(lambda::bind(_chown, lambda::_1, directory, user));
> if (result.isFailed()) {
> LOG(ERROR) << "Fetch of uri '" << uri.value() << "' failed: " <<
> result.failure();
> return Future<Nothing>::failed(result.failure());
> }
> }
> return Nothing();
> }
> {code}
> [~bmahler] and I had these thoughts:
> * .ifSome() and .ifError() to express control flow.
> * .and() for chaining to make it clear the code is synchronous and also that
> it will short-circuit error.
> e.g.
> {code}
> Try<string> result =
> _fetch(...)
> .and(chmod...)
> .and(extract...)
> .and(chown...);
> {code}
> Thoughts? How do other languages express this?
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)