This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-18
Channels
- # ai (1)
- # beginners (71)
- # boot (15)
- # cider (26)
- # clara (4)
- # cljs-dev (81)
- # cljsrn (26)
- # clojure (393)
- # clojure-berlin (2)
- # clojure-dev (5)
- # clojure-dusseldorf (1)
- # clojure-greece (5)
- # clojure-italy (6)
- # clojure-russia (97)
- # clojure-serbia (11)
- # clojure-sg (2)
- # clojure-spec (14)
- # clojure-uk (66)
- # clojurescript (58)
- # core-async (19)
- # cursive (18)
- # data-science (2)
- # datomic (75)
- # emacs (20)
- # events (5)
- # figwheel (1)
- # graphql (2)
- # hoplon (29)
- # jobs-discuss (3)
- # juxt (6)
- # lein-figwheel (1)
- # london-clojurians (2)
- # lumo (29)
- # mount (9)
- # off-topic (4)
- # om (16)
- # onyx (25)
- # other-languages (2)
- # pedestal (38)
- # protorepl (2)
- # re-frame (20)
- # reagent (9)
- # ring-swagger (6)
- # sql (10)
- # unrepl (3)
- # untangled (19)
- # utah-clojurians (1)
- # videos (2)
- # vim (20)
I have a sorted list of things, say: [4, 9, 100, 327]
and I want to fill in all the gaps in the range [0,1000]
with 1
s,
so, [1,1,1,4,1,1,1,1,9,...]
(the sorted "things" are actually records, sorted by one key)
the collection will be quite big... I built an awkward loop
for it, but...
whats an elegant functional way to do that?
Maybe create a vector of 1000 1's, then update the keys for the ones that you have?
the 1000 is more like 1-10M, and you mean update it at it's index? That sounds slow, no?
Seems the same as the loop method though?
(oh also, i don't have the index numbers)
my loop method was to create a range of the keys and then walk the keys at the same time as walking my "populated" records
seems pretty imperative
Can you restate the actual problem with records? I don't really understand it
sure, thanks, one sec
so a generic "empty" record, no more than a date, fills in when a date isn't present for a thing
dates can be joda times, and I work with them through clj-time
they can also be present many times
not the prettiest, but you get the idea:
(defn distribute [r]
(flatten
[(take (first r) (cycle [0]))
(map
(fn [x y] [x y])
r
(map
#(take % (cycle [0]))
(map #(* -1 %)
(map #(apply - %)
(partition 2 1 r)))))]))
sure, I'm looking that over now, I like it
prob use repeat
instead of cycle
constantly, repeat, repeatedly
they always throw me off 🙂
ya, the partition
is what stood out to me, I think I can do something with that
and adapt the rest
thanks for helping me see this problem thru another lens!
can partition-by
take advantage of a collection being sorted?
mmm, with respect to the method I showed, I think all you want is the diff between them, right? Not sure where you're going with partition-by
oh it's fine, my use case was a bit different than the example I originally gave i think I lost some detail in distilling it to that problem but your answer helped
@josh.freckleton you could save a lot of space overhead by making a deftype that uses an underlying collection, or fills in a default if not found
you'd just need to make sure you implement the right protocols for seq access and associative lookup
yeah I was thinking about representing missing ones that way
or just via nil punning
well, get does take an optional not-found arg
so you could just use get to implement the stuff at the bottom
yeah that kind of thing
Hey gang, can someone explain why, for example, this is the case? I'm a bit lost in the semantics of it.
(apply '/ '(16 8))
; => 8
@attentive symbols when used as functions attempt to look themselves up
turns out '/ was not something you could look up in your list (or any list, incidentally) so it returns nil
err, no, sorry - thanks to apply it tries to look up '/ in 16, and 8 is the default (not found) argument to get
Ah, right—the symbol acts as a keyword-style map lookup, but in a non-map, and then returns the second (default) arg?
right, exactly
it is very strange
the most evil version of this: ('or true :not-found)
because sometimes your test case makes it look like it's working...
my favorite example of how weird get is:
oops, missed one, but you get the idea
I feel like the get
-alike behaviour should check for an IPersistentMap interface or something similar, but I guess it would degrade performance?
I have no idea
hello everyone, i know jdbc is synchronous, but is anyone aware of somekind of thread pool which can be consumed by an async api? (a dedicated threadpool for database access)
another noob question, any concise way of splitting a vector at a given set of indicies?
@cjmurphy thanks, yeah I was going down the recur path, was hoping for something built in, but that works
Hi! I want to do some changes on the figwheel-sidecar
project and push my version to the clojars. But when deploying, it tells me that I don't have access to the 'figwheel-sidecar' group. How can I successfully deploy it so that I can use it for myself? Thank you!
@cmal i found this site yesterday: https://jitpack.io/ (not sure how well it works). but allows you to deploy jars straight from your GitHub
@cmal you would have to change the project.clj to use your own namespace, e.g. cmal/figwheel-sidecar (good practice is to match your github username aka the whole thing matches where your fork is in github)
The idea was to avoid huge collections dumped to stdout in error messages (more idiomatic ways or library tools welcome). The issue is that the collection doesn't get realized with this, so only an object name is printed to stdout.
here you pass it a string, which is an eager collection so doall is effectively a no-op
what is the full set of places where a doall
wrapper would work for this example? I have probably not mastered this aspect as of yet, so thanks for your help!
well as soon as you do (count coll) it will likely realize it anyway, so it's seems flawed in many ways
the goal of the whole function seems not to have to realize the whole coll in logging (I think)
How can I write this http://stackoverflow.com/a/14987992 on Clojure? .class
expression?
@ilevd So:
(def cs (.getDeclaredField Charset "defaultCharset"))
(.setAccessible cs true)
@borkdude Hmm, I'm trying with doto
(doto (.getDeclaredField Charset "defaultCharset") (.setAccesible true) (.set nil nil))
and it's not working@biscuitpants @stain Ahh... Thank you! I'll try those.
does anyone know if there exists some code to optimistically convert SQL queries to honeysql?
sorry, don’t know of such a tool… but you can always mix&match honeysql with hugsql/yesql/jeesql type of libraries
I've got it currently working as sql in the system just fine, but want to change generally to honeysql, because we just like it better - so looking for a tool to ease the process a bit
@cmal the preferred method for forks is to use the org.clojars.your-username
group - see https://github.com/clojars/clojars-web/wiki/Groups#personal-groups
How can the figwheel-sidecar
project be running on my own machine with my Emacs so I can debug into it? I tried to cider-jack-in
but how to let the clojurescript project depends on it and let Emacs run the local version?
@cmal do lein install
in that project folder. make sure to bump the version though, in both your project and the project.clj. your lein
will then pickup this local jar, and use it instead
@biscuitpants Should I run lein install
in the figwheel-sidecar
project, or the project I want to use my version of figwheel-sidecar
?
in your fighweel-sidecar
project
and then your other project will use your local one
So lein install
just replace the figwheel-sidecar
jar used by my project, so my project will use this jar generated by lein install
?
no, lein install
will install that jar locally, so another project can use it. once it is installed, running lein repl
in another project will retrieve that dependency (your custom sidecar, for instance) and use the local version
you can also use checkouts, if you want
https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies
Thank you very much! @biscuitpants But how can I run a repl and debug in my version of figwheel-sidecar
?
you can run the repl in a project that uses your custom version of sidecar
checkouts may actually be better, if you’re making a few systematic changes. that way you don’t need to restart the repl each time you want to try out your new version
sure 🙂 shout if you get stuck!
what are you trying to change / fix, if i may ask?
Ok, I'll shout loudly! I want to add a proxy to lein-figwheel
to let me get access to a remote API. Otherwise it will give me a CORS error note.
ah i see
how come this doesn’t work:
(def (symbol "f") 12)
CompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(/private/var/folders/7x/bdhllf3x3hj6rq19xn1rbh000000gn/T/form-init4103840200690063741.clj:1:1)
Also see here: https://stackoverflow.com/a/2530677
@tmtwd or use macro
user=> (defmacro make-var [name val]
#_=> (let [s (symbol name)]
#_=> `(def ~s ~val)))
#'user/make-var
user=> (make-var "aaa" 444)
#'user/aaa
user=> aaa
444
(defmacro make-vars
""
[names val]
`(do
~@(for [x names]
(let [s (symbol x)]
`(def ~s ~val)))))
I'm wondering is there any shorthand for (doall (for [x y] (side-effect-and-return-value x))
?
metametadata: just to make sure, you want to run over the entire collection at once, but you also want keep the return values?
I generally just do (mapv side-effect-and-return-value y)
; mapv
is identical to map
, but returns a vector and is non-lazy
if you don’t care about the results, then you can do (run! side-effect-and-return-value y)
yes, I do want to gather all the return values after doing all side-effects at once
ok, I think I could use mapv
for simple cases
but it's not symmetrical as soon as there's :when
in for
used 🙂
correct, there’s no direct equivalent to for
that’s not lazy. Your options tend to be to use doall
, mapv
, into
, loop/recur
, run!
, or reduce
. All of them are good choices depending on your use case 🙂
If you like for
with :when
, then doall
or (into [] ...)
are probably what you’re looking at
Thank you for the elaborate answer! I've also found the advice to use transducers: https://stuartsierra.com/2015/08/25/clojure-donts-lazy-effects
I've got something that looks like this
(def keyword->joystick-hat
{:centered GLFW/GLFW_HAT_CENTERED
:up GLFW/GLFW_HAT_UP
:right GLFW/GLFW_HAT_RIGHT
:down GLFW/GLFW_HAT_DOWN
:left GLFW/GLFW_HAT_LEFT
:right-up GLFW/GLFW_HAT_RIGHT_UP
:right-down GLFW/GLFW_HAT_RIGHT_DOWN
:left-up GLFW/GLFW_HAT_LEFT_UP
:left-down GLFW/GLFW_HAT_LEFT_DOWN})
(def joystick-hat->keyword (map-invert keyword->joystick-hat))
with this in ns macro: (ns glfw.enumerations
(:require [clojure.set :refer [map-invert]])
(:import org.lwjgl.glfw.GLFW))
with this as project.clj:(defproject vulkan-hello-world "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url ""
:license {:name "Eclipse Public License"
:url ""}
:dependencies [[org.clojure/clojure "1.8.0"]
[org.lwjgl/lwjgl "3.1.1"]
[org.lwjgl/lwjgl "3.1.1" :classifier "natives-linux" :native-prefix ""]
[org.lwjgl/lwjgl "3.1.1" :classifier "natives-macos" :native-prefix ""]
[org.lwjgl/lwjgl "3.1.1" :classifier "natives-windows" :native-prefix ""]
[org.lwjgl/lwjgl-glfw "3.1.1"]
[org.lwjgl/lwjgl-glfw "3.1.1" :classifier "natives-linux" :natives-prefix ""]
[org.lwjgl/lwjgl-glfw "3.1.1" :classifier "natives-macos" :natives-prefix ""]
[org.lwjgl/lwjgl-glfw "3.1.1" :classifier "natives-windows" :natives-prefix ""]]
:main ^:skip-aot vulkan-hello-world.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
(my src folder has two folders in it, vulkan-hello-world
and glfw
)
the core app just has this in it right now: (ns vulkan-hello-world.core
(:require [glfw.functions :as glfw])
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[& args]
; (when (glfw/init)
; (when-let [window (glfw/create-window 640 480 "Hello World" 0 0)]
; (glfw/make-context-current window)
; (loop []
; (when (not (glfw/window-should-close window))
; (glfw/swap-buffers window)
; (glfw/poll-events)
; (recur)))
; (glfw/terminate))))
(println "done"))
on lein run
i get the error Exception in threat "main" java.lang.RuntimeException: Unable to find static field: GLFW_HAT_DOWN in class org.lwjgl.glfw.GLFW, compiling:(glfw/enumerations.clj:22:1)
I find that very odd, since the static field is defined here: https://javadoc.lwjgl.org/org/lwjgl/glfw/GLFW.html, and why isn't it complaining about the GLFW/GLFW_HAT_CENTERED
or any of the others? 😱well, those java docs are for a specific version of the code, does it match the code you are trying to run against?
@mobileink seems like it
do you see anything wrong with this?
(defn create-window ^long [width height title monitor share]
(let [WIDTH (int width)
HEIGHT (int height)
TITLE (str->ByteBuffer title)
MONITOR (long monitor)
SHARE (long share)
RESULT (GLFW/glfwCreateWindow WIDTH HEIGHT TITLE MONITOR SHARE)]
(free TITLE)
RESULT))
The error i'm getting is: Exception in thread "main" java.lang.IllegalArgumentException: fns taking primitives support only 4 or fewer args, compiling:(glfw/functions.clj:22:1)
@bcbradley what if you move the ^long annotation so it would be on the function name and not the arg list?
or just removed it…
why are you annotating it?
you can’t annotate a function to take primitives and take 5 args
@bcbradley i don't see anything wrong with the syntax. the message suggests that glfw places constraints you have violated.
you aren’t annotating the return value, you are hinting the args
@mobileink no, it is a clojure compiler restriction on args
yeah - but I think spec will … eventually … help with that
@bcbradley maybe I’m misinterpreting - but the error message will go away if you remove the type hint
and you shouldn’t just randomly hint things - hint if there’s a performance issue
(or correctness issue that can only be fixed with hinting)
otherwise hints just add noise (and as here, break things)
thats kind of like saying that we shouldn't build bridges if we can build a dam on every river
no, hints shouldn’t be used in the general case
i realize clojure is a dynamically typed language and you should only optimize with hints to the compiler when you have a performance issue
hint it Long instead of long
@bcbradley my hunch is that only certain arity counts are supported to return primitives due to how IFn is defined
because of the way IFn works, clojure.core has to declare (in java code) every arity and return type separately
these are the declarations https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L25
they stopped at an arbitrary arg count
i would prefer if the compiler just ignored my hint in this case, not freak out and give up
another fix would be to put a bunch of args in a list / vector
because who knows, someone might someday figure out a way to solve this issue by redefining Ifn or something
@bcbradley but then you think you are getting an optimization that is silently not provided
I think it’s better to explicitly say “I can’t actually optimize this” - this is why we have recur instead of implicit self-call tail optimization also
nothing would have prevented implicit self-call optimization, but requiring that you ask explicitly and erroring if it wouldn’t work is better
the way it is now, i'll have to remove all primitive hints on return values for functions that have more than 4 arguments because of the way IFn is defined. If the compiler were to instead just ignore my hint and give me a warning telling me that the hint i provided cannot be used, then i would not have to touch my codebase-- it would also mean that in the future if IFn is ever redefined or some sort of changes elsewhere are made to circumvent the combinatorial explosion aspect that essentially prevents us from having primitive return values with arbitrary arity functions, then i again don't have to touch my code base because the hints I provided are still there-- only now the compiler will use them and has no need to warn me
because the compiler freaks out instead of giving me a warning, I have to remove the hints now, and I would have to add them again in the future if these issues were ever addressed
or you could wrap up some of your args in a collection to keep the arg count shorter
if you put them in eg. an int-array it should still perform well
wow. now i understand a bit of how much would be involved in adding more primitive types
its not a terribly big issue its just annoying to have to go through 7 thousand lines of code and remove type hints on return values
I agree that type hints are complected with optimization promises that actually change how code is compiled and that’s a bit weird
that makes me think that the name "hint" is deficient rather than the implementation
@bcbradley my response to the situation is to avoid primitive type hints in particular, due to the various weird ways they can break code
and to avoid type hinting at all unless I can prove I need it via profiling
i don't know what the performance profile will be because i don't know how it will be used
the best thing i can do is make it as lean as i can and help the compiler as much as i can
write it in java
seriously - if your top priority is that things be lean, doing htat in java is much less of a headache
then maybe your lib doesn’t need to exist?
OK - and if the domain calls for perf, wrapping it just-because seems an odd choice
oh, OK
well - keeping the clojure lean is going to be a pain in the ass, especially if you have no reasonable way to profile
I’ll leave it at that, and you can decide if it’s worth it
have you looked at the kind of stuff the arcadia people have had to do to use clojure? they built their own assembler
I mean - it’s some people’s idea of fun, and that’s cool
except it’s a lot easier to just write the java, especially if you want to use unboxed primitives
I’ve done both
the context was making a clojure library that just isomorphically maps to a java library is dumb
how about a sane java api?
if the clojure library doesn't actually do anything, if it just calls java methods-- thats not very useful
@mobileink if youre task is “make a wrapper that is sane to use from clojure” and your top priority is performance and making lean code, think about clojure usability while writing it in java
that’s the easier way to do it
of course if performance is a lower priority, yeah, clojure is a great way to make a saner api
welk to be honest i'm usually more interested in conceptual clarity. some java apis have some don't.
and i'll admit that performance is usually the last thing i think of. you can always optimize, later.
out of curiosity: how often do you come across a java api that is unclunky, such that a wrapper would be a straight translation?
technically most of kafka was written in scala, but I think it comes close, and joda time
I’m aware that there are people that disagree with me about these things
also ExecutorService and ScheduledExecutorService - almost always better and simpler to use directly compared to the many wrapper libs
yeah, de gustibus non disputandem etc. but ihave not come across many, not that i have looked very hard.
Process / ProcessBuilder
i wouldn't mind using clojure's java interop to work with vulkan if it were there were a pure java vulkan implementation but there isn't (and I don't expect there to be)-- working with java in clojure is fine, but working with what is basically c in java in clojure is not fine, and I just wanted to have a library to hide the ugliness, manual memory management, and etc
on top of that the lwjgl libraries use "buffers" instead of pointers, which means they basically have a subclass for every corresponding c struct that represents the "array" form of that struct
how many of those could you hide without degrading performance?
there is something i won't be able to hide though, and thats the ugliness inherent in vulkan itself
arcadia made a special compiler, using their own assembler, in order to make clojure code that doesn’t use the gc
it’s the thing that makes me wonder if the manual memory management isn’t serving an important purpose
i'll give it a look later, right now i'm in the process of finishing this library as I've already finished the code for it and just need to run it through the compiler to make sure I didn't mess up
@noisesmith nit: the examples you gave are "core" java, and i agree the for some of them you do not need a clojure wrapper. 3rd party libs are a whole 'nother story, though.
not all of them are core java
and all of them are libs that people commonly use clojure wrappers for
take String as an example. no need for a wrapper, except that we want one, in the end.
greetings! what are tradeoffs of this
(let [last-temp-id (atom -1000000)]
(defn tempid []
(swap! last-temp-id dec)))
compared to following?
(def ^:private last-temp-id (atom -1000000))
(defn tempid []
(swap! last-temp-id dec))
my understanding is that it is considered bad form to put def or defn inside a let.
I do that on occasion. I just guarantees that nothing except that function has access to that mutable value
because hiding data is an antipattern in clojure
that’s the common consensus at least
^:private
just means that no one outside of the namespace has access to the function (which is actually a lie, you can access it if you try hard enough)
the let
means that other code doesn’t have a reasonable means of accessing it. And yeah, it’s about “hiding” data
and mutating the top level, when all you want to do is play with something in a particular scope, is bad form.
generally when I use that kind of thing, it’s when I’m memoizing (or some other form of cache) that’s specific to the function I’m working on
also, in a second case, atom is not passed as an argument either, and the fact that that does not trigger most riders' aesthetic senses, brought me here now :)
@misha yeah, top level atoms are something I reject in code reviews
Could I implement it in a different fashion? Yes. But I like the separation of concerns the let provides. I’ll admit it does look horrible though, and it’s very rare that I do something like that.
but I also don’t accept def / defn inside let
@noisesmith what are the alternatives to top level atoms?
generally speaking clojure people expect functions to be pure by default, so if you create a function that returns a different value on subsequent invocations because it mutates a variable that only it can see, then you have something that isn't idiomatic clojure.
providing an argument, or using a proper system initialization argument (eg. as used with stuartsierra/component)
my advice is don't try to hide data. if someone wants to have some state let them control that, let them declare an atom or whatever kind of reference type
@misha why do you want a defn in your first example? why not (let [f (fn ... )]... f )
to whatever extent is possible, just use pure functions that take data and return data
Generally, most of the above - is a sound advice: don't hide the data, pass stuff as an argument, pure functions.
This particular use case, however: 1. only that function has to have an access to data, 2. need to emit unique value during lifetime of the process across all the calls.
so would renaming it to next-tempid!
be good enough?
@mobileink not sure I understood w/o an actual example
The cannonical way to do what you're wanting to do, if no other functions will be using the atom, is to use a def
sorry, i don't see what you're trying to do. but for the record def and defn are side-effe ctish - they intern vars.
not just that, they mutate vars
@bcbradley no particular reason "why not", just trying to keep in consistent with datomic/datascript temp-ids' semantics. An actual story is longer than that, of course
instead of looking at it like a function that mutates a local atom to ensure unique ids
@wiseman the fun part is that gensym does the same kind of shared implicit mutability that we are criticizing here
i’ve seen & done the let-over-defn thing in lisp before, for the same reasons you’ve brought up. i’ve mostly decided it’s better to make the state accessible, though, even if its a little hidden via ^:private
or whatever.
wiseman: agreed, and a pattern I like is an implementation function that takes an explicit state arg, even if that isn’t the one most users of the lib access, so that unit testing can be cleaner and simpler to implement
Is there a way to have a macro expand to (catch Exception ) / if in CLJ (catch :default ) / if in CLJS ?
@john does it have any different/measurable implications/advantages over "let-first" my first example?
it is not that triggering, when def
is a top form, yes, but does it actually work in a different way under the hood? atom is still inaccessible, neither it is passed as an argument, etc
yeah, the def is just quibbling with the semantics, it doesn’t address the criticism
it’s not just a smell, we actually want to avoid inaccessible state
especially inaccessible state that changes over time that doesn’t have an init or reset accessible anywhere
I’m saying it’s not just a smell - it also does something we don’t want
and his example solves the smell but not the problem
right, except when you don't. Basically, don't make impure functions if you don't have to. But when you really really have to, the def-let form above smells less than the let-def form.
I agree, that even If I understand every bit of this particular case, some reader might extrapolate a bit too much, and use same construction inappropriately somewhere else
(def local-state (atom 0))
(defn new-token
[state]
(swap! state inc))
(defn next-token
[]
(new-token local-state))
It’s clear that local-state is an implementation detail, but there is no inaccessible local state. This simplifies testing, debugging, and extension (let’s pretend the code was doing something that is actually interesting enough to need testing and debugging and extension)@noisesmith if that's a library, I'd like to avoid extra stuff to show up in an autocomplete suggests, please :) this is where "hide that atom nobody should ever care except this 1 fn" really comes from
OK, then use ^:private if you must, it’s simple to work around
what I’m providing an alternative to here is the thing where let is used to hide data
@noisesmith what about the argument that closing over the atom increases the semantic determinacy of the whole program, assuming others can come in underneath you and change it?
we increase semantic determinacy by not using mutation
sure, they can also use def to replace all your functions
closing over the atom just feels like a stronger guarantee, but you have me questioning my intuition 🙂
on a scale of dirty to filthy how bad is this:
(def ids (iterate dec -999999))
(def next-id []
(def ids (drop 1 ids))
(first ids))
don’t use def for runtime changes
(unless specifically redefining code because you are in a development environment of course - def / defn in a repl are fine)
we have types that are actually good for runtime mutation
that address things like data races for example
two people can get the same id from that code
can two threads get the same id back from datomic?
I went with private atom. the main benefit is "I will not freak out in 2 weeks looking at (gensym) in my mundane code just to get some negative int"
@bcbradley did you assume my gender? (I am dude, btw )
misha is a nickname for alexander in slavic countries
(I almost said something myself)
err, no, michael
sasha - alexander