代码之家  ›  专栏  ›  技术社区  ›  estanford

阅读J代码的最佳策略

  •  11
  • estanford  · 技术社区  · 14 年前

    1) 将代码段复制到word文档中

    4) 把J语法粗略地翻译成英语语法

    5) 使用翻译识别概念上相关的组件,并用换行符将它们分开

    6) 用平实的英语散文描述(5)中的每个组成部分应该做什么

    8) 写一个解释,说明为什么(1)中的代码可以表示(7)中的设计概念。

    虽然我从这个过程中学到了很多东西,但我发现这是一个相当艰巨和耗时的过程——特别是如果有人使用我以前从未遇到过的概念来设计他们的程序。所以我想知道:J社区的其他人有没有最喜欢的方法来找出晦涩难懂的代码?如果是的话,这些方法的优点和缺点是什么?

    编辑:

    binconv =: +/@ ((|.@(2^i.@#@])) * ]) @ ((3&#.)^:_1)
    

    我自己写了这个,所以我碰巧知道它需要一个数字输入,将它重新解释为一个三元数组,并将结果解释为一个以2为基数的数字的表示,最多有一个重复(e、 例如,binconv 5=(3^1)+2*(3^0)—>1 2->(2^1)+2*(2^0)=4。)但如果我在没有任何历史或文献的情况下偶然发现了它,弄清楚它的用途将是一个不平凡的练习。

    5 回复  |  直到 14 年前
        1
  •  10
  •   Jordan    14 年前

    试着先把动词分成不同的成分,然后看看它们是怎么做的。不必总是引用vocab,您可以简单地在数据上尝试一个组件,看看它做了什么,看看您是否能找到它。要了解动词的结构,就要知道你在看什么词类,以及如何识别像forks这样的基本结构(当然,在较大的隐性结构中,用括号隔开)。只需在ijx窗口中键入动词并按enter键,也可以分解结构,可能会有所帮助。

    <.@-:@#{/:~

    <. -: # { /: 都是动词, ~ 是副词,并且 @ 是连词(参见词汇表中的词性链接)。因此,我可以看到这是一个左动词叉结构 <.@-:@# /:~ ,和二元体 { . 这需要一些练习才能看到,但有一种更简单的方法,让J在ijx窗口中键入并按enter键来显示结构:

       <.@-:@#{/:~
    +---------------+-+------+
    |+---------+-+-+|{|+--+-+|
    ||+--+-+--+|@|#|| ||/:|~||
    |||<.|@|-:|| | || |+--+-+|
    ||+--+-+--+| | || |      |
    |+---------+-+-+| |      |
    +---------------+-+------+
    

    在这里你可以看到动词的结构(或者,你习惯了看这些之后就可以看到了)。然后,如果你不能识别这些片段,就和它们一起玩,看看它们能做什么。

       10?20
    15 10 18 7 17 12 19 16 4 2
       /:~ 10?20
    1 4 6 7 8 10 11 15 17 19
       <.@-:@# 10?20
    5
    

    你可以进一步分解它们,并根据需要进行实验来找出它们(这个小例子是一个中间动词)。

    J将大量代码打包成几个字符,大的默认动词看起来非常吓人,即使对有经验的用户也是如此。实验将比你的文档化方法更快,而且你可以通过尝试分解大型复杂动词来学习很多关于J的知识。我想我建议你集中精力去看语法结构,然后找出其中的部分,一步一步地建立起来(因为你最终会这样写默契动词)。

        2
  •  11
  •   Community CDub    7 年前

    只是想增加 Jordan's Answer 5!:2

       f =. <.@-:@#{/:~
       5!:2 < 'f'
    ┌───────────────┬─┬──────┐
    │┌─────────┬─┬─┐│{│┌──┬─┐│
    ││┌──┬─┬──┐│@│#││ ││/:│~││
    │││<.│@│-:││ │ ││ │└──┴─┘│
    ││└──┴─┴──┘│ │ ││ │      │
    │└─────────┴─┴─┘│ │      │
    └───────────────┴─┴──────┘
    

    还有一个树显示:

       5!:4 <'f'
                  ┌─ <.
            ┌─ @ ─┴─ -:
      ┌─ @ ─┴─ #       
    ──┼─ {             
      └─ ~ ─── /:     
    

    有关详细信息,请参见词汇表页 5!: Representation 还有 9!: Global Parameters

    另外,为了更好地阅读J,我自己的阅读方法是用手重新键入表达式,从右到左构建表达式,并在需要时查找片段,使用标识函数形成临时序列。

    例如:

       /:~ i.5
    0 1 2 3 4
       NB. That didn't tell me anything
       /:~ 'hello'
    ehllo
       NB. Okay, so it sorts. Let's try it as a train:
       [ { /:~ 'hello'
    ┌─────┐
    │ehllo│
    └─────┘
       NB. Whoops. I meant a train:
       ([ { /:~) 'hello'
    |domain error
    |       ([{/:~)'hello'
       NB. Not helpful, but the dictionary says
       NB. "{" ("From") wants a number on the left.
       (0: { /:~) 'hello'
    e
       (1: { /:~) 'hello'
    h
       NB. Okay, it's selecting an item from the sorted list.
       NB. So f is taking the ( <. @ -: @ # )th item, whatever that means...
       <. -: # 'hello'
    2
       NB. ??!?....No idea. Let's look up the words in the dictionary.
       NB. Okay, so it's the floor (<.) of half (-:) the length (#)
       NB. So the whole phrase selects an item halfway through the list.
       NB. Let's test to make sure.
       f 'radar' NB. should return 'd'
    d
       NB. Yay!
    

    附录:

       NB. just to be clear:
       f 'drara' NB. should also return 'd' because it sorts first
    d
    
        3
  •  3
  •   estanford    14 年前

    (我把这个放在答案部分而不是编辑问题,因为问题看起来足够长。)

    我刚在网上找到一篇优秀的论文 the jsoftware website 结合乔丹的回答和我在问题中描述的方法,这个方法很有效。作者提出了一些中肯的意见:

    1) 副词修饰的动词是动词。

    这加快了将默认表达式翻译成英语的过程,因为它可以让您将动词和副词分组为概念单位,然后使用嵌套的fork结构快速确定操作符的实例是一元还是二元的。下面是一个我使用精化方法进行翻译的例子:

    d28=: [:+/\{.@],>:@[#(}.-}:)@]%>:@[
    
    [: +/\
    
    {.@] ,
    
    >:@[ #
    
    (}.-}:)@] %
    
    >:@[
    
    • (右上角)拉威尔

      (左参数)计数

      (斩首减去剪短)右上角 论点

      除以

      左变元增量

    • 序列的部分和 定义人

      与…在一起

      (一加左参数)副本

      (除第一个元素外)减去 (除了最后一个元素)

      正确的论点,除以

    • 序列的部分和 定义人

      从同一初始点开始,

      由正确的论点导出的点

      从每个前置任务中减去每个前置任务 继承人

    • y的项目
        4
  •  1
  •   rdm    14 年前

    通过阅读这里的处方,我得到了这样一个想法:这与其他人使用语言的方式没有太大区别。

        5
  •  1
  •   Nick    13 年前

    我只想谈谈我是如何阅读的: <@-:@{/:~

    首先,我知道如果它是一个函数,那么从命令行,它必须作为

    现在我看看括号里的东西。我看到一个/:~,它返回参数的排序列表,{它从列表中选择一项,#它返回列表中的项数,-:half和<。,地板…我开始认为它可能是中位数,-列表中项目数的一半向下舍入,但是#如何得到它的论点?我看了看@符号,意识到那里有三个动词,所以这是叉子。列表在右边,经过排序,然后在左边,fork把列表放到#上,得到参数的数目,然后我们知道它占了一半。现在我们有了执行顺序:

    以列表中元素数量的一半为基础,这就成为中间动词的左参数。

    做中间的动词。

    这是我的方法。我同意有时短语有太多奇怪的东西,你需要查找它们,但我总是在J instant命令行中找出这些东西。