flow icon indicating copy to clipboard operation
flow copied to clipboard

Decompose dependency generation from viewing

Open krlmlr opened this issue 3 years ago • 3 comments
trafficstars

I'm having trouble creating a reprex for flow on my machine. I wonder if we can define an intermediate data structure (as a dm object or nested list) that contains everything we need to draw a diagram.

krlmlr avatar Apr 07 '22 08:04 krlmlr

Do you want flow:::flow_data() ? I used to export it so users could extend the package, but decided against it to limit features to more important features and make the package easier to navigate, I don't mind exporting it again :

flow:::flow_data(ave)
#> $nodes
#>   id block_type                                                       code_str
#> 1  0     header                                        ave(x, ..., FUN = mean)
#> 2  1         if                                   ⠀ if (missing(...)) ⠀\n⠀ ⠀ ⠀
#> 3  2   standard                                                  x[] <- FUN(x)
#> 4  3   standard g <- interaction(...)\nsplit(x, g) <- lapply(split(x, g), FUN)
#> 5 -1        end                                                               
#> 6  4   standard                                                              x
#> 7  5     return                                                               
#>   label
#> 1      
#> 2      
#> 3      
#> 4      
#> 5      
#> 6      
#> 7      
#> 
#> $edges
#>   from to edge_label arrow
#> 1    0  1               ->
#> 2    1  2          y    ->
#> 3    2 -1               ->
#> 4    1  3          n    ->
#> 5    3 -1               ->
#> 6   -1  4               ->
#> 7    4  5               ->

Created on 2022-04-07 by the reprex package (v2.0.1)

To be consistent over all functions of the package I can :

  • Have a special value for out to output data, that makes these functions pure functions OR side effect functions depending on this parameter, and flow_run() would be a bit weird since it now returns the result of the evaluation + side effect, so in this case would return the data only.
  • Have a new family of functions just to return the data, flow_data becomes flow_view_data()or flow_data_view() etc
  • Apply the side effect and return the data invisibly, I might then need a separate function to get the data from flow_run(). Now I return a widget or a path invisibly, this would be lost too.

moodymudskipper avatar Apr 07 '22 08:04 moodymudskipper

We also need to be able to draw from the data, for this no need for new function, flow_view() and friends should be able to take a data frame as a first argument. Might be better to make them generic at this point.

moodymudskipper avatar Apr 07 '22 10:04 moodymudskipper

Not sure if the generic is the best pattern here. Should we have a low-level API that consists of atomic operations (enumeration of objects, computation, pruning, display, ...)? The high-level API would then call only functions from the low-level API.

krlmlr avatar Apr 07 '22 15:04 krlmlr

  • Now that #125 is fixed so reprexes work.
  • Moreover I've documented out = "data" and out = "code" in 3aaf6616ad2aab39b3ff2ac4514d9f016430d2a1 , they provide the intermediate data structure
  • build_nomnoml_code() is the function to use to turn data into code and save_nomnoml() turns it into a file or widget, but I think it isn't useful to export them

moodymudskipper avatar Nov 24 '22 17:11 moodymudskipper