Лучшие стратегии для чтения кода J - PullRequest
11 голосов
/ 02 мая 2010

Я использую J уже несколько месяцев, и я считаю, что чтение незнакомого кода (например, то, что я не писал сам) является одним из самых сложных аспектов языка, особенно когда он молчалив.Через некоторое время я придумал эту стратегию:

1) Скопируйте сегмент кода в текстовый документ

2) Возьмите каждый оператор из (1) и поместите его в отдельную строку,чтобы он читался вертикально

3) Замените каждый оператор его словесным описанием на странице словаря

4) Сделайте грубый перевод из синтаксиса J в грамматику английского языка

5)Используйте перевод, чтобы определить концептуально связанные компоненты и отделить их с помощью разрывов строк

6) Напишите описание того, что должен делать каждый компонент из (5), в простой английской прозе

7)Напишите описание того, что должна делать вся программа, основываясь на (6)

8) Напишите объяснение того, почему можно сказать, что код из (1) представляет концепцию проекта из (7).

Хотя я многому научился из этого процесса, я считаю, что он довольно трудоемкий и отнимает много времени - особенно если кто-то разрабатывал свою программу, используя концепцию, с которой я никогда не сталкивался раньше.Поэтому я задаюсь вопросом: есть ли у других людей в сообществе J любимые способы выяснить неясный код?Если да, каковы преимущества и недостатки этих методов?

РЕДАКТИРОВАТЬ:

Примером кода, который мне нужно разбить, является следующее:

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

Я написал это сам, так что я случайно узнал, что он принимает числовой ввод, интерпретирует его как троичный массив и интерпретирует результат как представление числа в base-2 с не более чем одним дублированием.(например, binconv 5 = (3 ^ 1) + 2 * (3 ^ 0) -> 1 2 -> (2 ^ 1) + 2 * (2 ^ 0) = 4.) Но если бы я наткнулся на это безлюбую предыдущую историю или документацию, выясняя, что это то, что она делает, было бы нетривиальным упражнением.

Ответы [ 5 ]

10 голосов
/ 25 октября 2013

Просто хотел добавить к Ответ Джордана : если у вас не включен дисплей коробки, вы можете явно отформатировать вещи с помощью 5!:2

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

Также есть отображение дерева:

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

См. Страницу словаря для 5 !: Представление , а также 9 !: Глобальные параметры для изменения по умолчанию.

Кроме того, мой собственный подход к чтению 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
9 голосов
/ 06 мая 2010

Попробуйте сначала разбить глагол на его компоненты, а затем посмотрите, что они делают. И вместо того, чтобы всегда ссылаться на словарь, вы можете просто опробовать компонент на данных, чтобы увидеть, что он делает, и посмотреть, сможете ли вы это выяснить. Чтобы увидеть структуру глагола, полезно знать, на какие части речи вы смотрите, и как идентифицировать базовые конструкции, такие как вилки (и, конечно, в больших неявных конструкциях, разделенных скобками). Простой ввод глагола в окне ijx и нажатие клавиши ввода также разрушит структуру и, вероятно, поможет.

Рассмотрим следующий простой пример: <.@-:@#{/:~

Я знаю, что <. -: # { и /: - все глаголы, ~ - наречие, а @ - соединение (см. Части речевой связи в словаре). ). Поэтому я вижу, что это структура вилки с левым глаголом <.@-:@#, правым глаголом /:~ и диадой {. Это требует некоторой практики, чтобы увидеть, но есть более простой способ, пусть 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, пытаясь разбить большие сложные глаголы. Я думаю, что я бы рекомендовал сосредоточиться на попытке увидеть грамматическую структуру, а затем разбираться с частями, постепенно наращивая ее (поскольку именно так вы в конечном итоге будете писать молчаливые глаголы).

3 голосов
/ 23 мая 2010

(я помещаю это в раздел ответов вместо того, чтобы редактировать вопрос, потому что вопрос выглядит достаточно длинным.)

Я только что нашел отличную статью на на веб-сайте jsoftware , которая хорошо работает в сочетании с ответом Джордана и методом, который я описал в этом вопросе. Автор делает некоторые соответствующие замечания:

1) Глагол, измененный наречием, является глаголом.

2) Череда из более чем трех последовательных глаголов представляет собой серию вилок, которые могут иметь один глагол или крючок с левой стороны в зависимости от количества глаголов.

Это ускоряет процесс перевода молчаливого выражения на английский, поскольку позволяет группировать глаголы и наречия в концептуальные единицы, а затем использовать вложенную структуру вилок, чтобы быстро определить, является ли экземпляр оператора монадическим или двоичным. Вот пример перевода, который я сделал, используя усовершенствованный метод:

d28=: [:+/\{.@],>:@[#(}.-}:)@]%>:@[

[: +/\

{.@] ,

>:@[ #

(}.-}:)@] %

>:@[
  • cap (плюс префикс инфикса)

    (голова на правом аргументе) ravel

    (увеличение на верхний левый аргумент) подсчет

    (обезглавленный минус) сверху справа Аргумент

    делится на

    увеличение на левый аргумент

  • частичные суммы последовательности определяется

    первый пункт правильного аргумента, Равель вместе с

    (один плюс левый аргумент) копии из

    (все, кроме первого элемента) минус (все, кроме последнего элемента)

    правильного аргумента, разделенного на

    (один плюс левый аргумент).

  • частичные суммы последовательности определяется

    начиная с той же начальной точки,

    и добавление последовательных копий точки, полученные из правильного аргумента

    вычитая каждого предшественника из его Преемник

    и деление результата на число количество сделанных копий

  • Интерполяция значений x-много между предметы у
1 голос
/ 01 ноября 2011

Я просто хочу поговорить о том, как я читаю: <@ -:. @ # {/: ~ </p>

Во-первых, я знал, что если это была функция, то из командной строки ее нужно было вводить (для тестирования) как

(<@ -:. @ # {/: ~) </p>

Теперь я посмотрел на вещи в скобках. Я увидел /: ~, который возвращает отсортированный список своих аргументов, {который выбирает элемент из списка, # который возвращает количество элементов в списке, -: половина и <., Этаж ... и я начал думать, что это может быть медиана, - половина количества элементов в списке округлена в меньшую сторону, но как # получить свои аргументы? Я посмотрел на знаки @ - и понял, что там было три глагола - так что это вилка. Список приходит справа и сортируется, затем слева, форк получил список #, чтобы получить количество аргументов, и тогда мы знали, что это заняло половину этого. Итак, теперь у нас есть последовательность выполнения: </p>

отсортируйте и передайте вывод среднему глаголу в качестве правильного аргумента.

Возьмите пол половины числа элементов в списке, и это станет левым аргументом среднего глагола.

Сделай средний глагол.

Это мой подход. Я согласен, что иногда фразы содержат слишком много странных вещей, и вам нужно их искать, но я всегда выясняю это в командной строке J.

1 голос
/ 24 февраля 2011

Лично я думаю о J-коде с точки зрения того, что он делает - если у меня нет примеров примеров, я быстро теряюсь. Если у меня есть примеры, мне обычно легко увидеть, что делает подвыражение.

И когда это становится трудным, это означает, что мне нужно найти слово в словаре или, возможно, изучить его грамматику.

Читая рецепты здесь, я понимаю, что это не слишком отличается от того, как другие люди работают с языком.

Может быть, нам следует назвать это «тестом на основе понимания»?

...