blocchi di Ruby/chiusure di Java in C


6

Ho cercato di capire come blocchi di Ruby di lavoro, e per farlo ho cercato di attuarle in C.

Un modo semplice per implementare le chiusure è quello di passare a void* allo stack che racchiude la chiusura/funzione ma i blocchi Ruby sembrano gestire anche i ritorni e le istruzioni di interruzione dall'ambito che utilizza il blocco.

loop do 
    break i if (i >= 4000) 
    i *= 2 
end 

Penso che una delle proposte di chiusure per Java funzioni anche così.

Quindi, come implementeresti i blocchi di Ruby/Java-closures in C?

  0

"Quindi, come implementeresti i blocchi di Ruby/Java-closures in C?" Almeno fino a quando non viene rilasciato Java 7, non esiste nulla come Java-closures. 30 gen. 102010-01-30 00:23:52

  0

Sì, ecco perché ho già detto "chiusure di proposte per Java". 03 feb. 102010-02-03 02:06:49

10

Il concetto di chiusure richiede il concetto di contesti. Il contesto di C è basato sullo stack e sui registri della CPU, quindi per creare un blocco/chiusura, è necessario essere in grado di manipolare il puntatore dello stack in modo corretto (e rientraneo) e memorizzare/ripristinare i registri secondo necessità.

Il modo in cui questo viene eseguito dagli interpreti o dalle macchine virtuali consiste nell'avere una struttura context o qualcosa di simile e non utilizzare lo stack e i registri direttamente. Questa struttura tiene traccia di una pila e facoltativamente alcuni registri, se si sta progettando una macchina virtuale basata su registro. Almeno, questo è il modo più semplice per farlo (anche se un po 'meno performante rispetto alla mappatura effettiva delle cose).


2

C'è una buona serie di diapositive su Ruby blocchi come parte dei "binari con Passion" Certo:

Ruby_Blocks.pdf

Questo copre che rappresenta un blocco, il modo in cui ottenere gli argomenti passati e giustiziati, e ancora di più in cose come oggetti Proc. È molto chiaramente spiegato.

Potrebbe quindi essere interessante osservare come i ragazzi di JRuby hanno gestito questi nel loro parsing su Java. Dai uno sguardo alla fonte allo codehaus.


3

Non ho ancora implementato nulla di ciò, quindi prendilo con un sacco di sale.

Ci sono due parti per una chiusura: l'ambiente dati e l'ambiente di codice. Come hai detto tu, probabilmente puoi passare un vuoto * per gestire i riferimenti ai dati. Probabilmente potresti usare setjmp e longjmp per implementare i salti di flusso di controllo non lineari richiesti dall'interruzione di Ruby.

Se si desidera la chiusura, è probabile che si stia programmando in una lingua che li supporti effettivamente. :-)

AGGIORNAMENTO: Cose interessanti stanno accadendo a Clang. Hanno prototipato una chiusura per C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html potrebbe rivelarsi una lettura interessante.