This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-31
Channels
- # beginners (153)
- # cider (30)
- # cljs-dev (8)
- # cljsrn (8)
- # clojure (105)
- # clojure-dev (6)
- # clojure-dusseldorf (5)
- # clojure-italy (6)
- # clojure-nl (3)
- # clojure-russia (34)
- # clojure-spec (23)
- # clojure-uk (54)
- # clojurescript (104)
- # core-matrix (3)
- # crypto (1)
- # cursive (17)
- # datomic (90)
- # duct (13)
- # editors (5)
- # emacs (1)
- # events (1)
- # figwheel-main (9)
- # fulcro (54)
- # hoplon (18)
- # hyperfiddle (2)
- # jobs-rus (1)
- # lein-figwheel (5)
- # leiningen (3)
- # luminus (52)
- # mount (6)
- # off-topic (22)
- # other-languages (3)
- # parinfer (7)
- # powderkeg (3)
- # re-frame (52)
- # reagent (58)
- # rum (4)
- # shadow-cljs (49)
- # spacemacs (12)
- # sql (13)
- # tools-deps (2)
- # yada (1)
@seancorfield it worked!
thank you so much!
Using clojure 1.10.0-alpha6 and added -init
to the robot class
You've piqued my interest so I may take a look at that at the weekend and write a robot too 🙂 @mrdalloca
I'm trying to make a macro that can "make" a reify call. assuming data
here is the correct syntax that should go in reify
, how do I make this into an actual macro call?
(defn make-reify [data]
`(reify
com.my.Class
[email protected]))
the output of this function is code that is a correctly formatted reify
call that i can then copy and paste into the repl and it works. But I can't seem to find the right incantation to make this work as a macro. Just changing the defn to a defmacro I get a IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:542)
sounds like the body of make-reify isn't a form, but a binding that has the value of the form at runtime?
Clojure 1.9.0
(ins)user=> (defmacro make-reify [data] `(reify [email protected]))
#'user/make-reify
(ins)user=> (make-reify (Object (toString [this] "hi")))
#object[user$eval150$reify__151 0x732f29af "hi"]
(ins)user=> (def body '(toString [this] "hi"))
#'user/body
(ins)user=> (make-reify body)
CompilerException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol, compiling:(NO_SOURCE_PATH:4:1)
@jjttjj that's the most likely way to get that error from that code, and the answer is that a macro can only use the data that is visible during compilation, it doesn't see run-time data unless called at runtime
and it isn't called at runtime unless you force clojure to compile (eg. eval)
and eval is a big heavy expensive tool that you usually don't want to use
Is it possible in deps.edn to specify global dependency exclusions like you can in lein?
Hi! I'd like to know how to create a multiline-string that does not implicitly get newlines. I tried the following:
"Hello
world"
=>
Hello
world
Hello\
world
=> RuntimeException
I would like something like
Hello \
World
=> Hello World
@slipset I don’t have any official sources for it right now - I’d advise doing a search on JIRA - but I believe the issue is performance. If you have keyword
check its inputs, you potentially slow things down a lot. The gradual integration of spec in Clojure code should eventually solve this, as you’ll be able to turn on checks when needed, and turn them off for production or performance-critical code.
Is it idiomatic/a good idea to return an eduction
, particularly in cases where it’s going to be used as a value and not for composition?
@slipset in my experience the real solution to keyword
creating unreadable objects is not to call keyword on freeform runtime input.
if the value is flowing through at runtime, a string should work just fine
If you’re not allowed to use clj-http
, what would you pick? I’m using it to poke and prod REST APIs.
only bummer is I seem to remember it doesn't support some proxy or cert configs
@tbaldridge do you use jackson directly too?
not really since cheshire adds enough value it's not worth going directly against the Java libs
Could someone please verify if this namespace organization strategy is idiomatic? I'm attempting to make my code a bit more structured with the use of protocols, while sill remaining relatively easy to consume.
- Single protocols.clj
namespace that defines all the major protocols in the project
- Various my-app.thing.impl-a
, my-app.thing.impl-b
namespaces that extend the above protocols
- "Cosmetic/aggregate" namespaces such as my-app.thing
that collect and expose the above implementations in a user-friendly way.
Am I on the right track here?
as long as protocols.clj is actually my-app.protocols, or some other multi segment thing, sure
@noisesmith cool, thank you. That is indeed how I've written it. There is a bit of duplication in my-app.thing
in which I have to "point to" all of the protocol definitions again, but I think it's a small price to pay. Protocols should be relatively stable I imagine.
right - both your top level ns and each implementation should be written in terms of the protocol
Also, if there are any good "structured Clojure" resources out there that anyone knows of I'd love to read through them. My very first Clojure app is really suffering from having zero protocols defined...very difficult to refactor.
the most common thing is to reuse the built in protocols (IFn, PersistentVector, PersistentCollection, PersistentHashMap) by using functions and vanilla data
(at that point it doesn't even look like you are using protocols)
@noisesmith that's something I'm already noticing...one of my protocols in this pet project is very similar to a Set, but is stateful. Another is very similar to a map (assoc/dissoc semantics) but again is a stateful map...I haven't figured out how to reconcile this yet...if I extend the PersistentHashSet
(or whatever the interface is called), how do I regain my stateful semantics?
no, it's an immutable data type
err, you could own a set, and change which one you own (this is what refs, atoms, agents, vars all do)
So basically if I'm modeling a stateful thing, then stick with stateful semantics? For example, the fact that I'm using a ref is an implementation detail that I'd like to remain hidden, because I have a different strategy for the same component that doesn't use refs.
mutating and non mutating "things" should have completely separate interfaces
at least on the update side.
But most many Clojure functions work fine with mutable Java interfaces (get, count, to name two) so you can code against the Java interfaces, which are mutable
@tbaldridge >mutating and non mutating "things" should have completely separate interfaces This makes sense. I think I fall into the trap of trying to make my protocols cover too many things. I'm not very familiar with classic Java interfaces, but it sounds like I need to explore them more.
Theory: The platonic ideal protocol/interface has one method
They're way too broad (the Java interfaces) but you can always stub out the ones you don't want, and clojure does this automatically for you
For example: a persistent hash map is a Java Map, just all the mutation stuff throws exceptions
But something to think about, if you have more than two or three methods in a protocol, you should probably split the protocol.
A good example of this is Clojure vs ClojureScript. Clojure tends to have a lot of methods in its interfaces, these are split out in CLJS
It seems that the process of splitting protocols is very iterative...this is partly why I think I'll enjoy having them all defined in one protocols.clj
namespace, in that I can tease them apart without being distracted by concrete implementations.
I've also discovered a cool way to discover interfaces at the REPL, e.g.:
(use 'clojure.reflect)
(:bases (reflect (type (ref {}))))
;; returns
#{clojure.lang.ARef java.lang.Comparable clojure.lang.IFn clojure.lang.IRef}
The thing I'm modeling is very "ref-like", in that it needs to be able to support coordinated concurrent updates, so IRef
looks very promising...
@tbaldridge do you tend to design your protocols all up front when you start a project, or do you tease them apart over the course of weeks/months while still writing implementations? How much can you hope to "get it right" in design?
They change over time, but the more you pull them apart the less you have to change them in the future.
For example, if I'm defining a collection I may have get-item
and set-item
, how much do those need to change in the future? They shouldn't much at all.
If the protocols are changing too much, the argument could be made that the abstraction is tied too closely to the implementation.
Abstraction is about providing a common interface to disparate "things". So I'd say make sure you have more than one "thing" if you are using a protocol. Abstraction over a single "thing" is just adding complexity
If you do have multiple things to abstract, then the abstraction is a unification of the common operations supported by all the implementations.
I find that sort of design (and though process) results in protocols that don't need to change often
@tbaldridge >Abstraction over a single "thing" is just adding complexity This seems to be the crux of my folly. I currently only have 2 protocols, and each has 5+ methods. I definitely have some teasing to do. I can definitely tell when things are complected whenever I use the word "and" in my comments. e.g. "This is a collective and stateful and associative thing that x y and z".
Hi everyone. Currently I'm in a project where I need to consume events from other systems and then transform then into a CSV report sometime in the future. I was just consuming every event, creating somekind of database "snapshot" of the data so that I'll be able to query DB in the future and extract some CSV file. Will this be a good fit for a rule engine like Clara-Rules or some other library?
I've never used a rules engine before, so I simply don't know of the implications (and the data I'll have to work is kinda big - we're talking about millions of rows)
something like apache derby can give a sql engine in process with data entirely in memory, and then if you need to it can switch to storing data on disk
i'm still having issues writing a beastly macro to make a reify call with extensive type hints in the parameters of the methods. Is there anything special about the type hints such as ^int
or ^java.lang.String
or can i just generate them as symbols?
to emit metadata from a macro you need to explicitly use with-meta
just putting a metadata on a symbol isn't sufficient for a macro to put metadata on the right thing
so in
(reify
my.class
(myMethod [^int x]))
the ^int x
is equal to adding {:tag 'int}
to the symbol x
?starting to think i might be better off emitting source as a string and eval'ing for this use case
user=> (binding [*print-meta* true] (prn ^:int []))
^{:int true} []
nil
he's trying to make a reify form with type hints from a macro
I mean, what are you trying to do that you are making a reify form with type hints in a macro
why aren't you making a function with a reify in it, or a deftype or whatever, and having a macro expand in to calling that?
i'm trying to wrap this java api which requires implementing a wrapper interface which has a bunch of method callbacks that you're supposed to implment. they provide an example stub implmentation. i basically want to get all the methods and parameters from that java file, and somehow end up with an implementation that results in calling a single function on a clojure map of the method's parameter names -> values
at the repl, use reflection to generate a scaffolding of a deftype or a defrecord, then c&p that in
ok cool, i have the reflection stuff working to get the data i need, just not sure exactly what to do with it
i would kinda prefer to not have to manually copy and paste anything and do it all programatically
if you want to do it right, then do it right, don't generate a string and call eval (which will fail anyway because eval works on datastructures not strings)
if you want to be really dynamic about it, maybe check out https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html
sorry, what do you mean by do it right here? are you saying since I'm generating source it's better to treat it as source and just spit it into a file somehow?
no, I just mean doing that is better than "starting to think i might be better off emitting source as a string and eval'ing for this use case"
for scaffolding a single thing, that likely will never change, so generating it once should be fine vs. re-generating it everytime you do macro expansion
for a very small minority of the methods it seems that the type hints are required as the method signatures are ambiguous otherwise
(for some context I'm basically trying to implement this https://github.com/jsab/ib-re-actor/blob/master/src/ib_re_actor/wrapper.clj#L111 but the thing it's wrapping has a lot of new changes and I'm trying to think about accomplishing the same thing without having to maintain ~250 lines of code going forward)
i think just a dev tool to "create wrapper file" would be good enough. thanks for the input!
does anyone know if there's a way to get a reference for the data encapsulated by the :or
API in a destructured map?
;; this doesn't work :(
(defn foo [& {:keys [a b]
:as m
:or {a 1 b 2 :as this}}]
(merge this m))
it seems like a lot of duplicated code to do something like
(defn foo [& {:keys [a b] :or {a 1 b 2} :as m}] (merge {:a a :b b} m))