digitalmars.D - Imperative port of haskell optics stated simply
- monkyyy (41/41) Jul 07 Haskell as always got an idea first by mashing some keys together
Haskell as always got an idea first by mashing some keys together and a surprisingly something compiled then it takes decades to untangle it. See monads. Math NERDS, then spend 100000s of big math words and arcane symbols intentionally hiding the result. See monads. This is my current understanding of the "optics" libs and how they could be metaprogrammed in d: --- Optics in imperative languages are a kind of sumtypes built as wrappers around `void*` that contain a metaprogram on assignment. Note, everything here is a reference type and therefore can dodge complexity of handling the expression problem and determining `.sizeof`. If you wanted a `sumtype!(vec!2,vec!3...vec!99)` thru no fault of the author given the design goals, you would need to initialize 100 templates preemptively even if you never used them, you would need to gather them all into one place, and you would be picking an upper bound on your vec family. `void*` does not need to know `.sizeof` and so you can make tradeoffs of knowing where the data is with the openness of your sumtype. `Lens!(vec!2,vec!3)` handles the overlap of the `fields` shared by the types it is initialized with i.e. `x,y` and maybe can make a `nullable!z`; this makes an opDispatch!"x" a trivial mixin of a cast and you get a ref of a `vec!?.x`. On opAssign you check that any assignments match the generated schema, this allows you to assign vec!99 in a separate compilation or after the lens was initialized. Implicitly vec!1 would fail the assignment at compile time. `Prism!(float)` grabs a bit of data on opAssign to produce a range, a vec!99 should be range of 99 floats, this may discard other fields and its probably not that efficient as its going to be a slice of offsets. You may also want to grab a specific field such as `Prism!(float,"z")`. `Iso` is a 0th special case of a lens, you dont feed it `vec!2`, instead it captures some metadata, such as `dim` from the family of vec's or typeinfo These types should compose `Lens!(vec!3)` should be assignable to `Lens!(vec!2). Prisms should "add" together, allowing for the one pointer to see many ranges. An `Affine` should be a combination of a `Len-y` and a `Prism-y` optic, consider `Affine!(Lens!(vec!2),Prism!(float,"radius"),Prism!(float,"size"))` and `square` and a `circle`, using the `Lens` you should be able to move the shape around, with the prisms you should be able to do some kind of pattern matching on the remaining fields
Jul 07








monkyyy <crazymonkyyy gmail.com>