2013-09-06 8 views
9

Imparando Haskell qualche tempo fa, mi sono innamorato della notazione pointfree e dell'applicativo di funzione parziale particolarmente conveniente - solo argomenti di fornitura che conosci. In Clojure, ho sempre partial. Penso che avere una sintassi speciale per i lettori parziali sia piacevole da avere.Sintassi concisa per parziale in Clojure

sguardo al codice di esempio:

; Notation with points: 
(map (+ 10 (* % 2)) [1 2 3]) 

; With partial: 
(map (comp (partial + 10) (partial * 2)) [1 2 3]) 

; Let #[] syntax means partial application in reader: 
(map (comp #[+ 10] #[* 2]) [1 2 3]) 

Questo è così bello! C'è qualcosa di simile? C'è la possibilità di definire macro del lettore personalizzato?

+0

* Notazione senza puntatore :) Notazione inutile ha un significato diverso – jozefg

+2

@demi: dovresti provare a modificare la tua domanda e renderla un po 'più obiettiva, e un po' meno su "bella" e "buona". Trovo interessante la tua domanda (dal momento che so poco su Clojure, ma so che manca di macro di lettura, che è il modo in cui qualcosa di simile sarebbe scritto in Common Lisp, ad esempio), ma è troppo supponente. Al momento sto scrivendo questo, ci sono già 2 voti per chiuderlo, quindi state attenti. – rsenna

+0

http://dev.clojure.org/jira/browse/CLJ-1760 – Mario

risposta

6

Un anonimo sintassi della funzione # (...) può essere utilizzato in modo simile a ciò che si sta cercando di fare:

user=> (map (comp (partial + 10) (partial * 2)) [1 2 3]) 
(12 14 16) 

è equivalente a:

user=> (map (comp #(+ 10 %) #(* 2 %)) [1 2 3]) 
(12 14 16) 

Una piccola piccola differenza è % che significa solo un argomento di funzione, in questo caso il primo e unico.

+2

La differenza non è così piccola se ci sono diversi argomenti. O se il loro numero cambia durante lo sviluppo. – fjarri

+2

questo è vero. quanto sopra è solo per illustrare le funzioni di un singolo argomento. "giocare" con il reale (applica ..% e), [qui] (http://fulldisclojure.blogspot.com/2009/12/how-to-write-clojure-reader-macro-part.html) è un pericoloso esempio di modifica del Clojure [codice], mentre [qui] (https://gist.github.com/liquidz/919875) è più delicato [macro]. – tolitius

+0

@tolitius Oh wow! Questo collegamento a Disclojure è ciò di cui ho bisogno. Sono molto orgoglioso che Sean abbia deciso di avere la stessa sintassi che ho proposto. – demi

5

Mi piace molto la tua idea per una notazione a funzione parziale usando il # # letterale. Sfortunatamente, Clojure non ci permette di migliorare direttamente la notazione #(), ma possiamo definirci una macro come #p per un'applicazione parziale.

Dato si dispone di una funzione di

(defn partial-wrap 
    [args] 
    (concat '(partial) args)) 

definito myapp.core. È possibile aggiungere la seguente voce nella data_readers.clj nella parte superiore del classpath:.

{p myapp.core/partial-wrap} 

(di solito uno dovrebbe utilizzare uno spazio dei nomi simbolo qualificato qui come a/p, dal momento che i simboli non qualificate sono riservati per Clojure simboli Tuttavia non qualificati funzionano , è necessario affidarsi a Clojure senza sovrascriverli in una versione futura).

Questo permette, infine, di fare quasi quello che hai chiesto:

(map (comp #p[+ 10] #p[* 2]) [1 2 3]) 
=> (12 14 16) 
+0

mentre ha un paio di svantaggi (senza "p" di namespace e "#p [" is "read stumbling"), è davvero interessante dimostrare l'uso di 'data_readers.clj'. – tolitius

+1

Sarebbe bello se ci fossero notazioni di stenografia sia per partial che per comp. Per esempio. # [] per comp come # [inc secondo vettore] e forse ~ [] per parziale, in modo che si possa fare # [~ [+ 10] ~ [* 2]]. Il mio codebase è pieno di partial-stealing. –

+0

la cosa principale con "migliorare" il lettore sarebbe non passare al lato oscuro con questi 'def compose [G [_]] (implicito G0: pieghevole [G]): Pieghevole [({tipo λ [α] = F [G [α]]}) # λ] ... ':) – tolitius

2

ho trovato un approccio di avere parziale in casi come nella mia interrogazione: (map #(+ 10 (* 2 %)) [1 2 3). Utilizza la macro ->>: (map #(->> % (* 2) (+ 10)) [1 2 3]. Macro simili sono ->, .. e doto applicabili in diverse situazioni.

Problemi correlati