14 Stimmen

Die besten Strategien zum Lesen von J-Code

Ich benutze J jetzt seit ein paar Monaten und finde, dass das Lesen von unbekanntem Code (z.B. den ich nicht selbst geschrieben habe) einer der schwierigsten Aspekte der Sprache ist, besonders wenn er stillschweigend vorliegt. Nach einer Weile bin ich auf diese Strategie gekommen:

1) Kopieren Sie das Codesegment in ein Word-Dokument

2) Nehmen Sie jeden Operator aus (1) und setzen Sie ihn in eine eigene Zeile, so dass er senkrecht steht

3) Ersetzen Sie jeden Operator durch seine verbale Beschreibung auf der Seite Vokabular

4) Erstellen Sie eine grobe Übersetzung von J-Syntax in englische Grammatik

5) Verwenden Sie die Übersetzung, um konzeptionell zusammenhängende Komponenten zu identifizieren, und trennen Sie sie durch Zeilenumbrüche

6) Beschreiben Sie in einfacher englischer Prosa, was jede Komponente aus (5) tun soll.

7) Schreiben Sie eine Beschreibung dessen, was das gesamte Programm auf der Grundlage von (6) tun soll

8) Erläutern Sie, warum der Code aus (1) das Designkonzept aus (7) repräsentiert.

Obwohl ich dabei viel lerne, finde ich es ziemlich mühsam und zeitaufwändig - vor allem, wenn jemand sein Programm nach einem Konzept entwickelt hat, das ich noch nie gesehen habe. Deshalb frage ich mich: Haben andere in der J-Gemeinschaft Lieblingsmethoden, um obskuren Code zu entschlüsseln? Wenn ja, was sind die Vor- und Nachteile dieser Methoden?

EDIT:

Ein Beispiel für die Art von Code, die ich aufschlüsseln müsste, ist der folgende:

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

Ich habe dieses Programm selbst geschrieben, daher weiß ich zufällig, dass es eine numerische Eingabe nimmt, sie als ternäres Array uminterpretiert und das Ergebnis als Darstellung einer Zahl zur Basis 2 mit höchstens einer Verdopplung interpretiert. (z.B. binconv 5 = (3^1)+2*(3^0) -> 1 2 -> (2^1)+2*(2^0) = 4.) Wäre ich jedoch ohne Vorgeschichte oder Dokumentation auf die Funktion gestoßen, wäre es eine nicht ganz einfache Aufgabe, herauszufinden, dass sie genau das tut.

13voto

tangentstorm Punkte 6993

Ich wollte nur hinzufügen, dass Jordans Antwort : Wenn Sie die Box-Anzeige nicht eingeschaltet haben, können Sie diese Formatierung explizit mit 5!:2

   f =. <.@-:@#{/:~
   5!:2 < 'f'

{
@# /:~
<.@-:   

Außerdem gibt es eine Baumausstellung:

   5!:4 <'f'
               <.
         @  -:
   @  #       
 {             
   ~  /:     

Siehe die Vokabelseite für 5!: Vertretung und auch 9!: Globale Parameter zum Ändern der Standardeinstellung.

Mein eigener Ansatz beim Lesen von J besteht darin, den Ausdruck von Hand abzutippen, ihn von rechts nach links aufzubauen und die einzelnen Teile nach und nach nachzuschlagen und bei Bedarf mit Hilfe von Identitätsfunktionen temporäre Züge zu bilden.

So zum Beispiel:

   /:~ 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!

Nachtrag:

   NB. just to be clear:
   f 'drara' NB. should also return 'd' because it sorts first
d

11voto

Jordan Punkte 226

Versuchen Sie zunächst, das Verb in seine Bestandteile zu zerlegen, und sehen Sie dann, was diese bewirken. Anstatt sich immer auf die Vokabeln zu beziehen, können Sie auch einfach eine Komponente an Daten ausprobieren, um zu sehen, was sie bewirkt, und dann sehen, ob Sie es herausfinden können. Um die Struktur des Verbs zu erkennen, ist es hilfreich zu wissen, welche Wortarten man betrachtet und wie man grundlegende Konstruktionen wie Gabelungen erkennt (und natürlich, bei größeren stillschweigenden Konstruktionen, durch Klammern trennt). Wenn Sie das Verb einfach in das ijx-Fenster eintippen und die Eingabetaste drücken, wird die Struktur ebenfalls aufgeschlüsselt, was wahrscheinlich hilfreich ist.

Betrachten Sie das folgende einfache Beispiel: <.@-:@#{/:~

Ich weiß, dass <. -: # { y /: sind alle Verben, ~ ist ein Adverb, und @ ist eine Konjunktion (siehe den Link zu den Wortarten im Vokabular). Daher kann ich sehen, dass dies eine Gabelstruktur mit linkem Verb ist <.@-:@# , rechtes Verb /:~ und Dyade { . Es braucht etwas Übung, um dies zu erkennen, aber es gibt einen einfacheren Weg: Lassen Sie sich von J die Struktur zeigen, indem Sie sie in das ijx-Fenster eingeben und die Eingabetaste drücken:

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

Hier können Sie die Struktur des Verbs sehen (oder Sie können es sehen, wenn Sie sich daran gewöhnt haben, diese zu sehen). Wenn Sie die Teile nicht identifizieren können, spielen Sie mit ihnen, um zu sehen, was sie tun.

   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

Sie können sie weiter aufschlüsseln und nach Bedarf experimentieren, um sie herauszufinden (dieses kleine Beispiel ist ein medianes Verb).

J packt eine Menge Code in wenige Zeichen und große stillschweigende Verben können sehr einschüchternd wirken, selbst für erfahrene Benutzer. Experimentieren geht schneller als Ihre Dokumentationsmethode, und Sie können wirklich viel über J lernen, indem Sie versuchen, große komplexe Verben aufzuschlüsseln. Ich denke, ich würde empfehlen, sich darauf zu konzentrieren, die grammatikalische Struktur zu erkennen und dann die einzelnen Teile herauszufinden, indem man sie Schritt für Schritt aufbaut (denn so werden Sie schließlich stillschweigende Verben schreiben).

3voto

estanford Punkte 1292

(Ich schreibe dies in den Antwortteil, anstatt die Frage zu bearbeiten, weil die Frage so schon lang genug ist).

Ich habe gerade einen hervorragenden Artikel über die jsoftware-Website die sich gut mit Jordans Antwort und der von mir in der Frage beschriebenen Methode kombinieren lässt. Der Autor macht einige sachdienliche Beobachtungen:

1) Ein durch ein Adverb modifiziertes Verb ist ein Verb.

2) Eine Folge von mehr als drei aufeinanderfolgenden Verben ist eine Reihe von Gabelungen, die je nach Anzahl der Verben ein einzelnes Verb oder einen Haken ganz links haben können.

