why need `constant` when implementing `html` of stdlib in a notebook

Since there is no development version of Observable standard library to import from, I decided to try to make the standard library available through notebooks. see my related question here

To start easy, I have tried to implement html of stdlib inside a notebook. The method is almost copy and paste the source code. However, I realized that the source code used constant which I didn’t. I am afraid I may miss something important when implement html (in my notebook I called it ohtml) in a notebook.

Could anyone help me understand why using constant(html)? Thanks a lot!

You can see the detail question description, source links and code in the notebook below.

See this outstanding issue:

The cause is that the definition of the builtin function is passed directly to variable.define here:

As such, the function is interpreted as a variable definition (a function that is invoked whenever a variable’s inputs change to compute the variable’s new value), rather than the value itself. This is appropriate for reactive values such as notebook cells, but it’s not appropriate for the standard library builtins because these builtins normally do not depend on other variables (at least reactively).

We’ll fix this in a future version of the runtime so that you don’t need to wrap builtin functions with another function that returns the function, but in the meantime it’s necessary when passing a library of builtins to the Runtime constructor.

2 Likes

Thank you so much Mike! Your reply makes perfect sense!

Also thank you very much for creating Observable notebook, it is truly magical and wonderful!

1 Like

Hi @mbostock and everyone,

I thought I understand your answer above, so this time I tried to write a simple builtin function called addo to simply add w with h, using constant to wrap the reactive function add.

I expected add will react to changes of h, but not addo. However, both add and addo react to the changes of h.

You can see my code here. Could you help me figure out where did I do wrong?

Thanks!

I’m not sure what you’re trying to do, but you might be able to glean some insight into how your notebook code turns into JS by taking a look at the ES module version of your notebook:

https://api.observablehq.com/@embracelife/html-stdlib-rewrite.js?v=3

Note in particular that add is in the list of inputs to addo and h is in the list of inputs to add, so when h is changed, both add and addo will change as well. You can also get this info visually from the official notebook visualizer:

1 Like

Hi,
You don’t have to wrap your addo, add functions. Those are functions you are creating and not Observable builtin functions. You can just use function name(arg, …), or an arrow; name = (d,i)=>{} But I may not be understanding the problem correctly.

The observable builtin stdlib functions are here, https://github.com/observablehq/stdlib
it sound like you would have to wrap these if you’re using them in a notebook:
(stdlib.DOM, svg, html, etc)

if you wanted add() to react to changes in h, but not addo, you don’t want to put the notebook variable h in addo.
maybe:
function add() {return w+h} will react to cell variable h
function addo(h) {return w+h} will not react to changes in cell variable h, but will react to cell variable w.

Good Luck

1 Like

Hi @bgchen,

Thank you so much for introducing the ES module version and Notebook visualizer! They seem to be quite useful.

Thanks @bchoatejr for your reply too!

I think I had some confusion of the reference of builtin functions in Observable. Right now, I think when Mike talks about builtin functions, he meant stdlib functions of Observable exclusively. My mistake was that I took builtin functions to be functions I want to write for my own little library using Observable notebook.

My intention is to rewrite a html inside a notebook which can behave exactly the same to the html in stdlib, so that I can debug and see how the html works step by step using debugger tool. But first of all, Is my rewrite (almost just copy and paste) of ohtml the proper way to achieve it? if not, how would you do it?

Besides rewriting stdlib in notebook, what I really want is to write my own small library using Observable notebook. Suppose I want to write a small library which rewrites all native Array methods, and use it in other notebooks. I think I don’t need to make my library functions non-reactive in order for it to work properly. Right?

Thanks a lot!

Here’s how I’d do it (this might be what you tried, I have to admit I didn’t look too hard at your approach):

1 Like

Thanks @bgchen for this nice notebook!

I noticed that you didn’t use constant to wrap html. But it works and html becomes debuggable. I guess I should not be bothered about using constant in notebook.