Rifiniture Rebol contro dialetti contro oggetti

4

A volte mi sento in conflitto quando uso un linguaggio che non è Rebol (di tanto in tanto accade) e mi viene in mente, hm-la vita sarebbe più facile in Rebol se questa cosa funzionasse in questo modo?

Per illustrare la mia istanza corrente, in Rebol si invia un messaggio come segue:

send [email protected] "A Message"

È sempre stato uno dei killer one-liner, molto conciso, elegante. Utilizzando i perfezionamenti, puoi iniziare a creare un messaggio più complesso:

send/subject/attach [email protected] "Hi Foo!" "A Message" %me.jpg

Ancora relativamente conciso, ma cominciando a riempire un po '. Mentre scolpisci il tuo messaggio, inizia a diventare un po 'disordinato:

send/subject/attach/header
    [[email protected] [email protected]]
    "Hi Folks! – Chris"
    "A Message"
    make object! [X-User-Agent: join "Rebol " system/version]

Questo è l'attuale modo prescritto per inviare un messaggio di posta elettronica (i feed di riga sono facoltativi qui, ma diventano essenziali non appena i componenti iniziano a essere aggiunti).

Rebol non è niente se non è versatile, possiamo sognare un approccio alternativo usando i dialetti :

send [
    ; no delimiters required, we can discern recipients
    ; by the use of the email! datatype:
    [email protected] [email protected]

    ; two string! values indicate the first as the subject
    ; second as the message
    "A Message"
    "Hi Folks!"

    ; a few attachments courtesy of the file! datatype
    %me.jpg %you.jpg %the-world.jpg

    ; and then some set-word!/value headers
    X-User-Agent: "Rebol"
]

Commenti sans:

send [
    [email protected] [email protected]
    "A Message"
    "Hi Folks!"
    %me.jpg %you.jpg %the-world.jpg
    X-User-Agent: "Rebol"
]

Abbastanza spinto, ma i dialetti diventano un po 'complicati quando si iniziano a inserire argomenti condizionali, dati esterni, ulteriore personalizzazione. Possiamo costruirlo in qualche modo proceduralmente:

send collect [
    keep [email protected]
    if "Monday" = pick system/locale/days now/weekday [
        keep [email protected]
    ]
    keep subject ; 'subject defined elsewhere
    keep {A Long Message}
    keep read %photos/
    keep compose [X-User-Agent: (join "Rebol " system/version)]
]

Sembra ragionevole, tranne che perdiamo un po 'di espressività in quanto i metadati impliciti offerti dai tipi di dati sono oscurati dal codice aggiuntivo. Anche solo l'aggiunta di parole non del nostro dominio corrente ( collect , keep ).

Il che mi porta al mondo basato su oggetti (che sembra coprire il modo in cui le lingue popolari là fuori si avvicinano alle cose). In questo linguaggio X composito, inesistente, recuperiamo parte dell'espressività attraverso l'uso esplicito delle azioni nominate:

message = mailer.new

// pity poor language X, only one string type:
message.addRecipient '[email protected]'
if (today = 'Monday') { // assumed 'today value 
    message.addRecipient '[email protected]'
}

message.subject = "A Message"
message.body = "Hi Folks!"
message.attach filesystem.read 'photos/'
message.header['X-User-Agent'] = 'Language X'

message.send

// Rebol's SEND function needs a return value with some
// status feedback. For another day...
if (message.isSentOk) {
    print "Hooray!"
}

La bellezza è negli occhi di chi guarda: questo approccio non ti lascia dubbi su quale sia la linea, ma contemporaneamente (ai miei occhi) appare pesante. Arriviamo a destinazione proceduralmente, send accade dopo aver stabilito i dettagli del messaggio. Nei miei momenti di dubbio, mi chiedo se avere send [...] dichiari l'intento prima di essere pronto.

Potresti facilmente trasferire l'approccio della lingua X a Rebol, o far sì che informi l'approccio adottato da un dialetto:

mailer [
    new message
    add recipient [email protected]
    if today = "Monday" [
        add recipient [email protected]
    ]
    subject: "A Message"
    body: "Hi Folks!"
    attach read %photos/
    send
    probe status
]

La mia domanda è: L'approccio al linguaggio X ha un approccio / influenza su qualcosa da desiderare, oppure l'uno o l'altro approccio di Rebol conserva abbastanza espressività man mano che aumenta la complessità?

PS: non solo posta-penso a questo riguardo al tag <canvas> e all'idea di un formato grafico procedurale rispetto all'esplicita <svg> .

    
posta rgchris 22.09.2015 - 06:43
fonte

2 risposte

1

