Functions VS Methods - Gozala/streamer GitHub Wiki

Design

Streamer library intentionally uses functions for stream manipulation instead of methods. This unfortunately makes complex code harder to read as it requires reading from inner functions to outer functions:

var pageContents = streamer.flatten(streamer.map(function(id) {
  return readURI(baseURL + '?id=' + id)
}, streamer.filter(function(id) {
   return isItFoo(id) && isItBar(id)
}, ids))

If library used methods for stream manipulation, same code have been rewritten in more readable (reads from left to right) way:

var pageContents = ids.filter(function(id) {
  return isItFoo(id) && isItBar(id)
}).map(function(id) {
  return readURI(baseURL + '?id=' + id)
}).flatten()

Unfortunately method based API had some important constraints. All the streams would have had to share a prototype with API methods in it. Third party APIs would either have had to extend stream prototype with a risk of naming conflicts or would have had a different signatures. For these reasons streamer core API is defined as functions, making it possible to write more readable code by employing local variables:

var pageIds = streamer.filter(function(id) {
   return isItFoo(id) && isItBar(id)
}, ids)
var contentStreams = streamer.map(function(id) {
  return readURI(baseURL + '?id=' + id)
}, pageIds)
var pageContents = streamer.flatten(contentStreams)

Still there is multiple ways to improve readability:

Local variables

Same code may be made more readable by doing one step at a time:

var goodIDs = streamer.filter(function(id) {
   return isItFoo(id) && isItBar(id)
}, ids)
var contentStreams = streamer.map(function(id) {
  return readURI(baseURL + '?id=' + id)
}, goodIDs)
var pageContents = streamer.flatten(contentStreams)

DSL

Naming all these intermediate steps may become quite a hassle, there for streamer provides (fab) like DSL for chaining:

var pageContents = ((streamer.run.on)
  (ids)
  (streamer.filter, function() {
    return isItFoo(id) && isItBar(id)
  })
  (streamer.map, function() {
    return readURI(baseURL + '?id=' + id)
  })
  (streamer.flatten))

If you prefer some other type of DSL for chaining it's also easy to do with a help of uses library.

⚠️ **GitHub.com Fallback** ⚠️