This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-01-09
Channels
- # beginners (38)
- # boot (160)
- # cider (143)
- # cljs-dev (62)
- # cljsjs (2)
- # cljsrn (3)
- # clojure (278)
- # clojure-austin (8)
- # clojure-brasil (5)
- # clojure-greece (2)
- # clojure-italy (11)
- # clojure-russia (188)
- # clojure-sg (2)
- # clojure-spec (118)
- # clojure-uk (103)
- # clojurescript (87)
- # core-async (8)
- # cryogen (2)
- # cursive (12)
- # datomic (119)
- # emacs (13)
- # hoplon (4)
- # immutant (12)
- # off-topic (12)
- # om (54)
- # om-next (5)
- # onyx (1)
- # pedestal (2)
- # portland-or (2)
- # re-frame (58)
- # reagent (18)
- # ring-swagger (18)
- # rum (4)
- # spacemacs (4)
- # specter (3)
- # untangled (65)
- # yada (25)
even shifting the mantissa is underspecified since it has that implicit leading 1
normally for floats * 2
and / 2
result in an exponent change, not a mantissa change
err wait, actually i do want to shift the mantissa...but this is clearly not the way to do it
in which direction? and what happens to the invisible 1
bit?
so you're essentially adding a 0 just to its right?
it's like halving just part of the number
@sophiago this may or may not be helpful https://github.com/gfredericks/doubles/blob/b0e348a57ffd45467a9462b90cad7ae344c86881/src/com/gfredericks/doubles.clj#L8
fwiw @sophiago float is rarely the right type to use, ever. better to use double, or BigDecimal, particularly when dealing with high precision and currency
@joshjones i know. i'm just not much of a java person so was having trouble finding the corresponding methods for double
@gfredericks i noticed you use type hints in that code. i've been wondering lately since i'm working on all these heavy numerics about the impact of reflection on performance, both for math and functions in general. i've never even tried turning warnings on for the latter. do you have any thoughts on this or could you link me to some reading?
@sophiago reflection adds some nontrivial amount of time to every call. It's somewhere between a micro and a milli, I can't even remember because I just avoid it in any code that might conceivably be sensitive just so I don't have to worry about it.
thought you wrote micro and nano (i have a pounding headache). that actually would matter for me. i should probably start checking for it as some point as well as using the primitive-math library
considering i read protocols add something like ~18ns overhead per call and i'm already considered about that in the context of a numeric tower
the docs are a bit unclear on how to add type hints for variadic functions where the arguments are of different types. is it just like [^int x ^double y]
? and for return values you just add a vector in parens before the argument vector?
each arity goes into a new form, started by a return type hint. (defn foo (^ret [args] body) (^ret [args] body) ... )
you can, sorry. that was a bit unclear. It would look something like:
(defn foo
(^long [x ^String y] x) ; takes something and a String, returns long
(^String [x] (str x))) ; takes something, returns String
one more question...can you only give type hints for primitives? or records as well?
i'm also a bit unclear about the difference between using hints and actual static typing, as in typed-clojure
iirc, hints basically result in a cast in the bytecode, which can give you ClassCastException. core.typed allows you actual checking which means making sure what you return is what you say you're returning
https://github.com/noprompt/garden <-- how do I use garden to write something which would match up with
<div id="app">...</div>
in particular, I don't see how garden allows me to write div.#app@williewillus that makes sense. so there's still a performance hit in terms of casting, just less so than with inference and hopefully less typecasting in general. unfortunately, core.typed doesn't seem to be coming back from the grave. i'm not sure how many people would use it, but afaik it seems like the real major performance difference between clojure and scala when it comes to things like numerics
core.typed is in the grave? o.o
it seems pretty alive haha https://github.com/clojure/core.typed
lol, yeah i saw this and missed the note at the top: https://github.com/frenchy64/typed-clojure
i'm really impressed/intrigued with how you were able to crowdfund working full-time on an open source project
yeah, crowdfunding anything always involves some degree of vulnerability i can imagine
well, projects like yours contribute great value. it just seems they're increasingly not fitting into traditional profit motives/structures. i know engineers at places like google talking about how if there was a universal basic income they would be happier doing open source work that was more interesting than their day jobs (part of a larger conversation about the demand for software engineers now being a bubble that likely won't continue, similar to automation in most other fields)
Hey how come
(with-open [w (java.io.BufferedOutputStream. (java.io.FileOutputStream. "streams/demo"))]
(.write w 1))
Works but
(with-open [w (java.io.BufferedOutputStream. (java.io.FileOutputStream. "streams/demo"))]
(a/go (.write w 1)))
doesnt
(:require [clojure.core.async :as a] [taoensso.nippy :as nippy]
is my require
right now, grad school is striking a nice balance because everyone at work knows what I do and has similar areas.
that's ironic because what got my wheels spinning wrt to this was thinking the project i'm working on is the kind of thing one could apply to a grant for, except i don't have the academic background to do that
so if it proves to have enough useful applications i wonder if crowdfunding my work on it would be viable, especially if i could offer SLAs as incentives
(it's a library/dsl for solving partial differential equations and i decided to lean more towards the dsl side so i can have domain experts test it)
nice. I spent two years developing typed clojure and had a few conf talks before crowdfunding (to say a bit about my journey)
people seem to respect going full time on OS in a different way than just leaving a few tips
I haven't really spent much effort on summarizing my experience, so this is a bit of brain dump
you definitely need a working project before doing something like that. but more where my thinking is coming from is being in a hard spot financially yet spending most of the time that allots time working on something that does contribute quite a bit of value, which i think is more respectable (even if i think that should be besides the point) and sustainable (which does matter) than the plethora of crowdfunding campaigns among broke people i know that are totally aimless
yea. For about 5 hours this summer I had a GoFundMe to raise $10,000 to "support my phd". Went like a lead balloon. But it led me to propose a narrow and compelling project related to core.typed, which went much better.
@adamkowalski The async/go block returns immediately. By the time the .write
is performed, however, the with-open
block has already completed, and as the doc says for with-open
: "Evaluates body in a try expression with names bound to the values of the inits, and a finally clause that calls (.close name) on each name in reverse order." So, the file handle has been closed, before the write can occur.
@adamkowalski Do this to delay completion of with-open
, and it works (only for demo purposes to see the concept, not an effective way to handle concurrency here):
(with-open [w (java.io.BufferedOutputStream. (java.io.FileOutputStream. "test.txt"))]
(async/go
(.write w 1))
(Thread/sleep 500))
so what would the recommended way of handling this be then?
I essentially want something that constantly waits for a message from a channel
then just writes it to a file
why not just do the with-open
inside the go block?
alternatively, you don't need to use with-open
at all; you can just create the stream somewhere and .close
it when you know you're done
you might, for example, close it when the channel closes
something like this:
(def write-channel-to-file [ch]
(let [w (java.io.BufferedOutputStream. (java.io.FileOutputStream. "test.txt"))]
(go-loop [thing (<! ch)]
(if thing
(do
(.write w thing)
(recur (<! ch)))
(.close w)))))
(untested, natch, and you should close on errors too)
yeah how do people generally deal with errors with channels?
right now I usually take in an error channel as an argument and toss em there
but I still have a really hard time debugging anything inside of go blocks
Question... I have a web app, I made an awesome uberjar over a year ago. It still works great, but the domain has changed, and I hardcoded the domain name in a certain email that the app sends to supply users with login links. Is there a way to run the lein repl via an uberjar (and modify running code?)
something like this maybe? https://clojure.org/reference/repl_and_main#_launching_a_socket_server
i tried asking this in the lein channel, but seems rather empty there: i'm maintaining an alternate version of a project that doesn't use a certain dependency and instead of creating a whole separate project i just added another file with a different ns to the current one figuring i could require it from the repl and it would override all the common functions. requiring it is working, but the functions don't seem to be available, including those that aren't duplicates. what am i doing wrong here?
did you refer
the things you wanted?
all the functions are duplicates of the ones in the core ns that i'd like to override
and really the only reason i don't want to create a separate project is because it'd be a mess on github. i'd rather a way to just swap out core files
ah, nm. i realized i can just switch namespaces in the repl, which is really what i wanted to do anyway 🙂
@isaac_cambron blocking io in a go block :(
@mpenet hmm, right, I suppose he should use (thread (loop
instead of (go-loop
@adamkowalski It's tricky, and the answer in my experience depends on who exactly needs to know about the failure (downstream readers of your output channels? producers pushing to your input channels?). One thing though is to catch inside your loop and print the stack trace before it's lost in all that async macro gobbledigook
I wrote some macros that codify how I use core.async and added my exception handling, logging, etc to it. I'd share them, but I don't think I got the error handling stuff quite right either.
@isaac_cambron I'm curious about what you think you got wrong. I'm just getting in to core.async, and I'm curious about best practices for error handling in go blocks.
what do you mean by 'ecommerce' ? i know quite a few european webshops running on clj
So I'm working on 4clojure problem #60 (http://www.4clojure.com/problem/60), and I've found a solution working on my local machine, but it seems to time out on the server. Is there any specific part of my code I can edit to make it run more efficiently?
(fn this
([func start coll]
(this func (cons start coll)))
([func coll]
(letfn [(reduct [result vals]
(let [val (func result (first vals))]
(if (and (not (instance? clojure.lang.IPending vals))
(= (count vals) 1))
(cons val [])
(lazy-seq (cons val (reduct val (rest vals)))))))]
(cons (func (first coll)) (reduct (func (first coll)) (rest coll))))))
@beppu basically I do a good job of a) formalizing who "owns" a channel, b) having good conventions about how to pass them around, and c) how to alert downstream consumers that there's been a problem. I do a terrible job of alerting upstream producers that maybe there isn't a point in producing anything anymore because the consumer kerploded. I still haven't found a satisfactory way to do that that generalizes so at this point it's shrug
@beppu indeed! as much as I like clojure, if there's non comparable from the choice, would go instead with oscar
@isaac_cambron Suppose you gave the chan a size limit; if the consumer stopped consuming, the chan would eventually get filled up by the producer and then it'll block once the limit is reached, effectively stopping the producer. Is that not enough? Do you really need to explicitly communicate some kind of stop message to the upstream producer?
@ejelome Having a big community like the django people seem to have is not to be underestimated. That raw man power can get a lot of work done.
@isaac_cambron (I need to get more hands-on experience w/ core.async before I say any more.) I imagine debugging long pipelines can get tricky.
my "lein ring uberwar" app, with ":aot :all", takes about 8 seconds to start up on google app engine; is this the "most optmized" I can do with "lein ring uberwar", or are there other options that will make startup time faster ?
@qqq, that seems pretty respectable for me. Remember that these highly virtualized systems tend to be pretty weak in compute power. How fast does the uberwar boot on your local box?
@tbaldridge: good question. I don't even know how to use uberwars (expect for packing it to Google). How do I run an uber war locally? (Google points me at running uberjars, which iirc are different things.)
I'm pretty sure these GAE instances I get are .5-1 GB ram + virtualized CPU, so yeah, not most powerful of systems.
I want to construct a namespace symbol programatically, e.g (x :a :b :c) => ‘a.b.c
— what function am I not finding right now? 😄
ah wait, it’s probably as simple as (symbol “a.b.c”)
(symbol ns name)
So I'm trying to solve problem #60 on 4clojure (http://www.4clojure.com/problem/60#prob-title). I basically have to implement reductions
. I have the following code, which works on machine but times out on 4clojure. What am I missing? Is there something I can optimize?
(fn reduct
([func start coll]
(cons (func start)
(lazy-seq (reduct func (first coll) (next coll)))))
([func coll]
(reduct func (first coll) (next coll))))
@donyorm without spoiling your satisfaction from solving it, a hint: what is the base/terminating case for the recursion here? the last case is the one that is not working. (reduct * 2 [3 4 5])
@joshjones Really? For me it fails on the first case. Anyway, that code is wrong I didn't test it properly I guess. I have some other code that was timing out, I'm seeing if I can get that to work. Thanks for helping!
well yes, your answer is wrong on the first case too, but it’s not a timeout issue there 😉 have fun!
@joshjones Yeah that code wasn't really my best code. I had tried to trim down this code (which works) but made some errors. This code passes all the test cases in my code pretty promptly. Why would it time out on the server?
(fn this
([func start coll]
(this func (cons start coll)))
([func coll]
(letfn [(reduct [result vals]
(lazy-seq (let [val (func result (first vals))]
(if (and (not (instance? clojure.lang.IPending vals))
(= (count vals) 1))
(cons val [])
(cons val (reduct val (rest vals)))))))]
(lazy-seq (cons (func (first coll)) (reduct (func (first coll)) (rest coll)))))))
I’m not sure — maybe it’s the clojure gods telling you that you don’t want to really submit that answer, with the IPending
and all .. I’d suggest thinking about it very simply again. Your other answer was actually closer to the spirit of what to do. Look at https://clojure.org/reference/lazy under “The new way:” and give it another go, IMO
What would be the right way to get this to return a value (-> [1 2 3] (partial (filter #(> 3 %))))
Because (-> [1 2 3] (fn [b] (filter #(< 3 %) b)))
says fn is an unsupported binding
is this what you’re trying to do @urbanslug ?
(->> [1 2 3]
(filter #(> 3 %)))
you’re using the thread-first macro there and it doesn’t make much sense in that context
your code was equivalent to:
(partial [1 2 3] (filter #(> 3 %))) ; don’t try this at home
->
and ->>
are macros. ->
evaluates the current form and uses this result as the first argument to the next form. ->>
evaluates the current form and uses this result as the last argument to the next form.
user=> (macroexpand '(-> [1 2 3] (filter #(> 3 %))))
(filter [1 2 3] (fn* [p1__10246#] (> 3 p1__10246#)))
Your code above does: (filter [1 2 3] #(> 3 %))
and it should be (filter #(> 3 %) [1 2 3])
user=> (macroexpand-1 '(->> [1 2 3] (filter #(> 3 %))))
(filter (fn* [p1__10254#] (> 3 p1__10254#)) [1 2 3])
@qqq you have to put wars into an application container like jetty or tomcat for instance
I would suggest to setup a similar system to GAE on your local machine, if that makes sense. At least that is what I usually do, mirror my dev environment as best as I can to the production environment.
@donyorm yes, and it also takes no arguments
Why is 4clojure giving me clojure.lang.ArityException: Wrong number of args (1) passed to: core$conj
then?
transducers want reducing functions in the format of conj: 0 arity = create something 1 arity = finish what you created 2 arity = add something to the something you created
interesting,
oh ick
@donyorm it's because 4clojure is running clojure 1.4
and those other arities were added in 1.8
Finally finished that problem, thanks @tbaldridge
Trying to connect to a JMX interface: The newMXBeanProxy method takes a Class<T> interfaceClass Using (class the-interface) throws a RuntimeExc Not an interface: java.lang.Class
(class foo)
yields the concrete superclass of foo not any of its interfaces
@williewillus ok thanks, that explains the RTExc above.
Anyone know how I can write this so that it gives me [1 2 3 4 5 6]
without changing ->>
to ->
(->> [1 2 3]
((comp vec concat) [4 5 6]))
well you can replace the ->> completely with the as->
this probably belongs on #beginners fyi @urbanslug
probably an occasion not to use a threading macro
@joshjones I don't agree, it's a valid question
in my experience, it's best not to fight threading macros
using comp + threading macros is a bad idea, imo
the question was, “how do I keep ->>
and still make this work" … sounds like forcing it to me .. so I think we agree @pesterhazy
The question is valid either way. But so is the assertion of not fighting the macros.
I usually extract the composition into a def
(def into-array (comp vec concat))
(->> [1 2 3] into-array)
@urbanslug since the question is mostly practice and fun:
boot.user=> (->> [1 2 3] (interleave [4 5 6]) sort)
(1 2 3 4 5 6)
@urbanslug is that for something "real"? 🙂
If you are using a threading macro to “chain” several transformations, that’s the intended purpose. But your cases so far have included only one transformation, which makes its use less than ideal. For learning, anything goes, but in practice you’d probably want to have at least a couple of transformations for it to make sense
@williewillus This seems to do the trick: (Class/forName "com.zaxxer.hikari.HikariPoolMXBean")
This baffles me, perhaps there is a good explanation. Why does almost every library I have ever found display their depedency info (for including in project.clj et al) as an image? I mean the first thing I want to do is copy & paste and... it's a damn image!?!
@sandbags yes. that pisses me off every time
what's particularly baffling is... isn't this actually more difficult than just having the text??
it’s developers being lazy and loading the image from a service which watches version of their library so they don’t have to update the README directly
it’s laziness
you don’t have to create the image. clojars allows you to copy/paste a ‘Version Badge'
add once to your README, and piss off you users for eternity
I cannot
the version badge is great. but it’s not a substitute for a textual representation in your installation instructions
red herring
I would suggest opening a PR to the lib with your reasoning
be the change
I believe in you
but i think trying to circumvent this kind of behaviour has a low probability of success
hell, I’ll commit to doing the same
@beppu now you’re thinking
I see clojars’ badge is an SVG
clojars does serve up an SVG. The idea was to provide something that is copyable. Unfortunately, Github loads SVG in a way to make them non-copyable, for security reasons
of course they do
@bostonaholic Not possible
Only way around Github restrictions seems to be to just write the version number to readme. Several Boot projects use a task to update marked part of readme automatically.
(Or a bash script)
Can someone explain what's so dangerous about embedding the SVG image that github had to resort to replacing SVGs with pixel images?
malware injection
@bostonaholic - oh man, I didn't know svg files could contain javascript. https://www.safaribooksonline.com/library/view/javascript-cookbook/9781449390211/ch15s05.html
well if you do things right you can just link the svg-badge from Clojars to the clojars website where there is a copy-paste text of the latest version. It is just one click away 😉 . You can see it in action in one of my libs https://github.com/carocad/clemence
Had a client once say that part of their app needed to support arbitrary HTML input by users that would then be displayed when any other users looked at that DB record.
I think the correct response is "Do you want someone to hack your site?"
lol, most likely
There's undocumented #=
reader form. Is it a bad idea retained for compatibility reasons, an implementation detail, or is it something else completely?
Yeah, and until recently it was a single reader form which caused side-effects. Weird, really.
I wouldn’t say it’s undocumented.
user=> (doc *read-eval*)
-------------------------
clojure.core/*read-eval*
Defaults to true (or value specified by system property, see below)
***This setting implies that the full power of the reader is in play,
including syntax that can cause code to execute. It should never be
used with untrusted sources. See also: clojure.edn/read.***
When set to logical false in the thread-local binding,
the eval reader (#=) and record/type literal syntax are disabled in read/load.
Example (will fail): (binding [*read-eval* false] (read-string "#=(* 2 21)"))
not much shorter but (str/join (repeat n \space))
? needs a clojure.string require though
It's bad enough that there's clojure.edn that disables it.
How are functions like ints
used? What kind of argument needs to be coerced into a typed array? I have tried to supply various objects to this function, and the only one which worked was (integer-array 1)
, which does not need to be coerced anyway.
Ah, I see the example here: https://clojuredocs.org/clojure.core/bytes
@qqq: use declare
or an unbound def
@williewillus : right, thanks!
@dottedmag I believe def
adds some extra metadata to the Var.
I really wish there was a version of map that was: list -> list, vector -> vector the existing map causes all types of confusion when I use conj
mapv
?
use into
with a transducer
(into [] (map foo) a-vector)
you pick the output coll
https://clojure.org/guides/faq#seqs_vs_colls has some more info too
@qqq (transform ALL map-fn any-seq-type)
with specter preserves type
@nathanmarz : I can't figure out if specter is a brilliant composition of orthogonal components or a set of useful hacks; is there some relation between specter and datalog? it seems like esentially there is a "query" step, and an "update" step
@qqq no relation to datalog
it's just function composition at its core
this is a simplified implementation of specter that shows the basics of how it works: https://github.com/nathanmarz/basic-specter/blob/master/src/basic_specter.clj
@nathanmarz: very interesting; thanks; was just about to look at https://www.youtube.com/watch?v=VTCy_DkAJGk
keep in mind that talk is outdated and does not include anything about inline caching
I recommend reading this as well: https://github.com/nathanmarz/specter/wiki/Specter's-inline-caching-implementation