L'approccio / influenza degli oggetti X della lingua rende esplicito il contesto dell'istruzione per ciascuna istruzione. I dialetti possono rendere implicito quel contesto, non dovendo fare ripetutamente riferimento al "messaggio" come nell'esempio della lingua "X". Nel mondo degli oggetti, le "interfacce fluenti" (annotate da Robert nel suo commento) sono diventate popolari per ottenere un risultato simile.

Un dialetto Rebol può essere arbitrariamente potente, quindi non vedo che l'approccio all'oggetto linguaggio X è uno da desiderare. Tuttavia, l'approccio ad oggetti dovrebbe essere usato come parametro di riferimento: "il mio dialetto è un valore aggiunto rispetto a un'interfaccia di un oggetto semplice?", "Il mio dialetto esprime l'intento in modo più chiaro e semplice?", "Il vantaggio del dialetto supera l'implementazione? costo?". Se il dialetto non aggiunge valore è davvero necessario, oppure esiste uno scopo migliore per un dialetto?

La parte difficile dei dialetti e delle interfacce fluenti è la progettazione dell'interfaccia / grammatica. Gli obiettivi sono come capire quali espressioni sono utili al codice cliente, fornendo sufficiente flessibilità, robustezza di fronte ai cambiamenti futuri e mantenere "una sufficiente espressività man mano che aumenta la complessità" non sembra facile.

I tipi di valori dei simboli sono facili da riconoscere per un interprete dialettale, il tipo diventa un'espressione a valore singolo - imposta questa variabile con questo valore, come hai mostrato nel tuo dialetto dichiarativo. L'utilizzo dei tipi di valore in questo modo consiste nell'utilizzare le scorciatoie (zucchero sintetico) per alcune espressioni. Con l'aumentare della complessità, penso che gli approcci che hai mostrato possano avere un problema perché stanno mescolando contesti concettuali. Ad esempio, concettualmente, gli indirizzi email dei destinatari verranno utilizzati per due concetti: SMTP e RFC822. I riferimenti al file sono scorciatoie per le espressioni MIME. Se il dialetto continua a mescolare più contesti concettuali all'interno delle sue parole chiave / valori, forse diventerà eccessivamente complesso perdendo espressività man mano che le espressioni più complesse vengono provate. Forse una strada da percorrere è pensare a come i dialetti provenienti dai diversi contesti concettuali si integreranno in modo che l'espressività non venga persa con l'aumentare della complessità. Le scorciatoie possono essere mantenute, ma scavando in un dialetto specifico come necessario per le espressioni specifiche di quel concetto. Il dialetto potrebbe essere incorporato all'interno di un altro come un blocco introdotto dal suo nome rappresentato come una parola. Per inciso, un dialetto MIME potrebbe essere riutilizzato al di fuori delle e-mail, per scopi web.

Quindi suppongo che sto suggerendo un terzo approccio, e ammetto uno che non ho esplorato correttamente, in cui sono fornite scorciatoie per gli usi più semplici che hai fatto e per un controllo più preciso per un contesto specifico chiama un nome dialetto incorporato.

    
risposta data 22.09.2015 - 16:47
fonte
2

In c #, è

Send("foobar@baz","A Message");

o

Send("foobar@baz, [email protected]", "Hi, folks","A Message", "me.jpg");

Non c'è bisogno di disambiguare i nomi dei metodi, grazie a un sovraccarico.

Con i parametri con nome, diventa

Send(addresses = "foobar@baz, [email protected]", 
    title = "Hi, folks", 
    message = "A Message", 
    attachment = "me.jpg");

Qualsiasi o tutti possono essere facoltativi.

La variazione del "messaggio" ha questo aspetto. Può sembrare pesante, ma ogni bit di codice significa qualcosa:

message = mailer.NewMessage();

message.addRecipient("[email protected]");

if (DateTime.Now.DayOfWeek = DayOfWeek.Monday) { 
    message.AddRecipient("[email protected]");
}

message.Subject = "A Message";
message.Body = "Hi Folks!";
message.Attach("photos"); // Folder within 'Current" folder
message.Header.Add("X-User-Agent", "Language X"); 

message.Send();

Con gli inizializzatori di oggetti, assomiglia a questo. Si noti che è possibile utilizzare un metodo factory per la creazione dell'oggetto iniziale e sfruttare ancora questa sintassi:

message = mailer.NewMessage()
{
    addresses = "foobar@baz, [email protected]", 
    title = "Hi, folks", 
    message = "A Message", 
    attachment = "me.jpg"
};
    
risposta data 22.09.2015 - 17:29
fonte

Leggi altre domande sui tag