Dies beschleunigt den Prozess der Übersetzung eines stillschweigenden Ausdrucks ins Englische, da Sie Verben und Adverbien in konzeptuelle Einheiten gruppieren und dann die verschachtelte Gabelstruktur verwenden können, um schnell festzustellen, ob eine Instanz eines Operators monadisch oder dyadisch ist. Hier ist ein Beispiel für eine Übersetzung, die ich mit der verfeinerten Methode angefertigt habe:

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

[: +/\

{.@] ,

>:@[ #

(}.-}:)@] %

>:@[
  • cap (plus Infix-Präfix)

    (Kopf oben rechts Argument) ravel

    (Inkrement bei linkem Argument) tally

    (köpfen minus beschneiden) oben rechts Argument

    geteilt durch

    Inkrement bei linkem Argument oben

  • die Partialsummen der Folge definiert durch

    das erste Element des rechten Arguments, verschlungen mit

    (eins plus das linke Argument) kopiert von

    (alle bis auf das erste Element) minus (alle bis auf das letzte Element)

    des rechten Arguments, geteilt durch

    (eins plus das linke Argument).

  • die Partialsummen der Folge definiert durch

    ausgehend von demselben Ausgangspunkt,

    und das Anhängen von aufeinanderfolgenden Kopien von Punkten, die aus dem rechten Argument durch

    Subtraktion jedes Vorgängers von seinem Nachfolger

    und dividiert das Ergebnis durch die Zahl der zu erstellenden Kopien

  • Interpolieren von x-many-Werten zwischen den Elementen von y

2voto

Nick Punkte 199

Ich möchte nur darüber sprechen, wie ich lese: <.@-:@#{/:~

Zunächst einmal wusste ich, dass eine Funktion in der Befehlszeile (zum Testen) wie folgt eingegeben werden musste

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

Jetzt habe ich mir die Sachen in der Klammer angesehen. Ich sah /:~, das eine sortierte Liste seiner Argumente zurückgibt, {, das ein Element aus einer Liste auswählt, #, das die Anzahl der Elemente in einer Liste zurückgibt, -: die Hälfte, und <., floor...und ich begann zu denken, dass es der Median sein könnte, - die Hälfte der Anzahl der Elemente in der Liste abgerundet, aber wie bekam # seine Argumente? Ich sah mir die @-Zeichen an - und stellte fest, dass es drei Verben gab - also ist dies eine Gabelung. Die Liste kommt auf der rechten Seite herein und wird sortiert, dann auf der linken Seite hat die Gabelung die Liste bis zum # gebracht, um die Anzahl der Argumente zu erhalten, und dann wussten wir, dass sie die Hälfte davon genommen hat. Jetzt haben wir also die Ausführungsreihenfolge:

sortieren und die Ausgabe als rechtes Argument an das mittlere Verb übergeben.

Nehmen Sie die Hälfte der Anzahl der Elemente in der Liste, und das wird das linke Argument des mittleren Verbs.

Machen Sie das mittlere Verb.

Das ist mein Ansatz. Ich stimme zu, dass die Phrasen manchmal zu viele merkwürdige Dinge enthalten und man sie nachschlagen muss, aber ich finde diese Dinge immer in der J instant Befehlszeile heraus.

1voto

rdm Punkte 46

Ich persönlich denke bei J-Code an das, was er tut - wenn ich keine Beispielargumente habe, bin ich schnell verloren. Wenn ich Beispiele habe, ist es für mich in der Regel einfach zu sehen, was ein Unterausdruck tut.

Und wenn es schwierig wird, bedeutet das, dass ich ein Wort im Wörterbuch nachschlagen oder möglicherweise seine Grammatik studieren muss.

Wenn ich mir die Rezepte hier durchlese, habe ich den Eindruck, dass sich dies nicht allzu sehr von der Art und Weise unterscheidet, wie andere Menschen mit der Sprache arbeiten.

Vielleicht sollten wir dies "Test Driven Comprehension" nennen?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X