Re: Keyword Arguments
Kevin Edwards <[email protected]> Fri, 15 Jun 2012 04:02:36 -0500
| Newsgroups | gmane.comp.lang.io |
|---|---|
| Message-ID | <[email protected]> |
On 6/14/2012 3:46 PM, Steve Dekorte wrote: > On 2012-06-14 Thu, at 10:52 AM, Kevin Edwards wrote: >> It can be suspicious to have a lot of args, but perhaps arity is >> not the best metric to use since you can just repackage the args, >> as you seem to be suggesting. >> Every 2+ argument method call can be rewritten as a series of 1 >> argument method calls which configures the object/frame. e.g. : > > I agree - a better metric would be to look at how much the data > "moves" around. The more it moves, the less it appears to be > coupled to it's logic. > > On a side note, this is why OO/actors are the only scalable > programming model. Since logic and data are localized, > communication is minimized (speed of light issues) and the Von > Neumann bottle neck is avoided. Maybe. It's hard for me to predict optimizations like that. One of my concerns is that OO method implementations are statically tied to the deeper structure of the data passed to it, which means that the core logic is mixed with packaging details. This works well in simple, homogenous systems, but more complex systems often have multiple formats for the same meaning and it can be nice for them to share core logic. As a simple and contrived example, consider a Rectangle object. Do we package that as 2 Points (x1, y1) and (x2, y2)? Or as 2 Ranges (x1, x2) and (y1, y2)? Or flat (x1, x2, y1, y2)? In OO, if we implement the logic for one format (like intersect, union, expand, contract, etc.), then we either have to convert to/from the other formats (more data moves), or we'll have to (manually) duplicate the core logic for each format we use (which can impact development time and locality due to size). So when multiple formats are used to represent similar meaning, you might see the core logic centralized into functions of higher arity where its activation frame basically serves as a common flat format to hold the minimum requirements for that function's logic. These arguments might be a small subset of the data structure passed in OO versions, which might reduce marshaling. But since I can't predict these optimizations, my plan is to use the structural equivalences of different formats to allow an optimizer to automatically substitute one for the another, or automatically specialize or factor out the core logic. Yikes! I feel like I've gone off on a long tangent since I meant to focus on the semantic equivalence between the syntaxes, not the pros and cons of optimizations. >> Every 2+ argument method call can be rewritten as a series of 1 >> argument method calls which configures the object/frame. e.g. : >> >> meth(a=1, b=2, c=3) <-> Meth clone setA(1) setB(2) setC(3) result >> >> Both versions can have the same massive, monolithic >> implementation of logic with just a difference in packaging. > > Right, the difference is that the method instance is used once and > discarded so the sender has to hold the data that was passed and > pass it in again on each call. We are left asking if the data > shouldn't belong to the receiver instead of being communicated > each time. I agree. So if we provide a simple way to hold the data rather than discarding it, would the difference just be syntactic? You also mentioned validation elsewhere. e.g. setA can perform validation. `a=1` could perform validation, too, couldn't it? More generally, I like the idea of custom setters and setSlot using the same syntax and control path (the same as any dict for that matter). > Here's a small example of how the rule of minimizing arguments > leads to power and simplicity: > > When dealing with collections, the two argument pattern is often used: > > aDict atPut(key, value) > > Changing this to a single argument form: > > aDict at(key) put(value) > > where at() returns a slot object, we find we can now pass it as > wrapper around this part of the collection - similar to passing > blocks as wrappers around particular contexts. This tends not to > be done because it requires better compilers to achieve the same > performance but it's AFAICS more expressive. I agree. My point is just the potential equivalence to the keyword arg syntax. i think part of the answer to performance is a more flexible dispatcher which can take the `at` and `put` together, so that an explicit Slot object doesn't actually have to be created if it doesn't already exist. But this may bear some similarity to multiple dispatch, so I'm interested in learning your thoughts about that anti-pattern. :-) Kevin