[mochikit] Re: connectEach shortcut
On Tue, Dec 16, 2008 at 3:47 PM, Eoghan eoghanomur...@gmail.com wrote: 2. Modify the lookup by id convention to lookup by selector + map: connect('#my-ul li', 'onclick', func); Yes, changing these lookups would break the current API. But it wouldn't be impossible to create a migration path with decent backwards compatibility if we really want to. The more important issues with this, I think, is that we would have to: * Change every MochiKit.DOM, Style, Signal, Visual... function that accepts the current shortcut to work properly on node lists (not just individual nodes). * Add the MochiKit.Selector module as a dependency for the DOM module (actually a circular dependency). I'm not very convinced that this is the right direction, but on the other side I hardly ever use the current shortcut either. My own use cases all rely on keeping object maps with direct references to my DOM nodes. 4. Map if passed an array-like connect($$('#my-ul li'), 'onclick', func); This looks like the fastest way forward right now. But instead of connecting signal handlers all over, I'd personally do the following instead: var func = function (evt) { var li = evt.target(); if (li.tagName == null || li.tagName.toUpperCase() != LI) { li = getFirstParentByTagAndClassName(evt.target(), LI); } ... whatever you wanted to do ... } connect('my-ul', 'onclick', func); Agreed that using getFirstParentByTagAndClassName() gets a bit messy, since it doesn't check the specified node for a match (just the parents). 5. More powerful partial: forEach($$('#my-ul li'), partial(connect, __, 'onclick', func)); We probably need the more powerful partial or bind, but I'm not so sure about this API. Cheers, /Per --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups MochiKit group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: Introducing the MochiKit.Text module
Amit Mendapara schrieb: Again, I'm too, agree with Arner. Try to follow Python conventions as much as possible. startsWith = startswith endsWith = endswith By the way, one (new) useful feature of Python's startswith is that you can also pass a tuple of substrings (prefixes) instead of only one. So maybe you can accept arrays as well. And I would also make the actual string the first argument (kind of self). Then you can also easily add more parameters (like optional start and end index for the search etc.). -- Christoph --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups MochiKit group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: Introducing the MochiKit.Text module
Hi Christoph, On Thu, Dec 18, 2008 at 13:00, Christoph Zwerschke c...@online.de wrote: By the way, one (new) useful feature of Python's startswith is that you can also pass a tuple of substrings (prefixes) instead of only one. So maybe you can accept arrays as well. Ah, nice - I didn't know about this feature of startswith. And I would also make the actual string the first argument (kind of self). Then you can also easily add more parameters (like optional start and end index for the search etc.). For this part, see me previous message in this thread about the partial(...) use case. Partially applying the needle looks much more common than partially applying the haystack (or at least that is my gut feeling). Again, if we get a more generic partial(..) this becomes a non-issue. cheers, Arnar --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups MochiKit group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: setNodeAttribute Not working with Google Chrome
This is a WebKit (both Safari Chrome) issue, since it handles attributes more strictly than other browsers. I.e. 'selected' is not an attribute on the HTML node, just a property. We try to work around this in most cases by setting both the attribute and the property just to be sure: if (typeof(elem[k]) == string elem[k] != v) { // Also set property for weird attributes (see #302) elem[k] = v; } But in WebKit typeof(elem.selected) == boolean, so this fix doesn't run... Perhaps we should add a patch for the patch here. Don't know if it will be safe, but it might work. The easy work-around for you is to do the following instead: function getAnalogueInputs(){ var node = getElement('[AN1_MEASURING_Q]'); // FIXME: the next line will always return 1... probably not intended var type = getSignalTypeAsIndex(node[0]); var opt = node.options[type]; opt.selected = 'selected'; } Cheers, /Per On Mon, Dec 8, 2008 at 11:20 AM, n.karako...@googlemail.com n.karako...@googlemail.com wrote: Hi, Thanks for the reply. There is no error shown in Google Chrome. Here is a test file. !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http:// www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html xmlns=http://www.w3.org/1999/xhtml; head meta http-equiv=Content-Type content=text/html; charset=utf-8 / !--script type=text/javascript src=MochiKit-1.3.1/lib/MochiKit/ MochiKit.js/script-- script type=text/javascript src=MochiKit-1.4/lib/MochiKit/ MochiKit.js/script title/title /head body form action= div style=margin-left:5px h2Analogue Inputs/h2/div !--AN1-- div class=an h3nbsp;/h3 div class=tableDataGrey style=width:130px; labelMeasuring Quantity select name=an1MeasuringQ size=1 id=[AN1_MEASURING_Q] option value=level Level/option option value=pressure Pressure/option /select /label /div /div /form /body /html script type=text/javascript function getAnalogueInputs(){ var node = 'pressure'; node = getElement('[AN1_MEASURING_Q]'); setNodeAttribute(node.options[getSignalTypeAsIndex(node [0])],'selected','selected'); } function getSignalTypeAsIndex(type){ if(type == level) return 0; else return 1; } connect(window, 'onload', function() { getAnalogueInputs(); } ); /script On Dec 7, 11:10 pm, Per Cederberg cederb...@gmail.com wrote: If you could provide more details on exactly what is breaking it would be easier to help. Perhaps a minimal HTML file exposing the issue? If you can find any error or debugging information from Chrome (if there is any) that too would be very helpful. Cheers, /Per On Sun, Dec 7, 2008 at 8:49 PM, n.karako...@googlemail.com n.karako...@googlemail.com wrote: Hi, The following code doest work with Google Chrome but is OK with firefox and IE7 node = getElement('[AN3_PRE_ALARM_ACTION]'); setNodeAttribute(node.options[getActionAsIndex(d.an3 [7])],'selected','selected'); Any thoughts? Regards, Nick --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups MochiKit group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: Curry and uncurry
The difference between currying and partial application is that you can call a curried function f with 1 argument that needs N arguments and the return value is a function f_1 that needs N-1 arguments and when called again with 1 argument will return a function f_2 that takes N-2 arguments, etc. until some point where N-K=0 and it returns a value instead of another function. It's effectively a transform that wraps a function f(a, b, c) with something like this: function (a) { return function (b) { return function (c) { return f(a, b, c); } } } Partial application explicitly takes a function with N arguments and returns a function that takes N-K arguments but the resulting function behaves the same as any other function in JS without that magic. I'm not a real big fan of currying in languages where it's not built-in. It's easy to make a mistake by calling a function with too few arguments and you get a harder to track down bug. It also doesn't work well with languages that have default arguments or the equivalent (e.g. using the arguments object) because you don't know exactly when to stop currying. On Wed, Dec 17, 2008 at 11:31 PM, Per Cederberg cederb...@gmail.com wrote: The names curry and uncurry were a bit confusing to me, so it took me a while to understand these two functions... http://en.wikipedia.org/wiki/Currying To me (and probably other non-Haskell users) the names imply the same thing as bind or partial. It's a confusing world... :-( In JavaScript, I think plain apply + MochiKit.Base.bind does the same thing: var test = [ [10, 1], [20, 2], [30, 3] ]; var addArray = bind(apply, operator.add, null); assertEqual(map(addArray, test), [11, 22, 33]); It's no beauty, so perhaps this particular variant of bind merits an alias? Uncurrying is just the same as the built-in apply function, so that seems unnecessary. Cheers, /Per On Wed, Dec 17, 2008 at 5:22 PM, Arnar Birgisson arna...@gmail.com wrote: One thing I think could be useful is to port Haskell's curry and uncurry. This is basically a convenience method for (un)wrapping an .apply on a function object: function curry(f) { return function () { // first convert arguments to a regular array var args = Array.prototype.slice.call(arguments); return f(args); } } function uncurry(f) { return function (args) { return f.apply(this, args); } } Example use: test = [ [10, 1], [20, 2], [30, 3] ]; assertEqual(map(uncurry(operator.plus), test), [11, 22, 33]); // assume join is a function that takes a list and returns a string // with the elements joined with some delimiter f = curry(partial(join, _, , )) assert(f(Bond, James Bond) == Bond, James Bond) Does anyone else think this could be useful? What module would it fit? Base already has a lot of functional stuff (compose, partial, map friends) - I'm wondering if it fits there or if all the functional stuff should be in a seperate module MochiKit.Functional - as Python seems to be heading. cheers, Arnar --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups MochiKit group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: Curry and uncurry
Hi all, On Thu, Dec 18, 2008 at 16:07, Bob Ippolito b...@redivi.com wrote: I'm not a real big fan of currying in languages where it's not built-in. It's easy to make a mistake by calling a function with too few arguments and you get a harder to track down bug. It also doesn't work well with languages that have default arguments or the equivalent (e.g. using the arguments object) because you don't know exactly when to stop currying. Actually, the functions I proposed (curry and uncurry, stolen form Haskell) do not describe this kind of currying. curry takes a function of one argument, a tuple, and returns a modified function that instead takes N arguments (the elements of the tuple). The reason for the name curry is that it basically performs the translation you (Bob) mentioned in Haskell, i.e. it transforms an N argument function to a nesting of N one-argument functions, i.e. it curries the function. uncurry takes a function of N arguments and returns a modified function that instead takes one argument, a tuple of N elements. Obviously the naming comes from this being the reverse of curry. The absolute main use case is mapping functions over a list of tuples (in js list=tuple). This uses uncurry to change a function f(a,b) to f(t) where t is a tuble of a and b. That way you can simply map (or filter) the function over the outer list and arguments get placed in the correct spot. Currying is a convenience for changing a function that takes a tuple (i.e. a list in js) and apply it with the tuple elements as arguments -- i.e. exactly what Function.apply does in js. I'd still include it if uncurry is included, for the sake of symmetry. I do realize this might be a bit too eccentric -- but it is the kind of thing that becomes very useful to grab when you do a lot of functional-style programming in any language. Per provided bind(apply, operator.add, null) as equivalent to uncurry. This is true, except that the context (this) is not maintained.. but yes, maybe it is my weird style but I'd give an alias to this. Dunno.. I'm happy to keep it in my personal library of helper functions :) cheers, Arnar --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups MochiKit group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: Curry and uncurry
Thanks for the clarification, Bob! Regarding the functions in questions I think other names might be in place, to avoid misleading interpretations. What we're really doing here is attempting to patch the poor JavaScript syntax and/or standard library for function calls (i.e. call, apply, arguments and others). The current MochiKit work-around for this is the excellent bind() function (in its many incarnations). But it still has weaknesses, since it doesn't allow us to do any of the following cool things: 1. Use the call-time 'this' object as an argument to the function (can only be used as the object). If we had this, the currying mentioned here would strictly be a version of bind(). 2. Leaving gaps for call-time arguments in the list arguments set at bind-time. Currently call-time arguments can only be appended to the argument list. 3. Perform reordering of arguments. Typically inverse two arguments, like in the startsWith discussion. 4. Perform random argument transformation. Using an array as the argument list or vice versa. Or adding automatic flattening to arguments. The more I think about this, I tend to come to the conclusion that we need something powerful enough to allow both the current bind() and all of the above. Perhaps the syntax needn't be trivial, since we could then add simplifying aliases for whatever common use-cases we can identify. One option, for example, would be a bind-version that would actually map each function argument: caller(func, self, { value: 123 }, { arg: 3 }, { arg: 1 }, { arg: -1 }); Another might be to create higher order argument-mapping functions: var flip = function (func, self, args) { return args.reverse(); }; caller(func, self, flip); These were just two ideas off the top of my head. But I think we should discuss more options here before plunging ahead and adding yet another variant of bind to MochiKit. Although they might all be very useful. It will slowly get too confusing for the average user. Thanks for reading this far! :-) Cheers, /Per On Thu, Dec 18, 2008 at 5:25 PM, Arnar Birgisson arna...@gmail.com wrote: Hi all, On Thu, Dec 18, 2008 at 16:07, Bob Ippolito b...@redivi.com wrote: I'm not a real big fan of currying in languages where it's not built-in. It's easy to make a mistake by calling a function with too few arguments and you get a harder to track down bug. It also doesn't work well with languages that have default arguments or the equivalent (e.g. using the arguments object) because you don't know exactly when to stop currying. Actually, the functions I proposed (curry and uncurry, stolen form Haskell) do not describe this kind of currying. curry takes a function of one argument, a tuple, and returns a modified function that instead takes N arguments (the elements of the tuple). The reason for the name curry is that it basically performs the translation you (Bob) mentioned in Haskell, i.e. it transforms an N argument function to a nesting of N one-argument functions, i.e. it curries the function. uncurry takes a function of N arguments and returns a modified function that instead takes one argument, a tuple of N elements. Obviously the naming comes from this being the reverse of curry. The absolute main use case is mapping functions over a list of tuples (in js list=tuple). This uses uncurry to change a function f(a,b) to f(t) where t is a tuble of a and b. That way you can simply map (or filter) the function over the outer list and arguments get placed in the correct spot. Currying is a convenience for changing a function that takes a tuple (i.e. a list in js) and apply it with the tuple elements as arguments -- i.e. exactly what Function.apply does in js. I'd still include it if uncurry is included, for the sake of symmetry. I do realize this might be a bit too eccentric -- but it is the kind of thing that becomes very useful to grab when you do a lot of functional-style programming in any language. Per provided bind(apply, operator.add, null) as equivalent to uncurry. This is true, except that the context (this) is not maintained.. but yes, maybe it is my weird style but I'd give an alias to this. Dunno.. I'm happy to keep it in my personal library of helper functions :) cheers, Arnar --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups MochiKit group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---