Let's imagine

Rank=:2 :0
  NB. u: verb
  NB. n: noun (list of numbers)
  NB. y: boxed nown
 ...
)

Here, #n must be at least 1 1.5 0.5&p.#y

u is applied at rank specified by n {~ (i. + _1 0.5 0.5 p. ])@# y to the
contents of the boxes of y.

Would this be practical? Yes and no... for some small problems and for
illustrative purposes a straightforward J implementation would work great.
This could also serve, for some people, as an example of how rank "really
works". But for larger problems it would be a pain to use, and something
closer to more classical APL might be a better approach.

If we had good J compilers, that would open up some additional options and
make some of those cases be significantly more efficient. And writing such
a compiler might be a fun student project (for the right kind of class).
But efficiency is often a misleading issue and reasoning about it is often
contradicted by experience.

Let me know if you want me to draft up an implementation (of Rank, not of
good J compilers - Rank is something that would take maybe an hour to
implement, a good compiler takes longer). (And, I've got other things I'm
working on today.)

Thanks,

-- 
Raul


On Sun, Mar 30, 2014 at 2:34 PM, Dan Bron <[email protected]> wrote:

> I recommend cultivating a skepticism of the thought "this is a bug in J".
> It's a thought-stopping reaction, and almost always wrong.
>
> That's not to say J has no bugs: no, I mean "almost always" in the
> measure-theoretical sense; while I've found plenty of bugs in J, their
> number is absolutely dominated by the number of bugs I've found in my
> understanding of J. So now my first reaction is to debug my mental model
> before I try to debug J.
>
> Here's how I might approach that in your current case. First, I recognize
> that the argument to }, here, is a 3-element gerund, and the derived verb
> being invoked dyadically:
>
> > 3 +`((0 0;1 1;2 2)"1)`]} i.3 3
>
>
> So I look up that case in the definition of } :
>
> x (v0`v1`v2)} y ↔️ (x v0 y) (x v1 y)} (x v2 y)
>
> Next, I would test this assertion the DoJ is making, against my current
> example:
>
>    x =: 3
>    y=:i.3 3
>
>    v0=:+
>    v1=:(0 0;1 1;2 2)"1
>    v2=:]
>
>    m=: v0`v1`v2
>
>    benchmark=:x m} y
>    test =:(x v0 y) (x v1 y)} (x v2 y)
>
>    test-:benchmark
> 1
>
> So, since the results agree with each other, and therefore the Dictionary,
> there is no bug in J (at least not here). Which means, if I disagree with
> either result or the fact that they are identical, the bug must be in my
> mental model.
>
> Make sense?
>
> -Dan
>
> PS: I think I know what's confusing you, and it's related to your earlier
> frustration with ^:(1 0 1"_) .
>
> I have a half-written draft in response to that, but to treat it properly
> and clearly would take more time than I anticipated, so I didn't send it.
>
> The short story is that conjunctions and adverbs, for all their power,
> have on critical handicap with respect to verbs: they can't slice or dice
> their arguments. Conjunctions and adverbs always address arguments in toto;
> there is no (straightforward) way for them to operate piecewise. When you
> ask an operator to work piecewise, typically you'll just end up making
> multiple copies of the entire argument (as happens with ^:1 0 1).
>
> That's why we often say that the verb has primacy in J: most code is
> written as verbs and most tools assist in writing verbs. In fact, this is
> what adverbs and conjunctions are mostly intended to do: help write verbs,
> rather than stand by themselves (in the ideal J statement, you wouldn't
> even see the advs/conjs; they would fade into the background, so we could
> focus on the logic expressed by the verbs. Which is why we find trains so
> elegant and bicker about a better use for "hook", how and whether to
> interpret juxtaposed nouns, etc).
>
> The shining example here is: " . It is absolutely the most used
> conjunction in J (if you count implicit uses) and is designed precisely to
> let J verbs operate piecewise, in a straightforward, non-intrusive (often
> literally invisible) way.
>
> To let adverbs and conjunctions and adverbs operate piecewise (in a
> straightforward way), we'd need some kind of meta-" that could take
> operators as arguments, but currently no wordclass in J has higher
> precedence (binding power) than adverbs and conjunctions, so that's not
> possible.
>
>
> >  On Mar 30, 2014, at 1:35 PM, Pascal Jasmin <[email protected]>
> wrote:
> >
> > I'm sure your explanation is helpful to many, but the reason for my
> comment comes from the natural frustrations of "I wish the computer would
> do what I meant instead of what I say" moments and then the obvious
> consequence of obviously "I don't always understand what I say.", which
> even if we all acknowledge to be true, is not the foremost thought when
> debugging/troubleshooting.
> >
> > ~ is the demon that will haunt beginners the most.  Passive is by far
> the most common use of ~, and the most intuitively understandable (though
> all 3 are fairly quite straightforward), but its conceptually linked most
> directly to Passive.
> >
> > I do not like or recommend the practice of replacing J primitives with
> words such as 'verb define' because it obfuscates the parsing understanding
> needed to read and write J.  However, in the case of ~, (though I don't do
> it), it would have saved me many headaches if I had defined 3 adverbs and
> used them.
> >
> > For interest what is said with: (i. 3 3) }~ (0 1 2) is:
> >
> > 0 1 2 (i. 3 3) } 0 1 2
> >
> >
> > On another note, } is overly complicated, and IMO poorly designed,
> though Eelvex's example is something I just learned today towards
> explaining it.
> >
> >
> >    (0 1 2) } (i. 3 3)
> >  0 4 8
> >
> >
> > the above is incredibly cool, as it retrieves the diagonal from i. 3 3.
>  But note, the unfortunate asymetry with { which would have made a more
> approachable design decision:
> >
> >   (0 1 2) { (i. 3 3)
> > 0 1 2
> > 3 4 5
> > 6 7 8
> >
> >
> > so, this happens:
> >   1 (0 1 2) } (i. 3 3)
> > 1 1 1
> > 1 1 1
> > 1 1 1
> >
> >   +: (0 1 2) } (i. 3 3)
> > 0 8 16
> >
> >   (0 1 ) } (i. 3 3)
> > |length error
> > |       (0 1)}(i.3 3)
> >
> >   (0 1 ) { (i. 3 3)
> > 0 1 2
> > 3 4 5
> >
> >
> > The key to understanding }'s behaviour is that m} has both a monadic and
> dyadic verb result.  Which is completely unobvious for something called
> amend.  (An intuitive imagination based understanding (as opposed to RTFM
> based understanding which separates item amend from amend definitions)
> would be that n} returns an adverb instead of a verb, which can then take u
> or m to update y.
> >
> > I recommend using the following conjunction most of the time:
> >
> > amend_z_ =: 2 : 0  NB. v is n or n{"num
> > s=. v"_ y
> > (u"_ (s{y)) (s}) y
> >  :
> > s=. v"_ y
> > (x u"_ (s{y)) (s}) y
> > )
> >
> >
> > Though it loses the quirky feature of obtaining the diagonal (Item
> Amend), it gaI'm sure your explanation is helpful to many, but the reason
> for my comment comes from the natural frustrations of "I wish the computer
> would do what I meant instead of what I say" moments and then the obvious
> consequence of obviously "I don't always understand what I say.", which
> even if we all acknowledge to be true, is not the foremost thought when
> debugging/troubleshooting.
> >
> > ~ is the demon that will haunt beginners the most.  Passive is by far
> the most common use of ~, and the most intuitively understandable (though
> all 3 are fairly quite straightforward), but its conceptually linked most
> directly to Passive.
> >
> > I do not like or recommend the practice of replacing J primitives with
> words such as 'verb define' because it obfuscates the parsing understanding
> needed to read and write J.  However, in the case of ~, (though I don't do
> it), it would have saved me many headaches if I had defined 3 adverbs and
> used them.
> >
> > For interest what is said with: (i. 3 3) }~ (0 1 2) is:
> >
> > 0 1 2 (i. 3 3) } 0 1 2
> >
> >
> > On another note, } is overly complicated, and IMO poorly designed,
> though Eelvex's example is something I just learned today towards
> explaining it.
> >
> >
> >    (0 1 2) } (i. 3 3)
> >  0 4 8
> >
> >
> > the above is incredibly cool, as it retrieves the diagonal from i. 3 3.
>  But note, the unfortunate asymetry with { which would have made a more
> approachable design decision:
> >
> >   (0 1 2) { (i. 3 3)
> > 0 1 2
> > 3 4 5
> > 6 7 8
> >
> >
> > so, this happens:
> >   1 (0 1 2) } (i. 3 3)
> > 1 1 1
> > 1 1 1
> > 1 1 1
> >
> >   +: (0 1 2) } (i. 3 3)
> > 0 8 16
> >
> >   (0 1 ) } (i. 3 3)
> > |length error
> > |       (0 1)}(i.3 3)
> >
> >   (0 1 ) { (i. 3 3)
> > 0 1 2
> > 3 4 5
> >
> >
> > The key to understanding }'s behaviour is that m} has both a monadic and
> dyadic verb result.  Which is completely unobvious for something called
> amend.  (An intuitive imagination based understanding (as opposed to RTFM
> based understanding which separates item amend from amend definitions)
> would be that n} returns an adverb instead of a verb, which can then take u
> or m to update y.
> >
> > I recommend using the following conjunction most of the time:
> >
> > amend_z_ =: 2 : 0  NB. v is n or n{"num
> > s=. v"_ y
> > (u"_ (s{y)) (s}) y
> >  :
> > s=. v"_ y
> > (x u"_ (s{y)) (s}) y
> > )
> >
> >
> > Though it loses the quirky feature of obtaining the diagonal (Item
> Amend), it gains the feature of updating y in an intuitive (symetrical to
> {) way that accepts a verb for the updating.
> >
> >   +: amend ( 1 2) i. 3 3
> > 0  1  2
> > 6  8 10
> > 12 14 16
> >
> >
> >   3 + amend 1 +: amend ( 1 2) i. 3 3
> > 0  1  2
> > 9 11 13
> > 12 14 16
> >
> >
> >
> > the gerund } is weird too.  Here is a result I don't understand (might
> be a bug?):
> >
> >    3 +`((0 0;1 1;2 2)"1)`]} i.3 3
> > 9  1  2
> > 3 10  5
> > 6  7 11
> >
> >
> >
> > ----- Original Message -----
> > From: Dan Bron <[email protected]>
> > To: "[email protected]" <[email protected]>
> > Cc:
> > Sent: Sunday, March 30, 2014 9:16:51 AM
> > Subject: Re: [Jprogramming] Item amend ~: index error.
> >
> > You can tell immediately whether ~ is performing passive, reflexive , or
> evoke.
> >
> > Did you pass it a noun? Then it's evoke (this is very rare and very
> obvious: remember, as an adverb, ~'s argument is fixed at runtime, so you'd
> literally have to write or see a noun directly to the left of ~).
> >
> > You didn't pass it a noun? Ok, by definition, you passed it a verb. So ~
> consumed that verb and produced a new verb. Did you pass that new verb one
> argument, or two arguments?
> >
> > If you passed the new verb one argument (aka "invoked the monad") then ~
> will act in its reflexive capacity. If you passed the new verb two
> arguments (aka "invoked the monad") then ~ will act in its passive capacity.
> >
> > In other words, f~ ↔️ (] f ]) : (] f [) . That is, given a verb f, f~
> will produce an ambivalent verb which will always invoke the dyadic valence
> of f (the monadic valence of f is thus ignored and therefore irrelevant).
> When f~ is invoked, the left argument to f will always be the right
> argument of f~ .
> >
> > Thus, the only difference between passive and reflexive is the right
> argument to f, which will be the left argument of f~ if it has one (ie if
> f~ was invoked dyadically) or the same old right argument as before if it
> doesn't (ie if f~ was invoked monadically and the only argument around to
> use is on the right).
> >
> > So ~ is hardly a demon from hell, because you know what you're getting
> when you invoke it. The incantations are simple and the consequences
> predictable.
> >
> > -Dan
> >
> > Ok, need a mnemonic?
> >
> > 'name'~ : evoke the name (call upon, summon up, conjure, recall)
> >
> > verb~ y : reflect the argument (mirror, create a perfect image, clone,
> put a mirror up so the verb sees two identical copies, etc)
> >
> > x verb~ y : use the passive voice (switch the subject and object, invert
> the sentence, etc):
> >
> > Pascal invoked Astaroth
> > Astaroth was invoked by Pascal
> >
> > [do not try this at home]
> >
> > [1] "Why was ~ on a dyadic verb named "passive"?
> >     http://www.jsoftware.com/pipermail/general/2007-May/030070.html
> >
> >
> > Sent from my iPhone
> >> On Mar 30, 2014, at 8:31 AM, Pascal Jasmin <[email protected]>
> wrote:
> >>
> >> } is an adverb.
> >> ~ is a demon from hell for errors in that it can do one of 3 things
> (passive, reflex, evoke), and often its one of the other 2 than you
> intended.  (here you were assuming it would do passive).  I'm not 100%
> positive which of the other 2 it actually gets parsed at here.
> >>
> >>
> >> ----- Original Message -----
> >> From: EelVex <[email protected]>
> >> To: Programming forum <[email protected]>
> >> Cc:
> >> Sent: Sunday, March 30, 2014 7:07:05 AM
> >> Subject: [Jprogramming] Item amend ~: index error.
> >>
> >>     (0 1 2) } (i. 3 3)
> >> 0 4 8
> >>
> >>     (i. 3 3) }~ (0 1 2)
> >> |index error
> >> |       (i.3 3)}~(0 1 2)
> >>
> >> Why? What's the use of }~ when not used as 'amend'?
> >> ----------------------------------------------------------------------
> >> 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
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to