Giter VIP home page Giter VIP logo

Comments (7)

franciscotln avatar franciscotln commented on June 3, 2024 1

take is an operator, meaning that it takes a number max and returns a function, which takes a callbag (the original source) and then returns a new function (a new callbag, this one will be the source in the sink's eyes).
The sink (like forEach) will subscribe to the takeSource and the take operator will do its magic, meaning that it will subscribe to the original source and act as a proxy.
When the new callbag source returned by take reaches the number max of emitted items it sends a 2 to the sink but the sink will never send a 2 upwards to terminate it.
That's the meaning of it :-)
from here we can see:

const take = max => source => function takeSource(start, sink) {
  if (start !== 0) return;
  let taken = 0;
  let sourceTalkback;
  function talkback(t, d) {
    if (taken < max) sourceTalkback(t, d);
  }
  source(0, (t, d) => {
    if (t === 0) {
      sourceTalkback = d;
      sink(0, talkback);
    } else if (t === 1) {
      if (taken < max) {
        taken++;
        sink(t, d);
        if (taken === max) {
          sink(2);
          sourceTalkback(2);
        }
      }
    } else {
      sink(t, d);
    }
  });
};

module.exports = take;

ex.:

pipe(
  fromIter('abcdef'),
  take(2),
  forEach(console.log) . // a - b|
);

from callbag.

RylinMirabel avatar RylinMirabel commented on June 3, 2024 1

Why is it the case that the sink must not terminate the source? Here is a case where the implementation of callbag-take leads to a double termination

from callbag.

mperktold avatar mperktold commented on June 3, 2024

I agree with @RylinMirabel.

Maybe this situation rarely occurs in practice, but it is a bug; take should only terminate the sink if it hasn't been teminated yet itself.

from callbag.

franciscotln avatar franciscotln commented on June 3, 2024

Ok using take(2) followed by another take(2) isn't something that I considered because it's not a realistic case 😄 but in any case, this could be solved like so:
https://repl.it/repls/UntrueBisqueMice

adding a flag end: boolean

from callbag.

RylinMirabel avatar RylinMirabel commented on June 3, 2024

That still results in mutual termination between the two take callbags, although the downstream take callbag hides that from its sink. See the last two lines printed by the logger in this repl. To prevent mutual termination (which can lead to out-of-spec behaviour if unlike take, the downstream callbag does not disconnect its source from its sink upon termination), we need to check the end flag before sending any end signal (to either the source or the sink), and we need to set the end flag upon receiving any end signal. See this repl for a possible fix.

from callbag.

StreetStrider avatar StreetStrider commented on June 3, 2024

it's not a realistic case

It can occur due to some composition.

from callbag.

staltz avatar staltz commented on June 3, 2024

I followed this thread and had my own thoughts, but you all figured it out, and I agree it's a bug in callbag-take, for which a PR has solved. The spec is quite clear that termination shouldn't be mutual, so I don't think we need this issue open. :)

from callbag.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.