2010-05-02 7 views
11

Ho usato J da alcuni mesi e trovo che leggere un codice non familiare (ad esempio che non ho scritto io stesso) sia uno degli aspetti più impegnativi della lingua, in particolare quando è in tacita. Dopo un po ', mi si avvicinò con questa strategia:Le migliori strategie per leggere il codice J

1) Copiare il segmento di codice in un documento Word

2) Prendere ogni operatore da (1) e posizionarlo su una riga separata, in modo che legga verticalmente

3) Sostituire ogni operatore con la sua descrizione verbale nella pagina di vocabolario

4) fare una traduzione approssimativa dalla sintassi J in inglese grammatica

5) Utilizzare la traduzione per identificare i componenti concettualmente correlati e separarli con interruzioni di riga

6) Scrivere una descrizione di ciò che ogni componente da (5) che deve fare, in pianura prosa inglese

7) una descrizione di ciò che si suppone l'intero programma di fare, basato su (6)

8) Scrivi una spiegazione del perché il codice da (1) può essere detto per rappresentare il concetto di progetto da (7).

Anche se imparo molto da questo processo, trovo che sia piuttosto arduo e dispendioso in termini di tempo, soprattutto se qualcuno ha progettato il proprio programma utilizzando un concetto che non ho mai incontrato prima. Quindi mi chiedo: le altre persone nella comunità J hanno i modi preferiti per capire il codice oscuro? Se sì, quali sono i vantaggi e gli svantaggi di questi metodi?

EDIT:

Un esempio del sorta di codice che avrei avuto bisogno di abbattere è la seguente:

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

ho scritto questo uno io, così mi capita di sapere che ci vuole un numerica input, reinterpreta come array ternario e interpreta il risultato come la rappresentazione di un numero in base-2 con al massimo una duplicazione. (ad esempio, binconv 5 = (3^1) + 2 * (3^0) -> 1 2 -> (2^1) + 2 * (2^0) = 4) Ma se mi fossi imbattuto in esso senza qualsiasi storia precedente o documentazione, capire che questo è quello che fa sarebbe un esercizio non banale.

risposta

9

Provare prima a rompere il verbo nei suoi componenti e poi vedere cosa fanno. E piuttosto che riferirsi sempre al vocabolario, potresti semplicemente provare un componente sui dati per vedere cosa fa e vedere se riesci a capirlo. Per vedere la struttura del verbo, è utile sapere quali parti del discorso stai guardando e come identificare le costruzioni di base come i fork (e, ovviamente, in costruzioni tacite più grandi, separate da parentesi). Digitando semplicemente il verbo nella finestra di ijx e premendo Invio si analizza anche la struttura, e probabilmente aiuta.

Si consideri il seguente esempio semplice: <[email protected]:@#{/:~

So che <.-:#{ e /: sono tutti i verbi, ~ è un avverbio, e @ è una congiunzione (vedere le parti di collegamento discorso nel vocabolario). Quindi posso vedere che questa è una struttura a forcella con il verbo sinistro <[email protected]:@#, il verbo destro /:~ e la diade {.Questo richiede una certa pratica per vedere, ma c'è un modo più semplice, lasciare che J si struttura mostrare digitando nella finestra ijx e premendo Invio:

<[email protected]:@#{/:~ 
+---------------+-+------+ 
|+---------+-+-+|{|+--+-+| 
||+--+-+--+|@|#|| ||/:|~|| 
|||<.|@|-:|| | || |+--+-+| 
||+--+-+--+| | || |  | 
|+---------+-+-+| |  | 
+---------------+-+------+ 

Qui potete vedere la struttura del verbo (o, sarai in grado di dopo esserti abituato a guardarli). Quindi, se non riesci a identificare i pezzi, gioca con loro per vedere cosa fanno.

10?20 
15 10 18 7 17 12 19 16 4 2 
    /:~ 10?20 
1 4 6 7 8 10 11 15 17 19 
    <[email protected]:@# 10?20 
5 

È possibile abbattere ulteriormente e sperimentare come necessario per capire fuori (questo piccolo esempio è un verbo mediana).

J racchiude un sacco di codice in pochi caratteri e grandi verbi tacit possono sembrare molto intimidatori, anche per utenti esperti. Sperimentare sarà più veloce del tuo metodo di documentazione, e puoi davvero imparare molto su J cercando di abbattere i verbi complessi di grandi dimensioni. Penso che consiglierei di concentrarsi sul cercare di vedere la struttura grammaticale e quindi di capire i pezzi, costruendoli passo dopo passo (poiché è così che alla fine si scrivono i verbi taciti).

+0

Interessante. Non ho mai rotto le cose in modo esplicito in termini di parti di discorso prima - in genere il mio pensiero rimane al livello di struttura rispetto agli operatori di sostanze, almeno quando sto decodificando i verbi taciti nel frasario J per esercitarsi o cercando di capire cosa diavolo stava pensando Roger Hui quando ha scritto le sue soluzioni Project Euler. – estanford

3

(sto mettendo questo nella sezione di risposta invece di modificare la domanda, perché la questione sembra abbastanza a lungo come è.)

Ho appena trovato un ottimo documento su the jsoftware website che funziona bene in combinazione con la risposta di Jordan e il metodo che ho descritto nella domanda. L'autore fa alcune osservazioni pertinenti:

1) Un verbo modificato da un avverbio è un verbo.

