You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@mesos.apache.org by "Benjamin Mahler (JIRA)" <ji...@apache.org> on 2015/04/06 21:02:12 UTC

[jira] [Updated] (MESOS-785) Extend stout/try to support functional composition

     [ https://issues.apache.org/jira/browse/MESOS-785?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Benjamin Mahler updated MESOS-785:
----------------------------------
    Description: 
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?

  was:
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.

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();
}

[~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.
Try<string> result = 
  _fetch(...)
    .and(chmod...)
    .and(extract...)
    .and(chown...);

Thoughts? How do other languages express this?


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