Pascal wrote:
> There is no good reason for item amend to be an adverb.
Except that } , is an adverb (and there's a very good reason for that: to use
it for "regular amend" requires 3 distinct arguments, and verbs can't have more
than 2). That is, there's no way for the } in x } y to be a verb and yet still
have x idx} y work (because that requires } to be an adverb, not a verb. The
same symbol can't be an adverb sometimes and a verb other times).
If you're instead saying that there's no reason for J to offer the
functionality of "item amend", or anyway it shouldn't be advertised in such a
prominent location as the monad u}, then I can only respond: what else should
go there?
All verbs in J are ambivalent. That is, there is literally no way
(grammatically) to prevent a user from invoking a verb with one argument or
with two arguments. So either you provide meanings for both those cases or you
raise an error when the "wrong one" is invoked (viz ~. or E.). Therefore, the
choice is between defining u}y to mean something or raising an error when
someone tries that.
I wouldn't find the argument that a error would be more useful than the
functionality offered by "item amend" to be very compelling. In fact, I
personally like "item amend", though I agree with you that it could have a
better name. I call it "merge" in my head, and my favorite use of it is this:
'X'&=`(,:&' ') } 'XXXhiXthereXXX!'
hi there !
That is, I use it for substitution. The v1 part provides a "merge mask" and
each item of the (output of) the v2 verb nominates candidates for each position
of the output. So v1 is the "voter" and v2 is the "ballot" and } is the
election (and so far has yet to stumble on any hanging chads...). In this case,
v0 is not present, but if it were, it would be ignored (so in this case, it is
the v0 part, not the v1 part, that is "unnecessary").
But this merge thing is just a favorite toy of mine. It certainly is more
useful than a domain error, but I'm open to other ideas for what u} y should
mean, so long as they're not errors (that is: I won't mind if you ask me to
trade my toy for a new one, but I'd be quite vocally upset if you just took it
away).
Similar thoughts apply to x m} y , though of course that's just regular amend,
not "item amend". You seem to think that it should have been defined
differently (or at least you state that with some confidence), so if you're
willing to make the case for a change by comparing the current implementation
with your new proposal across a variety of use cases, I'm willing to read it
(with an open mind).
I've certainly used the idiom u@{`[`] } before ....
-Dan
PS: I've also also been quite embarrassed when I've confidently (ok:
arrogantly) asserted that I've come up with an "obviously superior" improvement
over one or another of Ken's design decisions, only to have its flaws and
failings wrt the current design graciously pointed out to me by this community
... and now I tend not to do that, either :) [Seriously, some of these guys
have been at it since the 60s...]
That said, the particular area of gerund} has always stuck out at me as
somewhat inconvenient, and even now it's one of the few patterns that I'm
forced to look up in the reference material before I can use it properly, so
I'm honestly quite open to other ideas here. We do own the J source now.
That said, my understanding is that the current design of m} was based on a
desire to make it consistent and consonant with other, related areas on the
language, so if we change it, we might have to sacrifice that.
Note also that I would be less open to ideas that make } less general. For
example, the current definition allows us to express u@{`[`] } , but redefining
v0`v1`v2} as (v0 v1 ])`v1} would preclude us from writing everything the
current definition permits, which would be a loss of generality I (personally)
would not accept.
PPS: the confusion on both ^:(1 0 1"1) and the domain error below arises (IMO)
from an expectation of how rank applies "within" an operator, and this
expectation does not match the (current) implementation of J. That's what I was
driving at when I related them.
For example, compare:
{ b. 0. NB. Left rank zero: treat each box or atom on the left independently
1 0 _
(+:@:])`[`]} b.0. NB. Left rank _: take all the boxes (or atoms) on left
together, all at once.
_ _ _
> On Mar 30, 2014, at 3:25 PM, Pascal Jasmin <[email protected]> wrote:
>
> I'm not sure this issue completely matches my difficulty with ^:1 0 1 because
> that was fixed with ^:[
>
> to be clear:
>
> (0 0;1 1;2 2){ i.3 3
> 0 4 8
>
> (0 0;1 1;2 2) (+:@:])`[`]}i.3 3
> |rank error
>
> 1 1 1 (0 0;1 1;2 2)}i.3 3
> 1 1 2
> 3 1 5
> 6 7 1
>
>
> The problem is actually with v0 and not v1... described/fixed below. I agree
> that it is not a bug though:
>
> To expand on the questionable design decisions:
>
>
> There is no good reason for item amend to be an adverb.
> The problem with the gerund version of amend that Henry helped with is in v0.
> It produces x v0 y and not x ([ v0 v1) y which would seem infinitely more
> useful. The v2 part seems unnecessary.
>
> At any rate though:
>
> (0 0;1 1;2 2) (+:@:{)`[`]}i.3 3
> 0 1 2
> 3 8 5
> 6 7 16
>
>
> +: amend (0 0;1 1;2 2) i. 3 3
> 0 1 2
> 3 8 5
> 6 7 16
>
>
> (0 0;1 1;2 2) (3 + {)`[`]}i.3 3
> 3 1 2
> 3 7 5
> 6 7 11
>
>
>
> ----- Original Message -----
> From: Dan Bron <[email protected]>
> To: "[email protected]" <[email protected]>
> Cc:
> Sent: Sunday, March 30, 2014 1:34:27 PM
> Subject: Re: [Jprogramming] Item amend ~: index error.
>
> 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
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm