I am surprised. Thank you,
-- Raul On Sat, Oct 5, 2013 at 1:55 PM, Dan Bron <[email protected]> wrote: > Thanks, this makes sense and I believe reflects the language of the > Dictionary. > > However, there is a discrepancy between the parser defined in the Dictionary > and the one implemented in the interpreter with regard to when names are > resolve [1,2]. In particular, while the Dictionary says name resolution > occurs as described below, in practice name resolution is only immediate > (i.e., when the name is popped of the stack) for nouns. For non-nouns, > including verbs, adverbs, conjunctions, and undefined names, name resolution > is deferred as long as possible. > > [1] "Adverbs/Conjunctions are stacked by name": > http://www.jsoftware.com/pipermail/general/2002-January/010688.html > > [2] "Stacking by name": > http://www.jsoftware.com/pipermail/programming/2009-August/015810.html > > > -----Original Message----- > From: [email protected] > [mailto:[email protected]] On Behalf Of Raul Miller > Sent: Friday, October 04, 2013 12:20 AM > To: Chat forum > Subject: Re: [Jchat] my programm looks terrible > > Name resolution happens when the name is shifted past the top of the stack if > the name refers to a noun, an adverb or a conjunction. It does not happen > for names which refers to verbs nor does it happen for undefined names. The > parsing rules treat undefined names as if they were verbs (and this can be an > error, if the definition of the verb is needed). > > Note also that the name of a verb has a locale associated with it. > This can happen in three different ways: > > 1) name_locale_ > 2) name__localereference > 3) name > > In case 1), the locale is included in with the name. In case 2) there's an > indirect reference to the locale (it's identified in another variable which > is accessible in the current context). > > ex_a_=: 1 > ex_b_=: 2 > ex=: <'a' > ex__ex > 1 > > In case 3) there's an implied reference to the current locale, and I thought > this was retained even if the verb is processed in another locale, but when I > tested this idea I found it not to be the case in my example: > > f_a_=: 3: > f_b_=: 4: > do_a_ 'g_b_=: f' > > g_b_ '' > 4 > > I think I am puzzled by this result, I was expecting a 3. > > Does anyone feel like telling me where I went wrong? > > Thanks, > > -- > Raul > > > On Thu, Oct 3, 2013 at 7:38 PM, Dan Bron <[email protected]> wrote: >> Thanks. This walkthrough of how the parser thinks about things (as opposed >> to how I think about things) was helpful for me. >> >> Could you further elaborate on this statement? >> >>> Name resolution happens when a name is shifted from the first position >>> on the stack to the second. >> >> In particular, does this apply to all name resolutions, or just pronouns? >> Are there cases where name resolution is deferred until the actual value (as >> opposed to nameclass) of the name is needed to evaluate a sentence? >> >> -Dan >> >> Please excuse typos; composed on a handheld device. >> >> On Oct 3, 2013, at 1:56 PM, Raul Miller <[email protected]> wrote: >> >>> [caution: i have been interrupted several times while composing this >>> message. I been trying to make things consistent but if something >>> looks inconsistent you should assume that your observations are >>> accurate and then experiment to find out what really happens. >>> Assuming, of course, you have time...] >>> >>> Personally, I am fond of making sure people understand the basics. So >>> let's take the line that Dan advertised as being sneaky: >>> >>> RE =. +1 :n=. |. <;._2 noun define >>> >>> J executes its sentences from right to left. So the first word it >>> encounters is 'define' which has the definition (: 0). In addition to >>> being a perhaps cute smiley, this is the 'explicit definition' defined >>> at http://www.jsoftware.com/help/dictionary/d310n.htm >>> >>> Since that's pretty much the whole language, let's kind of skip over >>> it and just accept, for now, that it's defining something. >>> >>> The next word encountered is 'noun' which has the definition (0). >>> Zero, if you recall, is the thing that if you add 3 to it you get 3. >>> In other words, it's just a number. >>> >>> Anyways, when we combine 0 and (: 0) we get (0 : 0) - when executed, >>> the J interpreter grabs subsequent lines from the session until >>> terminated by a closing parenthesis. (This is, perhaps, a slight nudge >>> at the lisp crowd, who use the closing parenthesis for a similar >>> purpose despite their lack of respect for individual lines.) The >>> result of evaluating (0 : 0) will then be those lines. (This can be >>> fun to play with.) >>> >>> Anyways, at this point we have executed two rules from >>> http://www.jsoftware.com/help/dictionary/dicte.htm >>> >>> The first rule was 3 Adverb and the second rule was the '4 Conj' rule >>> listed near the bottom of the page. >>> >>> This second rule has the pattern: >>> >>> EDGE+AVN VERB+NOUN CONJ VERB+NOUN 4 Conj >>> >>> In other words, when executing a sentence, J is looking at four of the >>> elements of the sentence (perhaps worth noting that some of those >>> elements can be empty - this is important for ending a sentence) and >>> for this rule, those elements must match this pattern: >>> >>> leftmost (EDGE+AVN): the emptiness off the left side of the sentence >>> an assignment operator, a left parenthesis, or an adverb or a verb or >>> a noun. >>> >>> next from the left (VERB+NOUN): a verb or a noun >>> >>> next after that (CONJ): a conjunction >>> >>> rightmost: (VERB+NOUN): a verb or a noun. >>> >>> In this example, both of the VERB+NOUN values were the number 0, and >>> the CONJ was the explicit definition symbol. (Hopefully this is >>> explicit enough?) >>> >>> Anyways, here's a more mechanical description of how this shift reduce >>> grammar works: >>> >>> sentence: RE =. +1 :n=. |. <;._2 noun define >>> >>> parsed into tokens: >>> ;:' RE =. +1 :n=. |. <;._2 noun define' >>> ┌──┬──┬─┬─┬─┬─┬──┬──┬─┬──┬──┬────┬──────┐ >>> │RE│=.│+│1│:│n│=.│|.│<│;.│_2│noun│define│ >>> └──┴──┴─┴─┴─┴─┴──┴──┴─┴──┴──┴────┴──────┘ >>> >>> (If your email client messes up the display of that result, just >>> execute the sentence for yourself in a J interpreter. That should >>> reproduce the same result.) >>> >>> Once J has the sentence and has parsed it into tokens, it can treat >>> the result as a queue, shifting the rightmost element from the queue >>> onto its evaluation stack (and then after each shift doing a pattern >>> match against the parsing rules and executing the first match). If >>> nothing matches, J performs no operation and attempts another shift. >>> Name resolution happens when a name is shifted from the first position >>> on the stack to the second. >>> >>> So at the point the '3 Adverb' rule triggered, the queue looked like this: >>> >>> RE =. + 1 : n =. |. < ;. >>> >>> And the stack looked like this: >>> >>> leftmost: _2 >>> next left: 0 >>> next left: : 0 >>> rightmost: >>> >>> The parsing rule for 3 Adverb look like this: >>> >>> EDGE+AVN VERB+NOUN ADV ANY 3 Adverb >>> >>> The '3 Adverb' off on the right hand side is just a label and not a >>> part of the rule itself. >>> >>> Also the 'VERB+NOUN' and 'ADV' parts of the rule are highlighted. >>> That's not portable to email. Highlighted means that that's the part >>> of the rule whose values are used in the execution (and these used >>> values will be removed and replaced with the result of the execution >>> of the rule). >>> >>> So after executing 3 Adverb the stack looks like this >>> >>> leftmost: _2 >>> next left: (lots of text) >>> next left: >>> rightmost: >>> >>> Anyways, after completing an execution J goes back to doing its >>> shifting (and pattern matching (and maybe some execution as well), and >>> when the next execution comes around, the queue looks like this: >>> >>> RE =. + 1 : n =. >>> >>> and the stack looks like this: >>> >>> leftmost: |. >>> next left: < >>> next left: ;. >>> rightmost: _2 >>> next right: (lots of text) >>> >>> J only inspects the top four elements of the stack during pattern >>> matching but the stack itself will have an arbitrary depth. >>> >>> And, remembering our '4 Conj' rule, it was: >>> EDGE+AVN VERB+NOUN CONJ VERB+NOUN 4 Conj >>> >>> and if you looked up that parsing and execution page in the >>> dictionary, you'd see that both the VERB+NOUN entries were highlighted >>> as was the CONJ. So the part being executed here is < ;. _2 and those >>> glue together to get a verb that splits on a final delimiting >>> character, chopping it off, and boxing each resulting string. And >>> since we know that our final character in this case will be a newline >>> character, we can call the expected result here a list of boxed lines. >>> >>> For our next step, the queue looks like this: >>> >>> RE =. + 1 : n >>> >>> and the stack looks like this: >>> >>> leftmost: =. >>> next left: |. >>> next left: <;._2 >>> rightmost: lots of text >>> >>> And the rule being executed is '1 Monad', and the elements being >>> processed are the two rightmost. >>> >>> For our next step in execution, the queue looks like >>> >>> RE =. + 1 : n >>> >>> and the stack looks like >>> >>> leftmost: n >>> next left: =. >>> next left: |. >>> rightmost: boxed lines >>> >>> Again, the '1 Monad' rule should trigger, reversing the list of boxes. >>> >>> Now here is a subtle issue which I am not completely certain about: I >>> believe that the next execution step occurs without moving anything >>> from the queue. The '7 Is' rule should kick in here, with the stack >>> being: >>> >>> leftmost: n >>> next left: =. >>> next left: reversed boxes of lines >>> rightmost: >>> >>> This step should set the local value 'n' and should have a result >>> which is the reversed boxes of lines. >>> >>> After some more shifting, the queue should look like this: >>> >>> RE =. >>> >>> And the stack should be: >>> >>> leftmost: + >>> next left: 1 >>> next left: : >>> rightmost: reversed boxes of lines >>> >>> Here, '4 Conj' takes action and the result is an adverb. >>> >>> Next, we get a queue of >>> >>> RE >>> >>> and a stack of >>> >>> leftmost: =. >>> next left: + >>> next left: 1 : (reversed boxes of lines) >>> rightmost: >>> >>> and the '3 Adverb' rule takes action. The boxed lines are then >>> evaluated as the body of this adverb. >>> >>> Next our queue is empty, and our stack looks like >>> >>> leftmost: R >>> next left: =. >>> next left: evaluated result >>> rightmost: empty >>> >>> Finally, we have this: >>> >>> leftmost: empty queue marker >>> next left: evaluated result >>> next left: >>> rightmost: >>> >>> And no rules can trigger here, and since the queue is now empty for >>> real, no syntax error is triggered and we are done executing the >>> sentence. (I showed the queue as having only the supplied tokens, but >>> really there's an "end of queue" token on the far left that we needed >>> to make this last step work right.) >>> >>> Anyways, hopefully I did not make too many mistakes here, and you can >>> either understand something of how J's parsing works despite my >>> mistakes or you can at least understand enough to ask questions about >>> the things I have not treated properly. >>> >>> Thanks, >>> >>> -- >>> Raul >>> >>> On Wed, Oct 2, 2013 at 11:35 PM, inv2004 . <[email protected]> wrote: >>>> Thank you very much! Sorry I cannot answer something about it right now, >>>> because I need much more time to read it and to understand. >>>> >>>> But I see none of < > and { :) >>>> >>>> Thank you, >>>> >>>> >>>> On Wed, Oct 2, 2013 at 10:04 PM, Dan Bron <[email protected]> wrote: >>>> >>>>> Alexander (inv2004) wrote: >>>>>> Description I am trying to calculate: >>>>>> http://www.usacycling.org/news/user/story.php?id=580 >>>>>> source data: https://dl.dropboxusercontent.com/u/34917039/2013.txt >>>>>> J source: https://dl.dropboxusercontent.com/u/34917039/1.j >>>>> >>>>> I knocked together an implementation in J (based on my perhaps-mistaken >>>>> understanding of your problem): >>>>> >>>>> >>>>> http://jsoftware.com/svn/DanBron/trunk/uncategorized/scoreRoadRace.ijs >>>>> >>>>> It didn't take very long to code, but unfortunately it would take much >>>>> longer to explain it in prose. Also, the style is very peculiar to me, >>>>> which means it's dense, and uses some sneaky tricks, so even veteran J >>>>> programmers may find it obscure (e.g. executing the first paragraph, which >>>>> defines 'RE', in reverse order). >>>>> >>>>> I know your goal wasn't to solve this little race scoring puzzle, but to >>>>> use >>>>> the puzzle as a means to learn J. So, if I get some more time over the >>>>> week, >>>>> I may select and dissect pieces of the code. >>>>> >>>>> In the meantime, it may be worth your while to play with it on your own. >>>>> If >>>>> you want to do that, it'll probably be easiest and most fruitful to break >>>>> it >>>>> into pieces and try them out, interactively, in the J session. >>>>> >>>>> So I recommend you replace all the local assignments (=.) with global >>>>> assignments (=:), so all the intermediate names will be available to >>>>> inspect >>>>> and play with individually*. >>>>> >>>>> For example, I think you'll be interested in 'score' and 'catSumCount' >>>>> (and >>>>> their respective dependencies), because these are the heart of the problem >>>>> and also highlight how J expresses such ideas differently, and perhaps >>>>> more >>>>> elegantly, than other programming languages: >>>>> >>>>> score 1+i. 3 NB. Fewer than 5 racers >>>>> 0 0 0 >>>>> score 1+i. 5 NB. 5 racers >>>>> 3 2 1 0 0 >>>>> score 1+i. 10 NB. 10 racers >>>>> 3 2 1 0 0 0 0 0 0 0 >>>>> score 1+i. 11 NB. 11 racers >>>>> 7 5 4 3 2 1 0 0 0 0 0 >>>>> >>>>> >>>>> pointGroup 1+i. 3 NB. Fewer than 5 racers >>>>> 0 >>>>> pointGroup 1+i. 5 NB. 5 racers >>>>> 3 2 1 >>>>> pointGroup 1+i. 10 NB. 10 racers >>>>> 3 2 1 >>>>> pointGroup 1+i. 11 NB. 11 racers >>>>> 7 5 4 3 2 1 >>>>> >>>>> >>>>> pointGroup >>>>> (0;3 2 1;7 5 4 3 2 1;8 6 5 4 3 2 1;10 8 7 6 5 4 3 2 1) {::~ 4 10 20 >>>>> 49 I. # >>>>> >>>>> >>>>> catSumCount 8 7 10 0 3 0 0 0 1 NB. 9 races, score=29, category=3 >>>>> +-+--+-+ >>>>> |3|29|9| >>>>> +-+--+-+ >>>>> catSumCount 5 4 0 7 NB. 4 races, score=16, category=4 >>>>> +-+--+-+ >>>>> |4|16|4| >>>>> +-+--+-+ >>>>> catSumCount 3000 NB. 1 race, score=super high, but still >>>>> category=4 >>>>> +-+----+-+ >>>>> |4|3000|1| >>>>> +-+----+-+ >>>>> >>>>> catSumCount >>>>> +/ (category ; ;) # >>>>> >>>>> (+/ category #) 8 7 10 0 3 0 0 0 1 >>>>> 3 >>>>> >>>>> (+/ , #) 8 7 10 0 3 0 0 0 1 >>>>> 29 9 >>>>> >>>>> 29 category 9 NB. x=sum of scores, y=# of races >>>>> 3 >>>>> 35 category 7 >>>>> 1 >>>>> 35 category 2 >>>>> 1 >>>>> 33 category 5 >>>>> 2 >>>>> >>>>> category >>>>> 4 <. 1 + 35 30 20 I. (* 2&<:) >>>>> >>>>> It's worth noting the core parts of the scoring algorithm, 'pointGroup' >>>>> and >>>>> 'category', are both based on the dyad I. [1]. This is because those parts >>>>> of the scoring system are defined in terms of ranges (a race of 5 to 10 >>>>> riders, a race of 11 to 20 riders vs. a total score from 0 to 20, a total >>>>> score from 21 to 30, etc). >>>>> >>>>> The dyad I., interval index, is a sterling example of the expressivity and >>>>> economy of J's notation. Here, it allows us to define these ranges by >>>>> their >>>>> essential characteristics, the demarcation lines between levels, rather >>>>> than >>>>> the (repetitive, superfluous) contents of each level. Not only is this >>>>> convenient, but critically, it allows these essential characteristics >>>>> stand >>>>> out in our code, rendering it at once briefer and clearer. The >>>>> fundamentals >>>>> are immediately exposed. >>>>> >>>>> For example, compare 'category' with the original 'cat' or 'pointGroup' >>>>> with >>>>> the original 'points'. Heck, compare the code defining GROUPs to the table >>>>> in the official scoring site you linked! Sometimes, formalizing a problem >>>>> makes it even clearer than the specification. And, that little itch you >>>>> feel to start playing with these rules, now that they're exposed and >>>>> accessible?* That's what we mean when we say the notation is >>>>> "suggestive". >>>>> >>>>> I hope this gives you a flavor of the benefits, and joys, of J. >>>>> >>>>> -Dan >>>>> >>>>> * And because it's really easy to do, given J's short feedback loop and >>>>> interactive nature. >>>>> >>>>> [1] Definition of the dyad I., "Interval Index" >>>>> http://www.jsoftware.com/help/dictionary/dicapdot.htm >>>>> >>>>> >>>>> >>>>> ---------------------------------------------------------------------- >>>>> For information about J forums see http://www.jsoftware.com/forums.htm >>>> >>>> >>>> >>>> -- >>>> Regards, >>>> Alexander. >>>> ---------------------------------------------------------------------- >>>> 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
