Clojurians
#clojure-italy
<
2017-07-07
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

mdallastella06:07:18

@reborg re-frame-http-fx si basa su https://github.com/JulianBirch/cljs-ajax, che supporta transit: `

mdallastella06:07:29

Cito:

There are four formats currently supported for communicating with the server: :transit, :json, :text and :raw. 

mdallastella06:07:07

e inoltre:

:format - specifies the format for the body of the request (Transit, JSON, etc.). Also sets the appropriate Content-Type header. Defaults to :transit if not provided.

helios06:07:27

'giorno :upside_down_parrot:

reborg06:07:53

@mdallastella vero. Sembra pero' una limitazione di re-frame-http-fx. Mi obbliga a mettere :response-format (ajax/json-response-format {:keywords? true}) se no non funziona. Ho provato con (ajax/transit-response-format) e smette di andare.

nilrecurring06:07:52

Sono dell’opinione che c’è molto margine di miglioramento per re-frame-http-fx

nilrecurring07:07:05

In particolare, IMO ha senso scriversi un wrapper per cljs-ajax (con reg-fx se ricordo bene) con il formato preciso della propria applicazione

mdallastella07:07:26

@reborg limitazione nel senso che con il default non funziona il transit?

mdallastella07:07:49

o perché devi esplicitare?

reborg07:07:06

Non funziona "null is not an object" o roba del genere

reborg07:07:58

@nilrecurring: infatti, ho guardato i sorgenti e sono 20 righe, si puo' forse fissare in fretta

mdallastella08:07:40

Domanda: secondo voi può aver senso usare

meta
per stabilire l'ordine in cui dev'essere processata una map?

mdallastella08:07:21

Mi spiego: se non erro sorted-map ordina per alfabetico, sorted-map-by ordina per una funzione

mdallastella08:07:40

Passo indietro, io ho una mappa {:a 1 :stuck_out_tongue: 2 :c 3} ma quando vado a processarla, devo per forza processare prima :c, poi :a e infine :stuck_out_tongue:

mdallastella08:07:56

(maledette emoticons)

mdallastella08:07:17

pensavo a: `(with-meta

bronsa08:07:47

solutamente si usa una normale map per la parte associativa + un vector di chiavi per l'ordine

bronsa08:07:56

ordered astrae ^

bronsa08:07:16

assunto che insertion order ti vada bene

mdallastella08:07:51

pensavo a

(with-meta {:a 1 :b 2 :c 3} {:order [:c :a :b]})

mdallastella08:07:23

e poi quando la processo estraggo :order e tiro fuori le chiavi in quell'ordine

bronsa08:07:54

e` terribilmente facile perdere metadata per strada

bronsa08:07:57

sconsiglio

mdallastella08:07:56

oki, perché ora uso una finta mappa

[[:c 3][:a 1][:b 2]]

bronsa08:07:15

perche` non ha le performance guarantees di una mappa e non e` accessibile tramite le funzioni associative

bronsa08:07:26

ma se non ti interessa ^ allora chiaramente non hai bisogno di usare una mappa

mdallastella08:07:13

sono dati che devo scrivere in un socket in un certo ordine, volevo fossero un po' verbosi a codice (oltre ai commenti)

mdallastella08:07:37

Cmq vedo di fare un gist per farvi capire meglio il contesto

reborg08:07:04

forse puoi fare qualcosa con array-map, sempre in relazione al contesto

bronsa08:07:42

trovo usare array-map per preservare ordine veramente pericoloso

reborg08:07:21

beh opinabile

bronsa08:07:35

sei un dissoc/assoc away dal perderlo

reborg08:07:01

non fare assoc dissoc :slightly_smiling_face:

reborg08:07:41

lo uso estensivamente nell'app principale qui... ovviamente sappiamo quel che facciamo

bronsa08:07:54

pistola carica e puntata, non spararti sui piedi. facile a dirsi, prima o dopo succede

bronsa08:07:29

senza contare che array-map e` lineare in lookup

bronsa08:07:16

quindi dopo un certo numero di elementi, non vedo veramente perche` vorrei usare array-map invece di una a-list manuale o una tupla di map+order vector

reborg08:07:10

