This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-24
Channels
- # aleph (4)
- # beginners (93)
- # cider (7)
- # cljs-dev (16)
- # cljsrn (5)
- # clojure (192)
- # clojure-dusseldorf (3)
- # clojure-italy (14)
- # clojure-russia (16)
- # clojure-serbia (1)
- # clojure-spec (85)
- # clojure-taiwan (1)
- # clojure-uk (79)
- # clojurescript (188)
- # code-reviews (9)
- # core-async (2)
- # crypto (1)
- # cursive (26)
- # datomic (21)
- # heroku (1)
- # hoplon (3)
- # jobs (7)
- # jobs-discuss (20)
- # jobs-rus (13)
- # off-topic (77)
- # om (15)
- # onyx (23)
- # pedestal (94)
- # planck (11)
- # proton (10)
- # protorepl (1)
- # re-frame (16)
- # ring (22)
- # ring-swagger (9)
- # rum (2)
- # specter (18)
- # testing (2)
- # untangled (14)
- # vim (12)
- # yada (58)
@hlship any plans to support cljs for client part of lacinia?
hi @martinklepsch, sorry i'm a bit behind but should have time to look into the issue this weekend.
Would you consider the following to be a reasonable (i.e. readable, performant, and idiomatic) implementation of "longest common prefix" for two strings?
(defn- longest-common-prefix [a b]
(->> (map vector a b)
(take-while (fn [[char-a char-b]] (= char-a char-b)))
count))
@pyr no worries, I think it’s probably not even related to unilog but I don’t know enough about this stuff to really tell...
@jumar I think it depends on how similar the strings are in general. I could imagine that using a bi-sectioning algorithm may be faster.
yeah, that's true. Let's say we have no idea how the strings look like and that performance is slightly important, but not the most important factor. Or we can just ignore it for a while and focus on "readable" and "idiomatic" 🙂.
You implementation is fine, you can optimize by replacing the anonymous fn with =
:
(->> ["abcdef" "abdd"] (map vector) (take-while =) count)
@ordnungswidrig I don't think that works.
@rauh you’re right (->> ["abcdef" "abcefgh"] (apply map vector) (take-while (partial apply =)) count)
it is. I was fooled by getting the correct result, 2
.
How do you combine multiple lein profiles in combination with the "+" operator that makes them add to the default profile?
Is there a function that selects keys according to an example map, like:
(f {:a {:b 1 :c 2} :d 2} {:a {:b identity}})
;;=> {:a {:b 1}}
Maybe Specter can do this? (cc @nathanmarz )
This seems useful hmm https://github.com/alandipert/intension
I'm having trouble using java.util.ArrayList
in Clojure, specifically the remove(int index)
method which is supposed to remove the item at given index. It always returns false (meaning item not removed).
There is also a remove(Object o)
method which removes the given object from the list, and this method works as expected.
Here's the code to reproduce:
(import '[java.util ArrayList])
(def foo (new ArrayList [\a \b \c \d]))
(.remove foo \a) ; true
(.remove foo (int 1)) ; false
I presume the integer is not passed as a primitive, but the docs say:
> Coercion ops int
, float
, etc. produce primitives when consumer can take primitive
> (let [foo (int bar)] …)
is the correct way to get a primitive local. Do not use ^Integer etc.
https://clojure.org/reference/java_interop#primitives
I would appreciate if anyone knows what's up here.As a thought, perhaps turn on *warn-on-reflection*
, which may have thrown up a warning when you tried to run compile it
@lsenjov yes, that threw a warning > call to method remove can't be resolved (target class is unknown)
i don't have much experience with java interop, didn't know warn-on-reflection
was a thing
@ihabunek Without the type hint, it probably sees (.remove foo (int 1))) as a call to remove the object (int 1)
i started with (.remove foo 1)
, which doesn't work, then tried using (int 1)
because of what the docs say
btw, is there a more idiomatic way of doing this: i have a large list (3M+ entries) and i need to (drop-nth)
repeatedly. Using vectors, this is slow, because i need to create a new vector each time i drop an element.
@ihabunek Although I’m not 100% sure what your problem looks like. Transients are mutable counterparts which are only to be used within a function for optimizations
@borkdude I've thought about having maps implicitly work that way by translating themselves into multi-path
+ keypath
never had a need for it though, but easy enough to implement yourself by extending ImplicitNav
to maps
@nathanmarz I’d like to use it for a light weight graphql like query to trim down a JSON response
also there's no performance cost to using ImplicitNav
since it is invoked only on the first time through that code and then cached
should only be a few lines of code, if you need help jump into #specter
also it will naturally work for both querying and transformation
@borkdude "only within a function" isn't exactly correct. They aren't thread-safe and so you have to do thread management on your own. That's about the extent of it.
but you can use them in stuff like stateful transducers where several functions and function bodies may modify the same transient
@tbaldridge yeah, correct
Just as I thought I’d seen all mutable types already. I used volatile as mutable inside a function, but would using transients be more performant? It’s mainly used for building/comparing sets in memory, which seems exactly where transients are useful for.
If you want to know more about transients: http://hypirion.com/musings/understanding-clojure-transients
@gklijs so whenever you modify a collection, (set, vector, map, etc.) you get back a new copy of the collection. This is relatively fast, but Transients let you say: "I'm just going to throw away each result since I'm building a collection and I'm only interested in the final result". So transients allow you to look up and add new values, but that's about it, since they are mutable.
But transients also support O(1) conversion to and from persistent collections. So think of (into [] ...)
, this is a perfect use-case for transients as you can make the []
into a transient, add all the items, then make it persistent again.
So I wouldn't say you should use them all the time, but if you want to build a collection and do it very quickly, transients are a good place to start.
if your use case is bulk loading a collection, you should probably use transients
I have a game-state, which I transform into a deftype object, and there are several collection in the deftype object, that are update for each ‘step’ to predict the next state. All I really need from the fuction is the next best move. So none of the intermediate collection really need to be persistant. Can you also do functions like remove on transients?
Looks like there is no remove for a transient, but I could do a reduce with pop to get the same result.
Hi, I got a question about locally installing project with leiningen. I tried to look up on what the standard way of doing this is, but when I do lein install although the dependency does get placed into the default local repo (~/.m2) a new project that wants to import it can not find it. So how am I supposed to do this properly?
lein install
should just work
Maybe you have a typo?
under "~/.m2/repository/"i get the directory structure projectname/projectname/0.1.0 so I tried [projectname "0.1.0"] but lein deps gives the error
are all of projectname's dependencies available either in your .m2/ or from some maven repo lein can pull from?
i basically did a lein install on it, swtiched to the other, added it to the project.clj and ran lein deps on it
how do you know it is the newly installed one? is it the same coordinates (group id, artifact id, version) ?
aaaah well got it, glanced over the fact that the version was named 0.1.0-snapshot, whooops
Bumping this in-case there's some lein experts around now that weren't here before: https://clojurians.slack.com/archives/C03S1KBA2/p1490351252897485
i.e. I'd like to do something like lein with-profile +foo,lib-v1:foo,lib-v2 test
but I get Profiles in with-profile must either all be qualified, or none qualified
Is anyone familiar with http://github.com/Gonzih/cljs-electron ?? Long story short I want to use it to build an app but I'm a confused in regards to where my Clojure (aka desktop code) would go and how it would communicate with the ClojureScript/Electron UI code?
i'm not terribly familiar with cljs-electron but very familiar with electron itself
@mattsfrey so I'm probably using the wrong tool for the job. What I'd like to do is have some clojure code that does some networking stuff and I thought it would be cool to use Electron as a nice front-end for that app. But perhaps my thinking of Electron and CLJS as a "View" for a Clojure "Controller" in a MVC type mindset is misguided. Yes?
you can have your backend server on the jvm and make rest calls to it from an electron frontend
if you want to launch it like an application you'd need to have electron fire up a jvm and run your server jar etc though
If I were to write the app in a more "traditional" (for me) way I would use Netty for the networking and JavaFX for the UI and it would all be one JAR. But if I wanted to do it the way you're describing the way I should approach it is put together the Aleph Clojure stuff and have it communicate to a separate running instance of Electron right?
yeah basically you'd have electron launch your jar file for the server in a process call
Hmm okay. So cljs-electron uses foreman I guess and it starts up electron then figwheel so if I added an additional call to lein run
and wrote my app the way I would expect, then what I need to do is do "typical" server/client comm between the electron and my "server" app right?
lein is a dev tool, don’t make an actual app depend on lein being present at runtime
Hmm, yeah I think you're right. I would be better off with CLJ + some JavaFX to properly bundle it rather than figuring out how I'd properly bundle the electron+clj app. Thanks @noisesmith
@mbcev For what it's worth, you could develop your entire app on top of node written in cljs. I think that's what the cljs-electron template is for. Probably better discussed in #clojurescript
@bja I'll definitely explore more now that I have a better understanding of what Electron is. That was my bad. What I'll probably end up doing is using Clojure to build what I need for right now and then as an exploratory exercise try to re-build it later with Electron and ClojureScript. I'm far less familiar with web related technologies so I think that's why I got tripped up with this.
Building it with cljs-electron would require me to learn more about Electron and Node/NPM and any and all other associated libs/tools/etc whereas if I stay in the JVM I have less new cognitive overhead for myself.
@dragoncube r.e. cljs & Lacinia: this is not on our radar, it is something that a group with a more client-side focus can take on. Part of the point of GraphQL is a clean separation and contract between client and server. Further discussion on #graphql please.
I have a SQL table that needs to be group
ed according to any combination of ~10 columns.
Am I correct that these are my best options, or can you see others?
* YeSQL
and do the group
ing in memory (in clojure)
* HugSQL
and I can do the grouping
in the db now using snippets
You should be able to do the grouping in the DB using either YeSQL
or HugSQL
?
What are you trying to group on?
if i used raw sql (or YeSQL), theres a combinatorial explosion of possible fns I would write oh, and each table can be up to 10-100M rows
and I'm grouping on some enums, and ids
When doing grouping in SQL, it's almost always better to do it in the SQL, as it prevents you from having to send all of the rows down the wire.
What makes it a "combinatorial explosion" of fns? Do you have some complicated logic about when to choose which id?
it's a reporting dashboard, and the client can decide what columns to group by
so, actually it's prob not combinatorial, but exponential (right?)
So something like https://www.hugsql.org/#param-identifier-list ?
Doing it in YeSQL would, admittedly, be rather complicated to do without some rather dangerous string splicing. But it does sound like something that HugSQL's identifier lists solves?
Have you looked at HoneySQL for composable queries?
@seancorfield has a good suggestion. https://github.com/jkk/honeysql will allow you to compose sql queries with native clojure data structures. So you can do what HugSQL is doing with identifier lists in code.
You might also consider checking out http://www.metabase.com/ (open source and written in clojure + js/react) for creating flexible dashboards like it sounds like you're trying to do. I use that regularly for that purpose at my job, much easier than spending my time handling the UI and backend side of that when it's already mostly solved by an off the shelf tool. Coincidentally, they use honeysql in their code for composing queries
@seancorfield thanks, I hadn't considered honeysql for this, so I'll check that out too!
@U236LQYB0 also considering HugSQL, thanks for weighing in on it 🙂
noob with js background here. what is an idiomatic way in clojure to represent a function with optional static properties attached to it?
do you mean like a closure?
(def myfn (let [x 123] (fn [y z] (+ x y z))))
(defn myfn [x] (fn [y z] (+ x y z))
so myfn
closes over the internal fn which will thence forth have an x
ie ((my-fn 1) 2 3) ; => 6
depending on what you're doing, you could also achieve something similar with partial
it's static, because it does not uses this, it's not a class or some stuff. but functions are objects so you can give them properties, in fact they already have properties like .name and .length
there is no way to do this idiomatically in clojure, the closest you can get is metadata
why do you want static (function) properties on a function?
ashnur yes they are objects, but they don’t support arbitrary data added on
well, if the main thing is a function, it's easy to just use it everywhere, and the attached stuff that is very secondary is used much less, but the two are tightly coupled
@noisesmith in javascript, they do
we avoid coupling data and code
ashnur congratulations to javascript
agreed, I haven'y (yet?) seen a use case for what you're asking for, which would lead me to say theres prob a more idiomatic alternative
@noisesmith you are being unhelpful. this wasn't about how js is or isn't, and I already knew that you avoid that coupling, that's why i am asking
as I said, this is possible with metadata
kingfisher.core=> (def foo (with-meta (fn [x] (+ x 42)) {:a "secret"}))
#'kingfisher.core/foo
kingfisher.core=> (meta foo)
{:a "secret”}
unless you are trying to pass the first function and then access the second from that, it's quite easy to just additionally use/refer to that second function
but we avoid coupling data and code
@U0CSAHDV0 well, i assume the situation of having to pass around multiple functions together appears quite often in clojure, but i am still waiting for some pointers 🙂
ashnur you ignored my first answer (use metadata) hopefully you’ll notice my working example
it’s also not idiomatic
@noisesmith i ignored because i know it's not idiomatic, and I sense that the clojure community has better solutions for this specific problems.
the solution being don’t tie data to your functions
you could bundle the functions in a map
{:A (fn [] …) :b (fn [] …)}
and then you can access both, one, or none as needed
I mean, I guess we can get into bigger picture design and show what we do instead...
instead of hiding them in one’s metadata
@noisesmith you continue to be unhelpful, i would appreciate if you would let others answer first, thanks 🙂
well but again, what is your use case here…
i want to represent views (takes a db instance, gives back a vnode that represents a html structure)
what little i understand of that, it sounds like you would return some datastructure that has a :render method, and a :query method
eg: {:render (fn [data] [:div {:class …} …]) :query (fn [db] (query db ..data..)}
not sure what exactly is meant by method in clojure land. in js and java land method is something bound to a this
. i am not fond of those kinds of methods
sorry overloaded terms, just a function
and the idiomatic alternative to a hash-map full of functions is to use defprotocol to define a protocol, and reify that protocol, or define a record implementing the protocol
@noisesmith now you are helpful, thanks 😉
adambros please don’t use the terms method and function interchangibly, they have distinct meanings in clojure and we can use both
@noisesmith what is method in clojure?
you have an object, and you call a method on it - eg. as we mentioned functions are objects, (.invoke f arg arg2 arg3)
uses the low level interface from clojure.lang.IFn to call the function (just an example, don’t do this in your code)
for example (.getTime (java.util.Date.))
returns a number - ms since epoch
yeah, not going to, so methods are the same thing, for java and in case of cljs: js interops
right - methods belong to objects, and are not first class - you can pass the object as an arg, but not the method - it has no independent existence
which is why we invented functions - which are objects with an invoke method
(hope that helps)
IFn only needs to exist in java clojure, in js functions already exist and behave close enough to the way we like - you can think of clojure functions as providing for java something close to js functions
my understanding is that what datomic requires of storage is a key value store and some kind of compare and set operation for keys. you could argue that A and D come from the storage's compare and set and durability of values for keys, but C and I are the result of the database following clojure's epochal time model.
riak is maybe the most extreme example of a non-acid datomic backend, but even dynamodb(the original backend as far as I know) doesn't provide the guarantees of acid
the postgres backend may be the only backend that has acid guarantees out of the box
I am trying to implement a Producer-consumer type system with core.async
using chan
s and go-loop
s. Basically building a web-spider. Two channels - one which stores the URLs encountered till now and another which stores the content from the crawled URLs - are used. I am writing and reading from them inside independent go-loop
s.
But when I execute it, an instance of clojure.core.async.impl.channels.ManyToManyChannel
is returned.
Hey fam. I'm a bit confused as to why I can't get any concurrency from my core.async code. I basically have a buffer of URLs that I'm feeding to n
webcrawlers. Every time there's a new URL, a new crawler service is started. But I'm only getting 1 crawler at a time. Also, my print
statement doesn't print. Any ideas?
(def in-chan (async/chan 2))
(defn start-async-consumers
"Start num-consumers threads that will consume work
from the in-chan and put the results into the out-chan."
[num-consumers chrome save proxyhost proxyport proxypass driver geo]
(dotimes [n num-consumers]
(async/thread
(doall (print (str "New thread" n))
(while true
(let [obj (async/<!! in-chan)]
(.run (core.ServiceDriver. (core.CrawlService. chrome save proxyhost proxyport proxypass driver geo) obj ""))))))))
(defn run [concurrency driver chrome save proxyhost proxyport proxypass geo addy]
(do
(start-async-consumers concurrency chrome save proxyhost (Integer. proxyport) proxypass driver geo)
(while true
(async/>!! in-chan (core.CrawlQueue/consumeAndReplace addy)))))
What are the chances
Clojure is fabulous. But I have not been able to grok the async and lazy bits completely yet. And they are burning me out completely on this problem.
My crawler code is here, in case anybody is feeling charitable enough to go through it: https://github.com/pawandubey/crawljer/blob/master/src/crawljer/core.clj
@bradford Your doall
wraps two expressions… I think that’s why your print
doesn’t.
doall
‘s docstring says it takes a coll
or n
and a coll
(but doesn’t explain the n
). You’re not passing it a collection tho’...
@seancorfield Ah, thanks. Removing that does not seem to fix the concurrency issue (I wasn't expecting it to)
You also don’t need the do
in your run
function — function bodies can have multiple forms already.
What does (core.CrawlQueue/consumeAndReplace addy)
do? Will it produce a new value each time it is called?
@seancorfield hahaha you're the answer on this. Small world. https://www.quora.com/Why-and-when-should-I-use-the-do-expression-in-Clojure-instead-of-just-writing-multiple-expressions-sequentially
I tried your example with a somewhat cut down example (that put random integers into the channel in run
and pulled them out and printed them in start-…
) and ran it with five consumers and it looked like I was getting all five consumer threads running, taking turns processing the values.
If you can’t figure it out, maybe ask in #core-async where you should find folks who use core.async
more heavily.