[ 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)