Mi piacerebbe eseguire una sessione su Clojure. Potresti consigliare un problema che può essere risolto elegantemente usando la programmazione funzionale con Clojure? Puoi indicare le risorse che coprono questo argomento?Che cos'è una buona vetrina per Clojure?
risposta
un sacco di argomenti per l'utilizzo di Clojure sembra essere correlato alla sua gestione della concorrenza, ma non voglio toccare questo tema qui.
Elencherò alcuni problemi che sono costretto ad affrontare settimana dopo settimana con Java e come li ho o li risolverei in Clojure.
Immutabilità
In Java raggiungimento immutabilità è molto molto difficile. Oltre a seguire rigorose pratiche di codifica, dovrai scegliere con cura i tuoi quadri e le tue librerie. Inoltre, come effetto collaterale scriverai molto codice per creare un'API pulita e utilizzabile, o semplicemente costringerai il cliente a gestirlo.
final Person person = personDao.getById(id);
// I would like to "change" the person's email, but no setters... :(
In Clojure si modella i dati sulla base di strutture di dati immutabili così tutti gli oggetti sono immutabili per difetto e per questo Clojure offre potenti funzioni che operano su queste strutture.
(let [person (get-by-id person-dao id)
person-with-email (assoc person :email email)]
; Use person-with-email...
Conversioni
In Java di avere una classe di dominio Person
con campi id
, name
, email
, socialSecurityNumber
e altri. Stai creando un servizio web per recuperare i nomi e le email di tutte le persone nel tuo database. Non si desidera esporre il dominio in modo da creare una classe PersonDto
contenente name
e email
. È stato facile, quindi ora hai bisogno di una funzione per mappare i dati da Person
a PersonDto
. Probabilmente qualcosa di simile:
public class PersonPopulator {
public PersonDto toPersonDto(Person person) {
return new PersonDto(person.getName(), person.getEmail());
}
public List<PersonDto> toPersonDtos(List<Person> persons) {
List<PersonDto> personDtos = new ArrayList<PersonDto>();
for (Person person : persons) {
personDtos.add(toPersonDto(person));
}
return personDtos;
}
}
Ok bene che non era così male, ma se si vuole mettere più dati in DTO? Bene il codice costruttore in toPersonDto
crescerà un po ', senza preoccupazioni. Cosa succede se ci sono due diversi casi d'uso, uno come sopra e un altro dove vogliamo inviare solo le e-mail? Bene potremmo lasciare il name
null (cattiva idea) o creare un nuovo DTO, forse PersonWithEmailDto
. Quindi dovremmo creare una nuova classe, alcuni nuovi metodi per popolare i dati ... probabilmente vedi dove sta andando?
Clojure, un linguaggio tipizzato in modo dinamico con strutture di dati immutabili, mi permette di fare questo:
(defn person-with-fields [person & fields]
(reduce #(assoc %1 %2 (get person %2)) {} fields))
(person-with-fields {:id 1
:name "John Doe"
:email "[email protected]"
:ssn "1234567890"} :name :email)
; -> {:email "[email protected]", :name "John Doe"}
E per manipolare una lista di persone:
(map #(person-with-fields % :name :email) persons)
anche l'aggiunta di dati ad hoc per un sarebbe facile:
(assoc person :tweets tweets)
E questo non spezzerebbe nulla. In Java, se i tuoi oggetti sono immutabili, probabilmente non hanno setter, quindi dovresti scrivere un bel po 'di codice per modificare un campo (new Person(oldPerson.getName(), oldPerson.getEmail(), tweets
), o creare una classe completamente nuova. Gli oggetti mutabili offrono una bella API (oldPerson.setTweets(tweets)
), ma sono difficili da testare e capire.
Testing
Un sacco di codice Java si basa su un certo stato, anche quando non v'è alcun bisogno di esso. Ciò significa che è possibile prendere in giro questo stato, il che di solito significa ulteriore standard di stampa e diventa più difficile se non si è creato il codice tenendo a mente la testabilità. D'altro canto, i test senza mock sono solitamente lenti e dipendono dall'accesso o dall'ora del database o da qualcos'altro che di sicuro verrà a mancare su di voi di volta in volta.
Mentre la codifica Clojure ho notato che non ho veramente bisogno dello stato più di tanto. Praticamente le uniche situazioni sono quando sto recuperando qualcosa dal "fuori", sia esso un database o qualche servizio web.
Sommario
mio codice è un tubo, da un'estremità ottengo alcuni dati, questi dati vengono poi cambiato nel tubo tramite filtraggio, trasformandolo o unirsi con altri dati fino alla fine la pipa. All'interno del tubo non è necessario modificare realmente i dati, ma in molti casi sono utili funzioni potenti e strutture di dati immutabili e questo è il motivo per cui Clojure fa miracoli con codice come questo.
Wow, ottimo esempio. – defhlt
Mi è piaciuto il riassunto. Questo è esattamente come mi sentivo mentre lavoravo con Clojure per tre mesi. –
Il classico problema della concorrenza "The Sleeping Barber" potrebbe essere buono.
Ecco un paio di esempi
http://www.bestinclass.dk/index.clj/2009/09/scala-vs-clojure-round-2-concurrency.html
https://github.com/bitsai/clojure-actors/blob/master/sleeping_barber.clj
Un paio di mesi fa, mi imbatto nello stesso problema e abbiamo deciso di risolvere il problema 'la Gioconda' in Clojure. Il risultato è stato this presentation. Fondamentalmente abbiamo dimostrato che Clojure è estremamente interessante per risolvere problemi per i quali "codice come dati" offre una soluzione elegante. Ad esempio negli algoritmi genetici.
- 1. vetrina per app pubblicata shinyapps.io
- 2. È buona norma per un record Clojure implementare IFn?
- 3. Componenti Android vetrina/guida visiva
- 4. Che cos'è una buona funzione hash?
- 5. Che cosa è una buona alternativa per openinviter in Django
- 6. Come scaricare la vetrina di PrimeFaces?
- 7. Agenti Clojure che consumano da una coda
- 8. Che cos'è una buona macchina virtuale per lo sviluppo di una lingua per hobby?
- 9. Una buona fonte per le librerie Lisp?
- 10. Una buona pratica/progetto per programmatore PHP
- 11. È una buona ragione per usare alloca?
- 12. C'è una buona libreria yaml per Android?
- 13. Una buona API per le citazioni famose
- 14. Una buona risorsa per l'apprendimento di HTML5
- 15. Che cos'è Clojure volatile?
- 16. Che cos'è una buona implementazione del parser RDFa di Javascript?
- 17. definisce un sinonimo per una macro Clojure
- 18. REST Web Services che utilizzano MVC, è una buona idea?
- 19. Che cos'è una buona raccolta di dati per rappresentare una corsa di cavalli?
- 20. Che cos'è una buona libreria di ottimizzazione convessa?
- 21. Che cos'è una buona struttura di progetto in C
- 22. Esiste una libreria AES per clojure?
- 23. Una buona soluzione blobstore/memcache
- 24. Campi multivalore una buona idea?
- 25. Esiste una libreria .net che ha una classe Vector immutabile persistente (come trovata in Clojure/Scala)?
- 26. smartGWT è davvero lento come la sua vetrina?
- 27. Che cos'è il Clojure idiomatico per "rimuovere" una singola istanza da molti in una lista?
- 28. L'istanza è una buona pratica?
- 29. Marmalade Mobile App Development - La marmellata è una buona scelta?
- 30. Che cos'è una buona libreria JavaScript o un plugin jQuery per gesti tattili?
Che tipo di sessione? Stai cercando un problema e una soluzione che possa essere spiegata in un'ora, un giorno, una settimana? Ci sono molte possibilità. –
Abbiamo un evento vetrina regolare in tutta la società per mostrare nuove tecnologie. È inteso come 2 ore di mani in sessione. – spa