What's happening with the ([: u v) : (u v) pattern is this: Every verb gets two (possibly empty) definitions. A monadic definition and a dyadic definition. The definition used depends on the context where the verb gets used.
In a monadic context (like your example here), the monadic definition gets used, and the non-functional dyadic definition is ignored. Note also that [: represents a verb with an empty monadic domain and an empty dyadic domain. [: a: |domain error Note also that you get similar behavior from empty explicit definitions: 3 :'' a: |domain error In other words, in J, these can be thought of as being roughly equivalent: empty domain empty definition empty explicit definition empty verb empty function Restated, ([: Volume F) : (Volume F) 3 4 5 is roughly equivalent to ([: Volume F) : [: 3 4 5 and also roughly equivalent to ([: Volume F) 3 4 5 Meanwhile, 9 ([: Volume F) : (Volume F) 3 4 5 would be equivalent to 9 [: : ([: Volume F) 3 4 5 and to 9 ([: Volume F) 3 4 5 Or, to take another example (which does not generate an error): 9 - : - 3 4 5 is equivalent to 9 [: : - 3 4 5 and to 9 - 3 4 5 (And, internally, there are two collections of definitions associated with the '-' primitive - a collection of negation primitives and a collection of subtraction primitives. (And, I say collection, because, for example, Roger's implementation code which handles 3r4 - 5 is different from his code which handles 3.1415 - 2j3.)) Thanks, -- Raul On Mon, Nov 17, 2014 at 8:52 PM, 'Pascal Jasmin' via Programming < [email protected]> wrote: > Thanks for your thoughts, Raul. > > Volume is a useless example function. the key part of the example > function is that it takes 3 parameters with the 'l w h' =. y pattern. > > The other functions are generic meant to apply curry to any function that > takes multiple parameters (through multi assign pattern). Including dyadic > and ambivalent functions. > > even without a multi assignment function, you can still do: > > 1 1 1 + &> curryB ( a:, a:,<4) curryB (3;a:) 10 > 4 11 5 > > > as a dyadic fork, this is also possible > 3 (; curryB (1;2) + &> curryB ( a:, a:,<4) curryB (3;a:) ]) 10 > 6 11 6 > (left tine (;) gets resolved as 3;1;2) > > In terms of currying the leftmost argument, that is easier, and as I > understand the basics of Haskell, everything there is currying the left > argument until there are no more arguments. > > > > Your approach to write a simple function that will place further arguments > in order also works. Maybe that gets too complicated for 5+ parameters. > curryB essentially does that, using a noun as the parameter template. The > core of it is the verb rather than conjunction: > > (3;a:,a:,<4) curry 1;2 > ┌─┬─┬─┬─┐ > │3│1│2│4│ > └─┴─┴─┴─┘ > > > Your approach is more straightforward and efficient. My approach is more > generic though. > > The big mystery to me though is how the compound : sentence manages to > work despite a reading that it shouldn't. > > > > ----- Original Message ----- > From: Raul Miller <[email protected]> > To: Programming forum <[email protected]> > Cc: > Sent: Monday, November 17, 2014 7:42 PM > Subject: Re: [Jprogramming] a weird thing with multiple : conjunction > > I'm working through what you have done here, and am trying to understand > your reasoning: > > Volume =: 3 : '''Volume is :'', (": l*w*h), '' for length '', (": l) , '' > width '' , (": w) , '' and height '' , (": h) [''l w h'' =. y' > > > This is a verb which only makes sense to use monadically. Also, it's mostly > dealing with lists of characters, many of them quoted. I think I'd instead > go with: > > > Volume =: 3 : 0 > > volume=. ": */y > > 'l w h'=. ":&.> y > > 'Volume is ',volume,', for length ',l,', width ',w,' and height ',h > > ) > > > The one-liner approach is great for experimenting, but not always so good > for other people. (And, I have probably offended on the wrong side of that > line, too often). > > > Next, we have: > > > hook =: 2 : '([: u v) : (u v) ' > itemamend =: 4 : '((2}.$y) $"1 0 x)} y' > filtermodA =: 1 : 'u itemamend ] ,: (#inv~ u)' > curry =: 4 : '(boxopen y) (a: = ]) filtermodA x' > curryB=: 2 : 'u hook (n&curry)' > > Studying this... the only left argument for 'hook' is Volume, which is > monadic. So what this will achieve is needless duplication. Furthermore, > what it's used for is not a hook but a hook-like concatenation mechanism. > So what I think is needed here is a better name. Also, since the > monadic/dyadic character of 'hook' is both irrelevant and distracting in > this context, I think I'd go with a simpler definition. > > after=: 2 :'([ u v)' > > Or, actually > > after=: @: > > Or, actually, since at this point it's just a primitive, I'd not bother > inventing another name for it. I am also tempted to use @ instead of @: > because the right argument will always have infinite rank, but for this > stage of this exercise I will refrain from that approach. > > itemamend =: 4 : '((2}.$y) $"1 0 x)} y' > filtermodA =: 1 : 'u itemamend ] ,: (#inv~ u)' > curry =: 4 : '(boxopen y) (a: = ]) filtermodA x' > curryB=: 2 : 'u @: (n&curry)' > > And, with that change, the result of > Volume curryB ( a:, a:,<4) curryB (3;a:) f. > is somewhat readable. Looking at it, I expect that I should be able to do > Volume curryB ( a:, a:,<4) curryB (3;a:) 5 > > but that gives me a domain error. So perhaps a different approach would be > good? > > I guess what I think I would want is something which curries the leftmost > or rightmost argument in a list. So I would want to generate > Volume@(,&4)@(3&,) > > And, honestly, that is good enough as it is. However, if I wanted to get > fancy, I could define > curryR=: 2 :'u@(,&n)' > curryL=: 2 :'u@(n&,)' > > Note that I am explicitly ignoring the possibility of a left argument for > u. If I need a left argument, that's not an obstacle: I can curry ] and use > that curried verb to provide the right argument of my dyadic verb. And I > think that that approach is fine and good, if I am really trying to define > useful modules. > > Of course, another approach would be to define something like: > Volume@(3,],4:) > > But if I am going to go that route, I do not think that the abstract > concept of "currying" adequately describes what I am doing. So I'd want to > come up with a better name as my first step. > > But maybe I have misunderstood what you were driving at here? I seem to be > good at that, sometimes. > > Anyways, I hope this helps. > > Thanks, > > -- > Raul > > > On Mon, Nov 17, 2014 at 2:35 PM, 'Pascal Jasmin' via Programming < > [email protected]> wrote: > > > as a test function > > > > Volume =: 3 : '''Volume is :'', (": l*w*h), '' for length '', (": l) , '' > > width '' , (": w) , '' and height '' , (": h) [''l w h'' =. y' > > > > Volume 3 4 5 > > Volume is :60 for length 3 width 4 and height 5 > > > > some functions for currying arbitrary parameters > > > > hook =: 2 : '([: u v) : (u v) ' > > itemamend =: 4 : '((2}.$y) $"1 0 x)} y' > > filtermodA =: 1 : 'u itemamend ] ,: (#inv~ u)' > > curry =: 4 : '(boxopen y) (a: = ]) filtermodA x' > > curryB=: 2 : 'u hook (n&curry)' > > > > This works: curry height to 4, and then in returned function, curry > length > > to 3 > > Volume curryB ( a:, a:,<4) curryB (3;a:) > > ([: ([: Volume ((0$0);(0$0);4)&curry) :(Volume ((0$0);(0$0);4)&curry) > > (3;0$0)&curry) :(([: Volume ((0$0);(0$0);4)&curry) :(Volume > > ((0$0);(0$0);4)&curry) (3;0$0)&curry) > > > > > > calling with remaining parameter (width) 2 returns as desired > > > > Volume curryB ( a:, a:,<4) curryB (3;a:) 2 > > Volume is :24 for length 3 width 2 and height 4 > > > > it also works as a dyadic call > > > > Volume@:] curryB ( a:, a:,<4) curryB (3;a:) 2 > > Volume is :24 for length 3 width 2 and height 4 > > 2 Volume@:] curryB ( a:, a:,<4) curryB (3;a:) 2 > > Volume is :24 for length 3 width 2 and height 4 > > > > > > If you look back to the returned function, it includes 3 : conjunctions > to > > separate monad and dyad calls. I don't understand how multiple : works, > > and if you look closely, only the dyadic sides appear to be complete > > expressions that curry both the 4 and the 3 > > > > actually upon closer inspection of parentheses matching, at the top > level, > > only the middle : exists. On a monadic call the left of that would be > > executed, but within that left side, only the right side of : provides > the > > "right" answer. > > ---------------------------------------------------------------------- > > For information about J forums see http://www.jsoftware.com/forums.htm > > > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
