Fork me on GitHub
#clojure-italy
<
2017-09-27
>
reborg08:09:25

Need coffee

nilrecurring18:09:56

Oggi abbiamo preso la nuova macchina per l’espresso in ufficio 😄

nilrecurring18:09:12

(Che essendo in Finlandia è una grande notizia)

nilrecurring18:09:25

Yep. Non è troppo male, penso sia meglio della moka, e fa una bella cremina

reborg18:09:50

anche a me non dispiacciono le cialde (ho sentito le Nespresso)

nilrecurring19:09:40

Le nespresso sono molto buone, e pensavo di prenderla per casa

nilrecurring19:09:51

Ma oggi abbiamo preso Nescafè

nilrecurring19:09:33

Ora, per smentire chiunque possa provare a rivendicare che il caffè sia il topic principale su clojure-italy, torno su clojure

nilrecurring19:09:01

È una settimana circa che scrivo codice per generare codice, e non si tratta di macro: https://github.com/f-f/gogolica

nilrecurring19:09:47

Sono al commit #50 e ancora non funziona nulla, e generare clojure senza macro ha un po’ di aspetti divertenti

nilrecurring19:09:36

(Senza macro perchè l’obiettivo è generare Clojure a partire da una specifica JSON, e dumpare su file, per poi committarlo, mentre il codice generato dalle macro è “invisibile”)

nilrecurring19:09:31

E.g. se voglio generare una variabile dinamica devo tenere una lista tipo (def ^:dynamic *bla*)

nilrecurring19:09:09

Ma questo è impossibile, perchè ^ è una reader macro, e viene interpretata durante il reading appunto

nilrecurring19:09:38

Quindi l’hack facile è avere una lista (def \^ :dynamic *bla*), poi una volta che tutto è una stringa avere uno (str/replace "\\^ :" "\\^:" s)

nilrecurring19:09:33

Quindi è divertente, e sono abbastanza vicino all’avere l’API per Cloud Storage funzionante

nilrecurring19:09:54

(dove “vicino” significa che riesco a fare auth e fare list su un bucket)

reborg20:09:12

non so se capisco bene... ma non potresti comporre tutto il codice che ti serve come quoted clojure? Tipo:

(defn gen [] `(do (def ^:dynamic *x* 1) (defn some [args] (identity args))))

nilrecurring20:09:23

È quello che faccio (vedi e.g. https://github.com/f-f/gogolica/blob/master/src/gogolica/core.clj#L29), ma apparentemente il ^:dynamic viene interpretato dal reader nella fase di reading del codice quotato

reborg20:09:36

a visto ora

nilrecurring20:09:41

A questo punto in realtà l’hack non mi piaceva proprio, e ho tirato fuori la parte di auth (con la dynamic var) in un altro namespace che importo dal codice generato

bronsa20:09:16

@nilrecurring non capisco cosa intendi

bronsa20:09:33

user=> (defmacro x [] `(def ^:dynamic *a*))
#'user/x
user=> (x)
#'user/*a*
user=> (:dynamic (meta #'*a*))
true

nilrecurring20:09:39

Ma la defmacro funziona finchè stiamo nello stesso environment

nilrecurring20:09:58

Qui il codice lo devo scrivere su file

bronsa20:09:04

ah, capisco

nilrecurring20:09:16

`(^:dynamic ~'a)
=> (a)

bronsa20:09:18

print-meta a true?

bronsa20:09:57

come scrivi il codice su file

bronsa20:09:22

user=> (binding [*print-meta* true] (prn `(~'^:dynamic a)))
(^{:dynamic true} a)
nil

nilrecurring20:09:31

Questa mi mancava 🙂

nilrecurring20:09:11

Non sto usando prn per il printing (dovrei?), ma dovrebbe funzionare lo stesso

bronsa20:09:02

str non rispetta *print-meta*

bronsa20:09:25

usa print-str al massimo

reborg20:09:45

(defn gen [] `(do (def *x* 1) (alter-meta! (var *x*) assoc :dynamic true)))

reborg20:09:52

cosa se usasse alter-meta?

bronsa20:09:24

non funzionerebbe

bronsa20:09:47

il compilatore setta la var come dinamica solo se il simbolo della var contiene la metadata :dynamic durante def

bronsa20:09:32

l'alternativa funzionante sarebbe (do (def *x* 1) (.setDynamic #'*x*))

bronsa20:09:52

ma perche` complicarsi la vita :)

reborg20:09:22

Ma vedo :dynamic true se estraggo i meta:

user=> (do (def user/*x* 1) (clojure.core/alter-meta! (var user/*x*) clojure.core/assoc :dynamic true))
Warning: user/*x* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic user/*x* or change the name. (NO_SOURCE_PATH:38)
{:line 38, :column 5, :file "NO_SOURCE_PATH", :name *x*, :ns #object[clojure.lang.Namespace 0x5d43661b "user"], :dynamic true}
user=> (meta #'*x*)
{:line 38, :column 5, :file "NO_SOURCE_PATH", :name *x*, :ns #object[clojure.lang.Namespace 0x5d43661b "user"], :dynamic true}

bronsa20:09:05

si` certo ma prova (binding [*x* 2])

bronsa20:09:37

se una var e` dynamic o no, dipende da una flag settata nell'oggetto var, non direttamente dal metadata

bronsa20:09:00

la proprieta` e` che, se la var e` dinamica, allora avra` per forza :dynamic come meta, ma non e` vero il contrario

bronsa20:09:39

in realta` non e` completamente vera nemmeno la prima

reborg20:09:42

ok, capito grazie. Ho visto anch'io il setDynamic sulla var ma non sapevo a che serviva

reborg20:09:36

direi che la migliore vista fin'ora e' la tua con print-meta a true mentre si printa il sorgente su file (anche per me gradita sorpresa :)