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

Can flyd streams be made lazy ? #198

Closed
sourcevault opened this issue Jul 5, 2019 · 9 comments
Closed

Can flyd streams be made lazy ? #198

sourcevault opened this issue Jul 5, 2019 · 9 comments

Comments

@sourcevault
Copy link
Contributor

when you have nodejs style API, you have this:

var fs = requie('fs');

var flyd = requie('flyd');

var read_hello = flyd.stream();

fs.readfile('./hello.txt',read_hello); // <- this runs immediately :(

read_hello.map(function(){/...../});

Is there some magic I can do to turn the stream upside down to make it lazy ?

var fs = requie('fs');

var flyd = requie('flyd');

var read_hello = flyd.stream();

read_hello = flyd.lazy(function(stream){

  fs.readfile('./hello.txt',stream);

});

read_hello.map(function(){/...../}).run(); // <- runs here !

Cheers !

@nordfjord
Copy link
Collaborator

nordfjord commented Jul 5, 2019

you could maybe do something like:

const start = flyd.stream();
const readFile = (file)=> {
  const s = flyd.stream();
  fs.readFile(file, s);
}
const read_hello = start.chain(()=> readFile('./hello.txt'));

read_hello.map(fileContents => console.log(fileContents));

start(true);

@StreetStrider
Copy link
Contributor

Afaik, flyd is push by it's nature.
Check for pull-stream, Highland.js (they're oriented to pull strategy) and most.js (starting cold).

@sourcevault
Copy link
Contributor Author

@StreetStrider it should be possible to express a push stream as a pull stream given that their operations are similar. I do not know what the theoretical equivalence law is.

@nordfjord yep - that seems like a cool workaround :D using chains !

Thank you both !

@sourcevault
Copy link
Contributor Author

sourcevault commented Jul 3, 2020

Hi @nordfjord !

const read_hello = start.chain(()=> readFile('./hello.txt'));

readFile would return undefined not a flyd stream.

I can think of creating a wrapper and create .run method but there might be a clever trick.

@sourcevault
Copy link
Contributor Author

  var flyd = require('flyd')

  var fs = require('fs')

  readfile = function(name){

    var s = flyd.stream()

    var F = fs.readFile(name, function(err, data){return s(data.toString())})

    setTimeout(F, 0);

    return s;
  };

  stream = readfile('file1.txt');

  stream.map(function(data){

    console.log(data);

  });

Using setTimeout as a hack.

@nordfjord
Copy link
Collaborator

Hey @sourcevault ! Glad you found a solution!

I think you might be able to make a generic nodeback -> Stream function.

function fromNode(fn) {
  return (...args)=> {
    const s = stream()
    fn(...args, (err, data)=> s(data))
    return s
  }
}

Then you could use that as:

const readFile = fromNode(fs.readFile)

readFile('file1.txt')
  .map(x => x.toString())
  .map(console.log)

@sourcevault
Copy link
Contributor Author

Hallo @nordfjord !! 😀

const readFile = fromNode(fs.readFile)

readFile('file1.txt') // <-- 1) This still runs immediately 
  .map(x => x.toString()) // <-- 2) This runs after [1]
  .map(console.log)

I don't think there is a way without using setTimeout to delay [1].

@nordfjord are you familiar with mostjs ?

https://github.com/cujojs/most

It runs / delays all side effects till all the .maps etc are defined, its said to be lazy.

flyd is more 'active', but I am trying to find a way to make it lazy, I hope I am making some sense.

@nordfjord
Copy link
Collaborator

don't worry, I understand what you're trying to accomplish.

I'm curious about your use case though, what use case do you have that requires lazy streams?

@sourcevault
Copy link
Contributor Author

It is more of a intellectual curiosity when you corner me like that @nordfjord ☺️.

I have no immediate usecase, most streams work fine on node events like fs.readFile.

But then things like fs.watch flyd is a better choice.

I was hoping if there was a way to make flyd work for all most.js usecases.

I have looked at some libuv internals and using setTimeout 0 with flyd should be fine.

libuv runs everything with setTimeout 0 in the next tick, making it lazy so to speak.

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

No branches or pull requests

3 participants