Prev: FAQ Topic - How can I access the client-side filesystem? (2010-05-11)
Next: apparently wrong function.
From: Garrett Smith on 16 May 2010 03:02 Scott Sauyet wrote: > Andrew Poulos wrote: >> On 16/05/2010 2:34 AM, Scott Sauyet wrote: >>> Thomas 'PointedEars' Lahn wrote: >>>> Irrelevant. >>> The requirements I had for my version of this are irrelevant, but your >>> fantasies of cases like this are relevant?: >>> | $prop(obj, 'prop/erty%.prop#erty.%[prop|erty]', '%') >>> Perhaps we inhabit different parts of the development world. Are you >>> in academia by any chance? In the business community I work in, we >>> write code to solve business needs. We try to keep it as simple as >>> possible, sacrificing simplicity for completeness only when real-world >>> considerations force us to. Is your experience very different? I do not believe that the business is in need of a property access function. It is a programmer decision to create the abstraction which provides little apparent value, other than convenience. >> It reads like your saying that improper, or incomplete, testing is >> important for solving business needs? > > I think you need to re-read the thread, or even the section you > quoted. > > I was discussing API design and the relative benefits of API > simplicity and API completeness. Thorough testing is quite important > in this environment. But it's also common to document the limited set > of values that a system can handle and not try to make it especially > graceful if values outside that range are supplied. The environment > that Thomas seems to be operating in requires that much more weight be > given to completeness; you couldn't simply document that your function > will not handle negative numbers. You would have to gracefully handle > this illegitimate input (hopefully with at least a useful warning > message!) > > This is a balancing act. The simplest APIs are generally less > complete; The most complete ones are generally less simple. I'm > afraid you can't have it all. > Matt's three-parameter solution is more complex and less complete than the two parameter approach that uses an array as the second parameter. The idea to add documentation for the added complexity is not justified. It seems to be an indication of poor design. With the array-based solution, documentation should not be needed at all. Matt's solution should be marginally less efficient (though not measurably so under normal circumstances). The string value is used with property access operator, getting a `split` property, resulting in the creation of a String object (via [[ToObject]]). The property name `split` is then resolved on `String.prototype` and called as a function call. If the character to split on was not present in one of the properties, the result is the desired array of string values to search. Instead, the desired array of string values to search could be passed in. The only advantage Matt's solution has is that it looks closer to a normal property access. That advantage is nice, but outweighed by complexity it introduces. If having something that looks like the property access operator is more desirable, then the property access operator fits that perfectly. The property access operator is easy to understand. It is more efficient. It is documented in the ECMA-262 specification. Matt's initial solution is more complicated than the others, it can fail, it is slightly less efficient, and now you are suggesting that it needs documentation. -- Garrett comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Thomas 'PointedEars' Lahn on 16 May 2010 07:56 Scott Sauyet wrote: > Thomas 'PointedEars' Lahn wrote: >> Scott Sauyet wrote: >>> Thomas 'PointedEars' Lahn wrote: >>>> Scott Sauyet wrote: >>>>> Thomas 'PointedEars' Lahn wrote: >>>>>> A helper function that by design makes it hard for it to be reused, >>>>>> that makes code less legible and less reliable than if it was not >>>>>> used, a function that is not generally applicable, is not a goal to >>>>>> be attained. >>>>> I can buy this: "A helper function that by design makes it hard for >>>>> it to be reused, that makes code less legible and less reliable than >>>>> if it was not used, is not a goal to be attained." But I'm not buying >>>>> your "generally applicable" clause. >>>> Perhaps you are misunderstanding, then. >>> Maybe, but I think it's more that I disagree. >> ISTM you do not know what you are disagreeing with. > > And ISTM that you are trying to solve a different problem than I am. > Matt hasn't chimed in here lately Correct. He has specified the problem and his suggestion to it right from the start. He has provided his implementation in a followup to his OP then, which was then subject to further discussion. > so it's not clear which approach is closer to his needs. Yes, it is. > I've explained clearly what my goals from the code are. You've explained > what yours are. Mine are the same as Matt's: Error-free deep property access. Matt is willing to accept that either certain properties cannot be accessed with it or that the caller is required to specify a delimiter that is not contained in a property name. I am not, for the reasons already given. > [...] >>>>> Code needs to have an reasonable domain. >>>> The domain is property access. >>> Not to my mind. And perhaps that is the crux of the matter. >> Yes, perhaps you do not read what you are discussing about. The whole >> point of this was guarded property access. Read the Subject, for >> goodness' sake! > > So the subject line in a USENET posting is supposed to be more > important than the direction of the subsequent conversation? Are you being intentionally obtuse? The Subject of the postings of this thread are continuing to describe the problem to be solved in this case! >>> The language already has '[]' for property access, and a shortcut for >>> some simpler cases: '.'. I have little need to use a function that has >>> the same domain as those language constructs. >> >> Then you are in the wrong thread. The problem was that the property >> access `foo.bar.baz' would fail if `foo.bar' did not store a value that >> can have properties. As a solution, a function was suggested that does >> the property access instead and returned `undefined' or `null' instead of >> throwing an exception then. > > Right, the goal was to get the value of "foo.bar.baz" if "foo" exists > and has a property "bar", which in turn has a property "baz". No, it was not. ..-<news:083890c5-1c81-48db-ac47-adced2d307e8(a)b21g2000vbh.googlegroups.com> | | Does anyone here use a general convenience method for deep property | access that will not throw an error if any property along the chain is | undefined? | | For example: | | deep(document, "body.firstChild.style.backgroundColor"); | or | deep("myElementId.childNodes[3].id"); | or | deep( myJsonObject, | "locations.ca.sandiego.directory.people.smith.john.phone"); | | This would return undefined if any element along the chain is not ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | there, or index is out of bounds, etc. If the chain gets to the end, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | it would return the last-evaluated value. This would be convenient for ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | accessing deep properties of objects that may or may not exist, and | not having to manually check the chain in your code. [...] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Since you are apparently not paying attention, it does not make sense for me to continue discussing this with you. PointedEars -- var bugRiddenCrashPronePieceOfJunk = ( navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1 ) // Plone, register_function.js:16
From: Scott Sauyet on 17 May 2010 09:12 On May 16, 3:02 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > Scott Sauyet wrote: >> Andrew Poulos wrote: >>> On 16/05/2010 2:34 AM, Scott Sauyet wrote: >>>> Thomas 'PointedEars' Lahn wrote: >>>>> Irrelevant. >>>> The requirements I had for my version of this are irrelevant, but your >>>> fantasies of cases like this are relevant?: >>>> | $prop(obj, 'prop/erty%.prop#erty.%[prop|erty]', '%') >>>> Perhaps we inhabit different parts of the development world. Are you >>>> in academia by any chance? In the business community I work in, we >>>> write code to solve business needs. We try to keep it as simple as >>>> possible, sacrificing simplicity for completeness only when real-world >>>> considerations force us to. Is your experience very different? > > I do not believe that the business is in need of a property access > function. It is a programmer decision to create the abstraction which > provides little apparent value, other than convenience. You're right. It's not a business need, but a programmer convenience. But when programming in a business environment, it's often the concerns about simplicity that trump those of convenience. >> This is a balancing act. The simplest APIs are generally less >> complete; The most complete ones are generally less simple. I'm >> afraid you can't have it all. > > Matt's three-parameter solution is more complex and less complete than > the two parameter approach that uses an array as the second parameter. Do you think it's more complex to implement or a more complex API? The former might well be true. But I don't buy the latter at all. $prop(obj, "foo.bar.baz") vs. $prop(obj, ["foo", "bar", "baz"]); Even in those rare cases where a delimiter is needed, I would argue that the first is simpler to read and understand that the latter. And mine went one step further, eliminating the first parameter, so it looked just like fetch("obj.foo.bar.baz"); > The idea to add documentation for the added complexity is not justified. > It seems to be an indication of poor design. > > With the array-based solution, documentation should not be needed at all. How much more documentation is needed for the string version than the array version? > Matt's solution should be marginally less efficient (though not > measurably so under normal circumstances). The string value is used with > property access operator, getting a `split` property, resulting in the > creation of a String object (via [[ToObject]]). The property name > `split` is then resolved on `String.prototype` and called as a function > call. If the character to split on was not present in one of the > properties, the result is the desired array of string values to search. Yes, but if this sort of micro-efficiency is important, you probably shouldn't be adding such a function call in the first place, just do the "if (obj && obj.foo && obj.foo.bar && obj.foo.bar.baz)" bit yourself. Remember also that mine was solving a somewhat broader problem than Matt's: fetch("obj.prop1.prop2[current.left.size].color"); which seems much clearer to me than $prop(obj,"prop1","prop2",$prop(current,"left","size"),"color"); > Instead, the desired array of string values to search could be passed in. > > The only advantage Matt's solution has is that it looks closer to a > normal property access. > > That advantage is nice, but outweighed by complexity it introduces. That's where I disagree. The whole point in my version was to reduce the complexity of the code by pulling the checks for undefined/null/ whatever out of the main code and into a function, leaving clear the intent of the call. The complexity was in implementation, which bothers me little, and not in API, where it bothers me much more. > If having something that looks like the property access operator is more > desirable, then the property access operator fits that perfectly. > > The property access operator is easy to understand. It is more > efficient. It is documented in the ECMA-262 specification. Right. But then you need to do all the intermediate checks for bad values in your main code. Often that's no big deal. But sometimes it can become a distraction. That distraction is what this code is meant to avoid. > Matt's initial solution is more complicated than the others, it can > fail, it is slightly less efficient, and now you are suggesting that it > needs documentation. In fact, I've said all along that given the requirements that Matt seems to have, he should do a multiple parameter version instead of a single string. But I've also been arguing against the categorical statements that a single-parameter approach is inherently wrong. -- Scott
From: Scott Sauyet on 17 May 2010 09:38 Thomas 'PointedEars' Lahn wrote: > Scott Sauyet wrote: >> Thomas 'PointedEars' Lahn wrote: >>> Scott Sauyet wrote: >>>> Thomas 'PointedEars' Lahn wrote: >>>>> Scott Sauyet wrote: >>>>>> Thomas 'PointedEars' Lahn wrote: >>>>>>> A helper function that by design makes it hard for it to be reused, >>>>>>> that makes code less legible and less reliable than if it was not >>>>>>> used, a function that is not generally applicable, is not a goal to >>>>>>> be attained. >>>>>> I can buy this: "A helper function that by design makes it hard for >>>>>> it to be reused, that makes code less legible and less reliable than >>>>>> if it was not used, is not a goal to be attained." But I'm not buying >>>>>> your "generally applicable" clause. >>>>> Perhaps you are misunderstanding, then. >>>> Maybe, but I think it's more that I disagree. >>> ISTM you do not know what you are disagreeing with. > >> And ISTM that you are trying to solve a different problem than I am. >> Matt hasn't chimed in here lately > > Correct. He has specified the problem and his suggestion to it right from > the start. He has provided his implementation in a followup to his OP then, > which was then subject to further discussion. > >> so it's not clear which approach is closer to his needs. > > Yes, it is. > >> I've explained clearly what my goals from the code are. You've explained >> what yours are. > > Mine are the same as Matt's: Error-free deep property access. Matt is > willing to accept that either certain properties cannot be accessed with it > or that the caller is required to specify a delimiter that is not contained > in a property name. I am not, for the reasons already given. And so Matt has made it clear that that the completeness that you're promoting is not as important to him as it is to you. That is central to the difference between your proposal and mine. I find the simpler API more important than the ability to use if for any legal property value. It's seems pretty arrogant to say that you know Matt's goals well enough to claim them as aligned with yours while simultaneously explaining the difference between you in what you will accept in a solution. >>>>>> Code needs to have an reasonable domain. >>>>> The domain is property access. >>>> Not to my mind. And perhaps that is the crux of the matter. >>> Yes, perhaps you do not read what you are discussing about. The whole >>> point of this was guarded property access. Read the Subject, for >>> goodness' sake! > >> So the subject line in a USENET posting is supposed to be more >> important than the direction of the subsequent conversation? > > Are you being intentionally obtuse? The Subject of the postings of this > thread are continuing to describe the problem to be solved in this case! As already made clear, the language already property access built in and ways to check for errors in the process. Why are you not promoting something along the lines of var result = (obj && obj.foo && obj.foo.bar) ? obj.foo.bar : undefined; or some more complete variant of it if there is no other goal than error-free property access? It will be at least marginally faster than any function that we create. No, I take as a major goal the convenience, as Matt suggested: | This would be convenient for accessing deep properties of objects | that may or may not exist, and not having to manually check the | chain in your code. So then the question of what API is most convenient for the day-to-day work of a developer becomes much more important to me than the possibility that she will one day want to use it to access a property chain with elements containing unusual characters. I know you see it differently. That's clear because I have been paying attention, whether you think so or not: > [ ... ] > Since you are apparently not paying attention, it does not make sense for me > to continue discussing this with you. Just as well, I was getting tired of your unwillingness to hear anything that might disagree with you. BTW, your signature is borken. -- Scott
From: Matt Kruse on 17 May 2010 10:27
On May 15, 10:45 am, Thomas 'PointedEars' Lahn <PointedE...(a)web.de> wrote: > No, I am saying that such a property-accessing function should allow access > to all properties. Your quest for completeness is cute, but ultimately futile. A string delimited with '.' works in probably at least 99% of the cases in which I wish to use it, and probably the same for most people. Solving for the remaining <1% of cases requires a syntax that is less concise and convenient, and more prone to error (matching up quotes, etc). There is simply no compelling need to solve for the general case. I realize this probably bugs you to the core, but that is your personal problem. Just to diverge a bit... this obsessive need to solve the general case is not necessarily the better approach. We live in a world of approximations, where the solution needed depends on the resolution at which you need an answer. Newton's theory of gravity is wonderful. The equations work for all practical cases that a typical person would ever encounter. If you want to calculate the trajectory of a pumpkin launched via catapult, the classical gravity laws work well. But they are NOT correct. We know this because of relativity. When we calculate more complex systems, we need to use more complicated (and more correct, but still not perfect) equations. So, are Newton's laws "wrong"? If you want 100% completeness for the general case, then yes, they are. However, they work perfectly well for most cases. Given the resolution of solution needed, a simpler - though less "correct" - solution is better. Computer Programming is a science, and similar logic still applies. It is not always practical to solve the general case. If you can find a solution that works well for a subset of the general case, and meets your needs, and solves that subset correctly, then it is perfectly acceptable to use it. It is also great to ponder the general case and consider alternative solutions, but that may be more of an academic exercise than a practical one. Between the two ends lies a sliding scale of pros and cons, and it is up to the individual developer to consider other factors (business requirements, execution efficiency, code maintenance, cost, reusability, etc) and decide where on that sliding scale he feels most comfortable. This is what I have done with my approach of a '.' delimited string. Pros: - Simple, concise syntax - Works for the vast majority of common cases - Handles arrays[0], methods(), nested arrays[0][0], and even property names with empty brackets[] Cons: - Fails for property names containing the delimiter - String splitting is slightly less efficient than passing multiple args I'm perfectly happy with that balance, while still being interested in and seeing the benefits of solving the more general case. Matt Kruse |