2) Un treno di più di tre verbi consecutivi è una serie di forcelle, che possono avere un singolo verbo o un gancio all'estremità sinistra a seconda del numero di verbi presenti.

Questo accelera il processo di traduzione di un'espressione tacita in inglese, poiché consente di raggruppare verbi e avverbi in unità concettuali e quindi di utilizzare la struttura a forcella nidificata per determinare rapidamente se un'istanza di un operatore è monadica o diadica.Ecco un esempio di una traduzione che ho fatto con il metodo raffinato:

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

[: +/\ 

{[email protected]] , 

>:@[ # 

(}.-}:)@] % 

>:@[ 
  • tappo (più prefisso infisso)

    (testa in cima argomento a destra) Ravel

    (incremento in cima argomento di sinistra) tally

    (decapitare meno curtail) in cima a destra argomento

    diviso per

    incremento cima argomento sinistra

  • le somme parziali della sequenza definito da

    il primo elemento dell'argomento destra, sfilacciata insieme

    (uno più il argomento a sinistra) copia di

    (tutto tranne il primo elemento) meno (tutti tranne l'ultimo elemento)

    dell'argomento a destra, diviso per

    (uno più l'argomento a sinistra).

  • le somme parziali della sequenza definito da

    iniziano con lo stesso punto iniziale,

    e aggiungendo copie consecutive punti derivati ​​dalla tesi destra

    sottraendo ciascuna predecessore da il suo successore

    e dividendo il risultato con il numero di copie da eseguire

  • interpolazione valori x-molti tra le voci di y
1

Personalmente, penso di codice J in termini di ciò che fa - se non ho alcun argomento di esempio , Mi sono rapidamente perso. Se ho degli esempi, di solito è facile per me vedere cosa sta facendo una sotto-espressione.

E, quando diventa difficile, significa che ho bisogno di cercare una parola nel dizionario, o forse di studiarne la grammatica.

Leggendo le prescrizioni qui, ho l'impressione che questo non sia molto diverso da come le altre persone lavorano con la lingua.

Forse dovremmo chiamare questo 'Test Driven Comprehension'?

1

Voglio solo parlare di come ho letto: <[email protected] -: @ # {/: ~

Prima di tutto, sapevo che se fosse una funzione, dalla riga di comando, doveva essere inserito (per la prova) come

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

Ora ho guardato le cose tra parentesi. Ho visto un /: ~, che restituisce un elenco ordinato dei suoi argomenti, {che seleziona un elemento da un elenco, # che restituisce il numero di elementi in un elenco, -: metà e <., Piano ... e I ho iniziato a pensare che potesse essere una mediana, - metà del numero di elementi nell'elenco è stato arrotondato per difetto, ma in che modo # ha ottenuto i suoi argomenti? Ho guardato i segni @ e ho capito che c'erano tre verbi lì - quindi questa è una forchetta. L'elenco viene visualizzato a destra ed è ordinato, quindi a sinistra, la forchetta ha ottenuto l'elenco sul numero # per ottenere il numero di argomenti, e quindi sapevamo che ci voleva per metà. Quindi ora abbiamo la sequenza di esecuzione:

ordina e passa l'output al verbo centrale come argomento corretto.

Prendere la metà del numero di elementi nell'elenco e questo diventa l'argomento di sinistra del verbo centrale.

Fai il verbo centrale.

Questo è il mio approccio. Sono d'accordo che a volte le frasi hanno troppe cose strane, e devi cercarle, ma sto sempre cercando di capire questa cosa alla riga di comando di J instant.

10

Volevo solo aggiungere alla Jordan's Answer: se non si dispone di casella di visualizzazione attivata, è possibile formattare le cose in questo modo in modo esplicito con 5!:2

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

C'è anche una visualizzazione ad albero:

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

Vedere la pagina del vocabolario per 5!: Representation e anche 9!: Global Parameters per modificare l'impostazione predefinita.

Inoltre, per quello che vale, il mio approccio alla lettura di J è stato quello di ridigitare l'espressione a mano, costruendola da destra a sinistra, e guardando i pezzi mentre procedo, e usando le funzioni di identità per formare temporaneamente si allena quando è necessario.

Così, per esempio:

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

addendum:

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