jscad / csg.js

DEPRECATED: CSG Library for JSCAD (See the link below)
https://github.com/jscad/OpenJSCAD.org/tree/master/packages/modeling
MIT License
217 stars 56 forks source link

V2 : ensure curryability of api #114

Open kaosat-dev opened 6 years ago

deckar01 commented 6 years ago

Copying a related discussion per @z3dev's request. I said:

After iterating on the pipeline function a little bit, I no longer think currying is necessary to make a useful pipeline. Currying is elegant and familiar, but orthogonal to the goal of stacking operations without nesting.

const pipeline = (...ops) => ops.reverse().reduce(
  (args, x) => x && x.call ? [x(...args)] : [x, ...args], []
)

function main () {
  return pipeline(
    scale, 10,
    translate, [0, 0, 1.5],
    union,
    difference(
      cube({size: 3, center: true}),
      sphere({r: 2, center: true})
    ),
    intersection(
      sphere({r: 1.3, center: true}),
      cube({size: 2.1, center: true})
    )
  )
}

Would you be interested in a PR that adds this functionality to the API in the master branch? No API change or new dependencies, just a 3 line pipeline utility. I am personally fine with copying this between my script since it is so compact, but I think it could really help clean up the complicated nesting most users will inevitably run into. I was constantly having to break operation chains off into variables at awkward points that were hard to name.

https://plus.google.com/u/0/104998044612346770322/posts/V45KdQ2EQiq

Edit: Once functions are normalized and curried, the same pipeline function could be used without modification. Currying would just make it more readable by explicitly grouping related args.

pentacular commented 5 years ago

I think there also needs to be a distinction between user APIs and system APIs.

It should be straight-forward to write something at the user API level which lets people write circle().translate() If that's what they want to write.

That can translate into system calls which are equivalent to translate(circle({})) without any real difficulty.

Or if they want pipelining, or to write a compiler, or to ...

The system level API doesn't need to be user friendly, and user APIs don't need to be consistent or elegant -- just convenient. :)

z3dev commented 3 years ago

Once functions are normalized and curried, the same pipeline function could be used without modification. Currying would just make it more readable by explicitly grouping related args.

@deckar01 JSCAD V2 has been released, and I’m very interested in the possibilities of using the pipeline (above) with V2 functions. Have you tried anything with V2?

deckar01 commented 3 years ago

I ended up making a wrapper module. I track csg.js as a peer dependency, so it should work with any published version. It injects a curried copy of all of the functions into the API with a $ prefix, along with the $pipeline utility, and a $ shortcut.

https://github.com/deckar01/csg-curry

It looks like the the latest release (0.7.0) was cut from master, so I'm not sure if it is V2. I pulled in the latest changes into my fork of OpenJSCAD.org and it seems to still work fine.

z3dev commented 3 years ago

@deckar01 the V1 code is frozen, including the CSG/CAG/etc classes.

I would guess that changes might be required for V2. Here’s a summary of what’s different, which should help working with V2.

https://openjscad.org/dokuwiki/doku.php?id=changes_v2

And of course, there are some special steps to develop changes for V2 as well.

https://openjscad.org/dokuwiki/doku.php?id=early_v2

z3dev commented 3 years ago

It looks like the the latest release 0.7.0 was cut from master, so I'm not sure if it is V2. I pulled in the latest changes into [my fork of OpenJSCAD.org and it seems to still work fine.

@deckar01 I looked over the pipeline code. Nice and simple. But it won’t work with V2 JSCAD, as the API is totally different. I think that the $pipeline function will still work, but the ability to use the V2 API with the pipeline needs to be verified.

Do you think the pipeline would be useful as part of V2?