Imports create circular definition

I copied ramda to there and it’s working :thinking: If you append this observable

doubleMyArr = R.map(
    x => 2 * x,
    [0, 1, 2, 3]
)

Returns [0, 2, 4, 6]

I was looking to recreate thinking-in-ramda here with playbooks, but when imports from another playbook I get:

RuntimeError: circular definition

Am I importing wrong?
How to wrap a library to use here?

Hi there,

Sure - so we can isolate this issue to the ramda notebook, which displays the Circular definition error in itself. The import into Thinking in Ramda is just showing the same error message.

The gist here is, well - these are indeed circular references. For example, the Ramda _equals method calls its _uniqContentEquals method, and the _uniqContentEquals method goes back and calls _equals if it needs to traverse deeper.

If you want to bring Ramda into Observable, the simplest way, by far, is simply:

R = require('ramda')

And if you want to expose individual functions, it’d just be a list of cells like

map = R.map

To expose them as named cells.

But if you definitely want to bring Ramda in, function-by-function, it’ll likely be a bit trickier - you’ll want to group cyclical methods like _equal into cells rather than splitting into into one function per cell. That might take a while, because you’ll need to follow all of the references between the cells, but it’s certainly possible if that’s your goal.

-Tom

:heart_eyes: far easy

inside _equal I put a uniqContentEquals copy to break the circle. inside the notebook the observable #doubleMyArr work fine

I split in several function because notebook have a size limit less than ramda minified.

thanks, its work. just need import(‘ramda’). I did not know that I could import this way :rofl:

links:

For anyone discovering this thread late (like me), it seems like R = require('ramda') is no longer working, as a tutorial notebook that I made has stopped working since the last time I checked it half a year ago. This is because I was using the line

R = require('ramda')

I tried using the “module require debugger”, but I haven’t been able to get one of the sample lines to work (if you just try to import latest ramda).

R = require('ramda@0.26.1/dist/ramda.min.js').catch(() => window.R)

The solution I ultimately decided on was to downgrade to an older version of Ramda, which supports import syntax (hopefully this saves someone else a few minutes ):

import('https://unpkg.com/ramda@0.25.0/es/index.js?module')

This unfortunately goes a bit deep: in Ramda 26.1, they introduced a new method called then. JavaScript’s duck-typing for Promise objects relies on the existence of .then to decide if something is a Promise, and methods like Promise.all and the await operator implicitly call that then function.

But Ramda’s then function isn’t part of a promise, it’s just a function that happens to be called then, but with entirely different behavior.

I suppose Ramda’s users haven’t run into this very much because they aren’t using await in many ways, but this is a problem, even in Node.js: for example, this will fail:

const R = require("ramda");

(async function() {
  return await R;
})();

I’ll look into a potential solution on our side but it’s likely that we’ll want to report this up to Ramda and see if they can choose a function name with fewer dangerous side effects.

5 Likes