This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-10
Channels
- # aleph (1)
- # aws-lambda (1)
- # beginners (80)
- # boot (20)
- # cider (75)
- # cljs-dev (45)
- # cljsjs (1)
- # cljsrn (11)
- # clojure (428)
- # clojure-dusseldorf (13)
- # clojure-italy (4)
- # clojure-russia (153)
- # clojure-spec (47)
- # clojure-taiwan (1)
- # clojure-uk (62)
- # clojurescript (84)
- # cursive (19)
- # datascript (96)
- # datomic (75)
- # dirac (9)
- # docs (3)
- # emacs (19)
- # jobs (5)
- # jobs-discuss (20)
- # jobs-rus (17)
- # lein-figwheel (5)
- # leiningen (1)
- # liberator (4)
- # luminus (12)
- # off-topic (4)
- # om (31)
- # onyx (102)
- # pamela (1)
- # parinfer (3)
- # pedestal (3)
- # proton (1)
- # protorepl (14)
- # re-frame (54)
- # reagent (22)
- # rum (40)
- # spacemacs (2)
- # specter (8)
- # test-check (5)
- # unrepl (110)
- # untangled (80)
- # vim (3)
- # yada (46)
Hi! Are [org.clojure/tools.analyzer.jvm "0.7.0"] and [org.clojure/clojure "1.9.0-alpha14"] compatibles ? When i add jvm analyzer dep i have a cast exception clojure.lang.Keyword cannot be cast to java.util.Map$Entry at clojure.core$imap_cons.invokeStatic (core_deftype.clj:143) clojure.core$imap_cons.invoke (core_deftype.clj:132) clojure.lang.Var.invoke (Var.java:383) logic.check.Rec.cons (check.clj:130) clojure.lang.RT.conj (RT.java:667) maybe its lein?
I was extending List and Map$Entry, guess extend-type is non-deterministic with interfaces.
(extend-type java.util.List
IMap
(-map [ a ]
(map -map a)))
(extend-type java.util.Map$Entry
IMap
(-map [ a ]
[(-map (first a))
(-map (second a))]))
This is documented at https://clojure.org/reference/protocols
If there are multiple extensions and one derived from the other, the derived is picked
If they are unrelated then it's undefined
And in practice either can happen
I missed that part of the docs, thanks @alexmiller.
@paulocuneo and in practice I've even seen it change at runtime as in one call will go one place, another another place. I think whenever something new is registered it can move things around
so yeah, best practice: stick with extending once per "level"
Multimethods have the ability to define preferences
So that's another option
@tbaldridge i guess as concrete as posible, for now i added MapEntry.
(extend-type clojure.lang.MapEntry
IMap
(-map [o ]
[(-map (first o)) (-map (second o))]))
Many thanks!!
What does the “dup” in *print-dup*
stand for?
oh, as in “I want this exact value to be duplicated when it’s read back in”?
when you perform java reflection to get the parameters of a method and ask the parameters for their types, if it is a object type it will give you the fully qualified class name like java.lang.String
. I need this as a string though, so I use clojure's str
on it, but when I do I get "class java.lang.String"
for example. Is the "class" part of the name? In other words, if i were to use with-meta to specify a :tag
for type-hinting purposes, would it be confused at the "class" part? If it would be confused, why did the "class" part get tacked onto the front in the first place?
@bcbradley Just use .getName
instead of str
If i use get name on an array type i get java.lang.String[]
rather than [Ljava.lang.String
under the section titled aliases https://clojure.org/reference/java_interop
hi all , anyone have an example how to use sente (https://github.com/ptaoussanis/sente) with json instead of transit ,
if you have so many futures it is slowing down your code, and you are sure you need the futures (or some other abstraction) in your code because it allows you to separate what happens from when it happens, you won't be able to find any other abstraction that gives you that separation at a lower cost except callbacks
but chaining callbacks leads to callback hell, and the difference between futures and callbacks in terms of cost is so negligible it would be hard to imagine any case in which callbacks would be measurably faster than futures
when you make a future, you are saying that it will eventually have a value, and its up to someone else somewhere to provide it
when you make a promise you are saying that you will produce a value, but its up to someone else some where to refer to it
the concept of running it in parallel with other stuff isn't mentioned because it isn't part of the abstraction
so if i need a future to (Thread/sleep 100) and then do something, what is the probability that Thread/sleep itself won’t be invoked for some significant time before the future is scheduled?
i wouldn't rely on probabilities, but with the exception of some edge cases its likely that it would be roughly 100 ms
i’m just wondering if it could happen that if i never deref a future and just discard it - it won’t be scheduled
i'm talking about memory footprint which is what people usually talk about when comparing green/real threads
because of the way clojure is structured around values and immutability, its more likely that the caching behavior of futures can actually be used
if you can't get good use out of the caching aspect of futures, it might be wiser to reorganize your program around agents
@bcbradley future used the agent threadpool internally 🙂
honestly i just use a lot of promises in my code, arrays of promises, seqs of promises
i really don't see how any of that is relevant TBH. futures are not lightweight and spawning too many futures can definitely negatively impact memory footprint/performance as they run in an unbound threadpool
Manifold can help, especially when dealing with blocking calls, or 'send-off' when using agents.
i misunderstood because i was thinking about how I use them not how he might potentially be using them
a data structure that stores data occupies the data it takes up forever (until you remove it)
hi, using this lib https://github.com/nberger/ring-logger how can I make log to file?
i find myself wrapping a lot of stuff in (go) blocks when i do core.async, like every time i have anonymous function that does send or receive - am i doing this wrong?
like it is said in the lib's docs (jetty/run-jetty (logger/wrap-with-logger my-ring-app) {:port 8080})
@tomaas: ring-logger supports different "logging backends". By default it comes with clojure.tools.logging, which in turn is an interface that delegates to a specific logging backend, knowing how to talk to the most common used java logging libraries (slf4j, commons.logging, log4j and others), so you have to use & configure one of those and tell them to log to a file
There is also clj-logging-config that can help you in configuring those logging backends. And then you could even use ptaoussanis/timbre, a "Pure Clojure/Script logging library" for which there is ring-logger-timbre. But still then you'll have to configure it to log to a file.
@nberger Once stdout logging is in place, shouldn't redirecting it to file just work?
@tomaas: what happens when you run your jar with the redirection? Do you still see messages in the console that you'd like to be sent to the file, or are the log messages being sent to a different file?
@keymone It can be fine as long as you understand when you want to wait on things or apply backpressure in your system instead of blindly grow an unbounded task queue.
has anyone written a case-insensitive map? not just down-casing, I’d like to preserve the capitalization of the keys
@nberger, exactly, I still see the messages of ring-logger in the console and they do not get written to file. However the (prn "...")
in clojure code are written in that file
yonatanel: so say i have (go (do-stuff))
<- i can run >!
and <!
in do-stuff
, but if i do (go (do-stuff #(>! channel)))
- this is not allowed. is it a normal pattern to just wrap anonymous call in a go
like so: #(go (>! …))
?
@tomaas ok, then the issue is that logging is being sent to stderr. Try with java -jar app.jar 2> file.txt
to send only the err output to the file or java -jar app.jar > file.txt 2>&1
to send both to the file
@keymone Maybe all you want is put!
: https://clojure.github.io/core.async/#clojure.core.async/put!
when calling use
from the repl on a given namspace, should i then have access to any namespaces required by that namespace?
for example, gen
can't be resolved when i call (use 'ms.specs)
on the ns (ns ms.specs (:require [clojure.spec :as s] [clojure.spec.gen :as gen]))
@yonatanel i don’t understand the difference between put! and >!
@joshkh No. in the ms.specs
namespace, require
only aliases clojure.spec.gen
as gen
for that namespace only. use
-ing that namespace from another namespace doesn't alias it in the namespace you use it from.
okay thanks! the evidence was pretty clear, i just wanted to make sure i wasn't missing something 🙂 is there a convenient way to pull in the aliases?
https://clojuredocs.org/clojure.core/require should make that more clear than I could 🙂
given a function g, is there a short hand for (fn [x y] (g y x)) ? basically swap the arguments before passing them to g; g is guaranteed to take precisely 2 inputs
@qqq the question pops up every so often. @shdzzl s solution is good, a macro involving reverse on the args is also possible.
@seancorfield tends to say that they have this implemented at his company.
And, @alexmiller is normally not interested in adding such a function to core ;)
Yep, no flip
in clojure's standard library that I'm aware of, but if you need a more general solution:
(defn flip [f]
(fn [& args]
(apply f (reverse args))))
@qqq @shdzzl @slipset : yeah, I guess I was epecting there be a "functional level appraoch" where it's (a->(b->c)) -> (b->(a->c))
@slipset Rich has vetoed this in the past
he feels it is not clojure style
I guess without type checking, flip / point-free programming becomes relaly hard to debug
in the vast majority of cases, I agree
in Clojure that is, not talking about Haskell or other langs
maybe I'm doing thing swrong, but often in my code for (map f lst), the "lst" is simple, and the "f" is a complicated (fn [] ... ) that is multipline
if your map fn is complicated, maybe make it a defn, not an anonymous function
or use for
you can make as many functions as you want :)
Generally I tend to write functions that operate on one thing, then map/filter/etc in a separate function
Look for redundant map https://stuartsierra.com/tag/dos-and-donts
Clojure has good namespacing, naming single-use functions is OK most of the time. A lot of Clojure's function manipulation happens at application rather than definition, is another takeaway here. More so than in Haskell at least. Threading macros are amazing.
How do I test assertions in macros? I have a macro that is supposed to fail under certain conditions, and I want to write a test that passes if it does fail.
@kauko (is (thrown? c body)) checks that an instance of c is thrown from body, fails if not; then returns the thing thrown.
(is (thrown? AssertionError (macroexpand-1 '(failing-macro))))
runs, but the test fails as that returns nil. When I run the expansion in my repl, I do get the assertion error
It made complete sense in the end. I guess I was just so used to thinking of macroexpand
as something you call from the repl, it didn't occur to me I should use it here
@kauko the general advice about macros is this: Do practically nothing inside the macro itself. Instead have the macro dispatch to a defn
where all the actual work is performed. Now you can test the assertions in the defn
like any other function
See the source of clojure.spec
for this. Tons of macros, each is paired with a foo-impl
defn
also easier to debug in the repl that way
I'm actually just learning about macros, I've been working with clojure for 2 years now but never really written any
@tbaldridge I was wondering about the -impl
stuff, thought it was because of private vars
I've found that I barely ever need macros unless I'm making a library or something. You can get really far without having to write a macro!
The only times I have ever used macros, it was to move quoting out of user space. I don't think I've ever written a macro that was longer than a single line.
like if i wanted to construct an object of that type in clojure using interop would i say (org.lwjgl.system.Configuration<java.lang.String>. param1 param2 param3)
(or whatever in place of java.lang.String)?
@keymone put!
doesn't have to be inside a go block, and it doesn't block. Seems like it's simpler and you can just use that to pass values around until you figure out your backpressure policy
@bcbradley have you looked at libgdx? I've never used it from clojure but it's a pleasant wrapper around lwjgl, among other things. Might be overkill for your use case though
i'm making a clojure idiomatic wrapper around lwjgl, but most of lwjgl's functionality is procedural or state machine oriented
one library will be a dumb simple wrapper for me and others who may want to build on it without dealing with oblique interop syntax and the ridiculous naming conventions of lwjgl
then there will be a second wrapper which depends on that one which provides as pure a view of open-gl and the other libraries that i can
I suspect i won't be able to enforce a lot of clojure's ideas about immutability onto opengl, even if i make the second wrapper really smart
but i can try, and anyone who thinks they can do it better can use the first "dumb-wrapper" to do it painlessly
@bcbradley do you have a repo I can bookmark? I’m interested in eventually porting a lib I have. It would be nice to depend on a clojure library than use lwjgl directly.
basically the only job of the first wrapper is to provide a straight view of open-gl, open-cl, open-al and all those others without having to say http://org.lwjgl.opengl.GL/glBlah()
i haven't put anything on github yet, i'm still working on programmatically converting lwjgl into a clojure-y version
i'm using java reflection and interop, and some other stuffs like trying to take the type information and add it to the clojure version using (with-meta ...) which works like type-hinting
Well if you import GL, it's basically just (GL/glBlah foo bar)
besides there are some things in lwjgl that just have silly naming conventions. I forget which class, but one of them i remember has every method start with "m"
do you have any plans to consolidate/make it easier to access constants in GL11, GL12, ….? I find myself doing absolutely awful things to stay sane when working with gl constants (https://github.com/aaron-santos/zaffre/blob/master/src/zaffre/glterminal.clj#L108)
how might one implement a case-insensitive map? one that preserves the case of the keys, not just downcases them
and if you do it, you'll have to live with a fundamental incorrectness factor by breaking the bijection between keys and what maps to them:
user> {:a 1 :A 2}
{:a 1, :A 2}
Anybody ever use something called JEXL (http://commons.apache.org/proper/commons-jexl/) in java land? Ever use it with clojure? I need to allow similar user entered expressions in a clojure program and would love to learn from others’ experiences. Thanks in advance.
but again, you need it to be correct only on your domain, so if this isn't a problem for you it's not a problem
Anyone have any insight on when Clojure Conj will be going on this year? @dnolen Maybe?
@njj we should be announcing it soon, but I believe it will be DC-area
@alexmiller Awesome thanks dude
@dpsutton I personally would love to do one there :)
well that’s how we got Austin :)
I think a Chicago conj would be cool too
We're up to confirmed 3 Clojure devs in Edmonton if you want to come north... (but please don't since I want to come south again)
is it possible to change the value of a static private final field in Clojure? perhaps using reflection?
you can call the Java reflection APIs
whether or not you’re allowed to do that has actually gone back and forth over various JDKs
it should go without saying that you shouldn’t do that :)
static final fields are often inlined directly into the code using it, so often changing it does not necessarily have any effect
@wei you can generate a new map that is the same as the old one except convert every key to lowercase. During your conversion, if you happen to have two keys that get converted to the same thing then you can handle the collision right there with an exception or whatever.
I have a function that I need to generate but that I would like to have full type hints for. Actually I would like to generate a map of them and then use them in some code in a type hinted way. So there are two problems, first to generate a function that takes and returns a primitive and then the next would be to call that function.
what do you mean by “generate”?
you typically need to use with-meta, vary-meta etc inside macros
@bcbradley right, it would be great if the resulting structure had map semantics though. just wondering if anyone has published something similar
@chrisn I don’t know what the outer ^long is doing
the thing you want to create is (fn ^long [^long data] data)
@wei i think he's saying just make a map with all downcased keys based on your incoming map and just make sure to lookup in it with downcased keys
it would be nice to create single map-like thing with case-insensitive lookup like @bcbradley's downcased key map, but preserving the case on the keys when you iterated through it
that's why i was suggesting the potemkin thing or looking at deftype and implement the functions that you need
oh I ended up just downcasing since it worked (if not ideally) for my case. I’ll probably take another stab at it sometime though, will ping you then!
Then put that in a map. Then a the callsite get it out of the map and call it in a correctly typehinted way.
i was looking into deftype and how to implement the interfaces like ILookup or whatever it is
and hijack valAt
but i'm not too sure how to do this kinda thing. Not sure how popular potemkin is here but you could check out https://github.com/ztellman/potemkin#def-map-type
@chrisn I don’t know that I have time to give you a proper example. I usually end up looking at prior examples to familiarize myself. You might look at some of the things in clojure.core. you’ll want to use meta with the :tag
and :rettag
keys
(defmacro create-simple-fn
[]
`(fn ^long [^long ~'elem-idx]
~'elem-idx))
(def test-map {:a (create-simple-fn)})
(defn call-test-map-fn
^long [^long arg]
(let [fn-data (test-map :a)]
;;currently I have boxing and unboxing here
(fn-data arg)))
yeah, I was wondering about that
Okay, (count "💩") ; => 2
it's a proper bytes count. Just curious about how to get UTF-8
symbols count?
they're not no-ops, as they will force casting of the return type to a long before boxing and they will unbox the args after invocation
but you can achieve the same w/o type hints using the long
function and not have to deal with metadata in macros
@netsu count
is not going to very meaningful with strings like that. look at the Java String apis for that kind of stuff
@alexmiller thanks.
@bronsa you are addressing the second. But defn still needs to be able to generate a function that if the proper overload is called it doesn't do boxing.
the metadata on the var however is the only thing that allows the compiler to use that overload
@netsu String “length” is really the number of Unicode code points and the emoji counts for 2
@chrisn it does but it also adds some metadata to the var, and the compiler looks that metadata up when invoking a Var
the problem is the generic ifn call path doesn't allow that, so stop using ifns, generate custom interfaces with the types you want and call those
at some point I had a prototype of a library that would generate typed interfaces and use those for calls internally in a given bunch of code, so you could write kernels of optimized code, and then externally would present the conventional vars and ifns
with the addendum that it's significant extra work so make sure you actually need that optimization
I am iterating through 10000s of indexes potentially on multiple things in tight math code.
once you get a certain way down that path you start to consider just calling asm directly and generating bytecode :)
I was playing with adding a special form to tools.emitter a while ago that would allow injection of custom bytecode in the middle of a clj statement
you may want to look at something like https://gist.github.com/hiredman/d6ea3e30be757fef6da6 too
or of course, just write this part in Java
Then I have to write different things for the different mathematical types. Or use a code generator for java.
Clojure is an excellent Java code generator :)
I have gone down these paths. The clojure needs to be fast but also I need to be able to add primitive types
Sure, but type hinted macros get you close and you don't have a 2 step compilation process.
This is for a neural networking library @bcbradley and I don't want to write convolution kernels in opencl.
actually that gist reminds me, you could also generate anonymous fns that implement the primitive interfaces, and then invoke the primitive interfaces directly, instead of just calling them like ifns
has anybody written a script to refactor out :refer :all
s? or have a guess how difficult an even-just-mostly-correct impl would be?
what clojure could actually do, is allowing type hinting of callsites to emit conditionally typed callsites, e.g.
^long (f ^long a ^double b)
could emit code that looks like
if (f instanceOf IFn$DLL) (IFn$DLL)f.invokePrim((long) a, (double) b)); else f.invoke(a,b)
@hiredman slamhound doesn't rewrite the non-ns-code at all currently, does it?
oh actually that's okay
lemme try
https://gist.github.com/hiredman/62f11dc663083f2127824d1c393c8f4c will tell you which vars are used in which namespaces over a bunch of code
I find it oddly common to have namespaces (in the wild) that use clojure.string
vars fully-qualified without adding a :require
for them to the ns
header
I see that one more than others. It turns out to be implicitly required automagically anyways (from some other load that happens during the RT startup I think). However, I’ve always considered it bad form to rely on any implicit namespaces to be loaded at all
the set of implicitly loaded namespaces has changed from release to release, if I recall, not something to depend on
you should never assume something is loaded if you haven’t loaded it
I have some pending tickets that reduce the implicit load set on startup
I do that kind of thing at the repl sometimes, but would never do it in my source
noob question - why do people complain about the clojure uberjar startup time in such a way as to suggest that it's a bad choice for backend w/ the lag?
wikibaus: maybe in the context of AWS Lambda
I think right now what actually happens is clojure.core
requires
requires clojure.string
@mikerod that’s the thing I have a ticket for :)
@alexmiller thanks for the input
and http://dev.clojure.org/jira/browse/CLJ-1891 is similar, mostly my fault that I made things worse when we added the socket server
I’ve done a lot of code reviews where I have to repeatedly tell people to not use fully-qualified clojure.string
and clojure.set
without a require
I see pprint occasionally because it’s auto-referred at the repl
it has been a really common thing I keep finding. Implicit dependencies are bad. It’s sort of the same if implicitly depend on transitive deps in Maven etc.
Ah yeah, the socket one makes sense too. Thanks for the links. Good to know this has been brought up before.
I think I started doing it based on some example somewhere - not sure why, but I had this assumption that it was the normal way to use clojure.string
and clojure.set
- I guess I have some fixing to do!
I’m glad we’ve had this chat
noticing java.math.BigInteger doesn’t print as e.g. 42N
but rather 42
. I know casting with bigint will cause it to print properly, but is there another way? These are values I’ve just pulled out of datomic
java.math.BigInteger's gets handled by the printer for java.lang.Number, which just calls toString on the number
I’m attempting to round trip datomic query -> print to edn -> transact. Printing the fields that are marked as bigint in my datomic schema does not include ‘N’ for the reason you mention. Then transacting the slurped edn data fails because the bigint fields are not marked as such. Again, I know I can manually cast to bigint
, but is there another way? like perhaps hijacking print?
they are marked as such in my datomic schema. and when they are read out of the data base they have type java.math.BigInteger
when printing them to an edn file, I lose that info, because the print-method, as you described
You can probably override print-method
cool, just stumbled on that. something like…?
(defmethod clojure.core/print-method java.math.BigInteger [b, ^Writer w]
(.write w (str b))
(.write w "N"))
but clojure doesn't read numbers with a trailing 'N' as a java.math.BigInteger, so if datomic is holding out for an exact type match, that will still fail
oh yeah
I would really think that transact would silently convert a long to a big int.
Datomic will not convert long to bigint, but it will accept Clojure bigint 1234N
as a value for :db.type/bigint
.
@hiredman querying datomic for a bigint attr returns java.math.BigInteger
, but transacting a clojure.lang.BigInt
for the same attr works fine. So, there is an asymmetry
Hi Clojurians! A noobie to clojure here. And to programming in general. I've heard that Clojure drifts away from using inheritance. Is this true? And how do you solve classic inheritance issues in Clojure? Any examples would be appreciated. Thanks!
juanmp: you can't have a problem with inheritance if you don't use it. It is possible to program without it, even without classes. Most business problems can be solved with a bunch of data transformations and some shared, atomically updated state. Inheritance seems to be more useful when implementing programming languages (see Clojure collections type hierarchy) than writing programs. Clojure has a "value-based" hierarchy system but I'm yet to see it used.
Inheritance is one approach to solving a more general problem. Clojure - like most other functional languages - prefers smaller composable parts to direct inheritance. This closely resembles the 'delegation over inheritance' recommendation in OO circles.
Thanks guys! Any examples on how to deal with common “inheritance” examples such as the car rental thats usually used in OO?
What “car rental” example is that?
A friend of mine that that OOP says there’s a typical test for students to teach them polymorphism and inheritance. I was wondering just any common OOP inheritance issues done in a clojure way
@juanmp check this article http://mishadoff.com/blog/clojure-design-patterns/
Thanks @U0HJNJWJH !
I don’t know what the car rental example would be so it’s hard to say how that would be implemented in Clojure. However, most of the OOP inheritance examples I see — particularly those aimed at students — are just plain wrong. Many times the “issues” are simply that inheritance is the wrong approach to use in the first place.
One such “classic example” is Employee / Manager which is often shown as an inheritance relationship, but it’s very easy to show how that breaks down in the real world. It’s a problem better solved with composition: Employee has-a Role, rather than Manager is-a (kind of) Employee. Since Clojure deals with (un-encapsulated, immutable) data separate from functionality, composition is a natural choice there, and either protocols or multi-methods are the natural choice for variability. Those are often complected in OOP languages.
For background, I started out in plain ol’ procedural languages, then spent several years with functional languages — before starting to learn OOP in the early 90’s. I built large production systems with OOP for about two decades before coming back to FP… and I do not miss the incidental complexity of those OOP languages and all the “design patterns” that evolved to address shortcomings in OOP and OO languages! 🙂
Thanks @U0HJNJWJH , lots to read on there!
And thanks @seancorfield Oh that makes more sense. One other example I’ve heard is having the 'Pac-man ghosts’. All four of them are units, are ghosts, have a colour, and have movement. But all four of them have different colours and different movement patterns. I had a friend showing me how he would solve this with inheritance in C#. But I wanna figure out how this would be solve with a Clojure approach to it, just making a good solution.
Three solutions spring to mind, from "most OOP" to least: 1) use a protocol (Ghost) with a move
function and a record for each ghost that implements move
2) use a plain map (or record) for each ghost and a multimethod for move
based on the :color
element of the map 3) use a plain map for each ghost and have :move
as a key whose value is the move function variant.
Only 2) specifically ties the color to the move pattern. The other implementations could have color and movement be independent.
Refactoring between the three is easy -- it's mostly a matter of where/how you define the move
functions -- so I'd probably start with 3) and see whether I needed 2) or 1) later.
Thank you @seancorfield ! This is more what I was looking for, to shift the way of doing things to fit more a functional-clojurey way 😄
@juanmp many "inheritance issues" are caused by OOP. Clojure doesn't really have these issues, since it solves most programming problems in a different way: by putting data first.
@juanmp but if you have some examples, we could probably show you how we solve them differently in Clojure.