scrivere dati "documentati" in un socket, a naso, sembra un buon caso. Mi immagino una volta costruita l'array-map (forse adirittura esplicitando le chiavi una ad una se non sono piu' di qualche decina) la mandi giu' al socket.

mdallastella08:07:49

Do un'occhiata ad array-map, grazie

mdallastella08:07:35

In ogni caso vi faccio un gist

mdallastella09:07:00

Il primo è con il metodo che uso attualmente per scrivere su un socket, il secondo è quello che avevo in mente per pulire un po' il codice usando i metadati

mdallastella09:07:28

Sono eseguibili da repl

mdallastella09:07:23

Quello che vedete ora è una summa di funzioni sparse per 4 namespace diversi, eh

reborg09:07:57

se per i dati usi (array-map :id 1 :first-name "Marco" :last-name "Dalla Stella" :age 35) dovrebbe funzionare senza altre modifiche

mdallastella09:07:24

Provo una versione con array-map e vedo com'è

mdallastella09:07:23

Tecniche a parte, fa schifo il codice?

bronsa10:07:15

(defn encode
  [spec message] 
  (let [out (ByteArrayOutputStream.)
        stream (DataOutputStream. out)]
    (doseq [[field-name value] message
            :let [function (get spec field-name)]]
      (try
        (apply function [stream value])
        (catch Exception e 
          (throw (Exception. (str (.getMessage e) " writing " field-name))))))
    (seq (.toByteArray out))))

bronsa10:07:51

e preferisco molte volte la versione con explicit ordering che qualsiasi altra soluzione basata su metadata o implicit ordering via array-map

reborg10:07:15

Se elimini il dispatch esplicito via "spec" map ed usi protocols, diventa conciso:

(defprotocol Encode
  (serialize [v out]))

(extend-protocol Encode
  java.lang.Long
  (serialize [v out]
    (.writeInt out v))
  java.lang.String
  (serialize [v out]
    (let [b (.getBytes v)
          l (long (count v))]
      (serialize l out)
      (.write out b 0 l))))

(defn encode
  [message]
  (let [out (ByteArrayOutputStream.)
        stream (DataOutputStream. out)]
    (doseq [[field-name value] message]
      (serialize value stream))
    (seq (.toByteArray out))))

mdallastella10:07:15

Interessanti soluzioni, grazie mille!

elenacanovi12:07:33

Ciao! scusate la domanda stupida, ma sapete consigliarmi una libreria per fare in modo che il codice clojure si ricompili automaticamente? ho provato con lein-auto (lein auto run) ma non ricompila. grazie!

bronsa12:07:47

usi emacs?

bronsa12:07:08

e per ricompilare, cosa intendi esattamente? un re-eval nella REPL o produrre un jar?

elenacanovi12:07:32

intendo un jar

bronsa12:07:30

provato con lein auto jar ?

bronsa12:07:35

(o uberjar, dipende da quale vuoi)

elenacanovi12:07:07

non avevo provato, provo adesso. se volessi qualcosa tipo “lein auto run”, cioè fare anche rieseguire il codice, si può?

bronsa12:07:29

rieseguire dove? nella repl?

bronsa12:07:53

non saprei con lein auto, ma con emacs dovrebbe essere relativamente semplice scrivendo 3 righe di elisp

bronsa12:07:01

facendo un hook on file save

bronsa12:07:47

non conosco soluzioni pre-pronte che lo fanno

elenacanovi12:07:41

ok grazie comunque

bronsa12:07:27

qualcosa del genere (add-hook 'after-save-hook (lambda () (cider-load-buffer))) (non testato)

skuro12:07:28

o magari cider-refresh?

skuro12:07:34

dipende da quello che serve

elenacanovi12:07:33

in pratica io ho un server http-kit. vorrei che quando cambio il codice, quello si ricompilasse e si riavviasse il server. non so se si può fare

bronsa12:07:09

in quel caso cider-refresh come dice @skuro

mdallastella15:07:59

@elenacanovi non voglio mettere naso nel codice, ma potrebbe tornarti utile o components (https://github.com/stuartsierra/component) o mount (https://github.com/tolitius/mount)

mdallastella15:07:21

Noi ad esempio usiamo mount, che "capisce" quando il namespace di un "servizio" viene cambiato e lo "riavvia"

elenacanovi15:07:56

grazie li guardo!