This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-12-28
Channels
- # admin-announcements (72)
- # aws (23)
- # beginners (43)
- # boot (140)
- # cider (11)
- # cljs-dev (4)
- # cljsrn (82)
- # clojars (2)
- # clojure (215)
- # clojure-nl (2)
- # clojure-russia (149)
- # clojurecup (4)
- # clojurescript (159)
- # cursive (19)
- # datomic (47)
- # editors (1)
- # emacs (27)
- # hoplon (32)
- # jobs (11)
- # ldnclj (3)
- # mount (33)
- # off-topic (1)
- # om (380)
- # onyx (1)
- # re-frame (2)
- # reagent (54)
- # yada (63)
hmmm, maybe that's a bad idea. perhaps staying in interop is better in this case. thx
@aaelony: What's your use case here?
well… the ecosystem around leiningen is so vast and tooling wise… I can’t ask for anything better
I’ve never used boot… but someone should write a program that takes a leiningen plugin and makes it boot compatible
@aaelony: Well, using Clojure to do Java interop can be better than straight Java, insofar as there's less typing (in multiple ways ) but it's certainly not as nice and "pure Clojure". How much pain you get will depend on the API of the Java code. (sorry for the slow response -- had to feed cats and get our dinner too!).
@seancorfield: thanks, but this question was only about java 8 streams
@crocket: We just switched from Leiningen to Boot at work (World Singles). We really want to move more of our build processes into Clojure but writing Leiningen plugins hasn't always been very easy for us. By converting to Boot, we've already been able to replace the plugins with simple Boot tasks, and move several other parts of the build into Boot tasks, and compose them. So we shaved about a minute off our build script because we're not firing up as many JVMs
@aaelony: Understood. If all you're working with is streams, you're not going to get much benefit from Clojure there.
@seancorfield: Could boot be a short-term gain followed by a long-term loss? Long-term means several months down the line.
@seancorfield: yes, there be streams and there does not appear to be a stream/collection conversion, or perhaps interop is better anyway.
@crocket: Our long term goal was to move more of our build process to Clojure and we can do that with Boot so that's a win over the long term for us
I wasn't very impressed with Boot when it first appeared but revisiting it now it really has matured... the ecosystem is still young...
An advantage is that boot could easily go beyond leiningen in scope since it's clojure code.
Yeah, Boot is more than just a project build tool. But Leiningen has the templates which is a big plus, and it's pretty much ubiquitous in the Clojure world
Not yet.
We started out with Grunt, but the new front end project we're doing is using Gulp.
No, Gulp is used by our front end team.
We're moving an Ant script to Boot
I've never liked Ant, but the alternatives were... mostly no better...
Are you suffering the cost of writing and running tests on clojure? I heard that test costs become uneconomical in large projects in dynamic languages.
Where did you hear that?
A blog maintained by a haskell supporter. I never maintained large projects, so I don't have first-hand experiences.
Haskell people don't like dynamically typed languages
We have 30,000 lines of Clojure.
And about 7,600 lines of tests.
But some of that is testing our REST API (which is written in multiple languages).
He likes clojure, too, but he thinks haskell is more economical than clojure in large projects because of haskell compiler.
100,000? 200,000?
(I used to maintain a code base that was about 250,000 lines of C++, back in the 90's)
@seancorfield: How was your experience on large projects written in statically typed functional languages and dynamically typed functional languages?
We have 89,000 lines of non-Clojure code alongside the 30,000 lines...
In the map
you could just use *
instead of #(* %1 %2)
I think you can avoid the condition on bigint
/ int
by using a N
suffix on 13
and 10
?
@seancorfield: Thanks!
Using assoc!
function for assoc items to the transient associative data structure and it only associates 8 first elements discarding the rest...
It s normal, you re not supposed to bash it in place (it s not a java style mutable ref)
http://clojure.org/transients > Note in particular that transients are not designed to be bashed in-place. You must capture and use the return value in the next call. In this way, they support the same code structure as the functional persistent code they replace.
Say, if I want to extend equality what is the common practice? Say I have a new type SomeRecord
and I want to make sure that both (= new-record any-existing-type)
and (= any-existing-type new-record)
work as expected.
It would have been nice if operators had multimethods you could extend on, but alas I don't think that's the case.
I was just wondering how hard would it be to replicate Perl junctions so that they work in usual Clojure contexts, instead of requiring a new set of operators.
Or maybe it is IComparable
( https://github.com/mylesmegyesi/clojure.core/blob/master/src/jvm/clojure/lang/comparison.clj#L7 ) ?
I think it is one of the differences between clojure and clojurescript : in cljs protocols are at the bottom
@niwinz: Yeah, that sounds like a nice feature to have, being able to extend core types easily.
I think Dunaj was going in such a direction, but not sure if that extended to all the operations like +
, *
, and
and the like.
@niwinz: yeah, I noticed that while looking at the code of clojure.lang.Util/equiv
, but this begs another question
myRecord.equals(somethingElseEntirely)
is just one direction of equality, what about sometingElseEntirely.equals(myRecord)
so if you compare different types of objects it should return false (in java it will not compile because of type checking)
Sure, but - since I was thinking about junctions - let's have a concrete example - it is entirely valid to want to (= a (junction/any 1 2 3))
where one side is Integer
and the other is AndJunction<Integer>
.
In Scala that could probably be solved by implicit conversions, by lifting Integer
to something like JunctionComparable<Integer>
or something, but I'm not sure how that would be approached in Clojure.
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentSet.java#L53
If you see the set impl, it uses equals for just do that, receiving Object as parameter so I think you can do the same thing.
Yes, but that's just this once specific case again - of course you can just do (#{1 2 3} a)
to the same effect as (= a (junction/any 1 2 3))
and all
, one
, none
junctions can be rewritten in a similar way probably
But there's no generic solution to this problem, that is extending the built-in behaviours.
The only solution that I found, is implement the equality check as your own abstraction
Right, but then you're building your own walled garden, since other libraries will not be using that ; /
Being able to do (defmethod clojure.lang/equals [MyType _] ...)
and similar (for things like multiplication, addition, comparision and such) would give a lot of flexibility.
I think multimethods were in 1.0 though, so the same could have been achieved without protocols.
Sure, but that's an optimisation concern more than anything, now that Clojure is at 1.8 (almost) then changing the shape of the API is considerably harder than investing in optimisations.
And also I think multimethods can be optimised to be fairly performant, let me find that.
http://www.stroustrup.com/multimethods.pdf - see the last page for performance. But it's probably true that it would be slower in Java, since single dispatch is built-in into the VM.
But then again I imagine the degenerate case of single dispatch multimethod could be reduced to Java's virtual method call probably.
Hi, I have a couple of Maven dependencies using a variable for versioning ( ${foo.bar} ) - how do I express this in project.clj
using leiningen? Best I could find is “LATEST” and that isn’t necessarily a good solution IMO.
It sounds like it could be easily expressed with boot, but I'm not sure how to do it with lein.
This SO answer sounds plausible - http://stackoverflow.com/questions/15883222/pass-argument-to-leiningen-readable-by-project-clj
@jaen: stuck with lein since it is what I know. Are there many boot projects in the wild? I have never seen one.
There are some projects that use boot certainly - https://github.com/tolitius/mount, https://github.com/mjmeintjes/boot-react-native, https://github.com/Jannis/om-next-kanban-demo - but yeah, it's still less popular than leiningen
I remember @seancorfield recently mentioning moving from lein to boot at work and being pleased.
In addition to ClojureScript tooling I think another place where Boot has advantage is projects with multiple closely tied together artifacts, Boot allows one to write some tasks to build and deploy multiple artifacts from one build.boot: https://github.com/Deraen/less4clj/blob/master/build.boot#L57-L88
No, the jars contain different files
@shriphani: https://github.com/boot-clj/boot/wiki/Community-Tasks https://github.com/boot-clj/boot/wiki/Community-Projects https://github.com/boot-clj/boot/wiki/Blog-Posts
@juhoteperi: which part of the build decides what files go into the jar? I can't seem to find it from a quick glance.
@jaen: with-files
uses a predicate to filter the fileset so that the wrapped tasks only see the selected files
just a quick intro, very new to Clojure coming from years of .NET and RoR web development. Tasked with building a C# .NET application as a Clojure website.
I've got this function I wrote and am wondering if there is some existing solution to this that is more idiomatic?
(defn hashmap-set
[keyvals]
(persistent!
(reduce
(fn [ret [k v]]
(assoc! ret k (conj (get ret k #{}) v)))
(transient {}) keyvals)))
Basically I want to end up with a map whose values are the set of all the values in the original keyvals for the same key.
@jcomplex: out of curiosity - does "C# .NET application as a Clojure website" means you will be doing CLR Clojure or are you moving to JVM?
I see. I thought you might have wanted to leverage the ability to share your C# code between Clojure CLR and the current application.
The only big use of Clojure CLR I've seen is the Unity plugin that lets you use Clojure.
Wondering if I could replace that function using into {} xform
and maybe a custom stateful transducer...
i like to write test driven code and would like to write a test for Monger and also I am trying to get metadata from gridfs
@jcomplex: Can’t help you with that. Never used gridfs. Mostly used it as a json datastore, and for that monger worked perfectly.
@jjconti: #{} is a reader macro that expects a valid set, you should use the set function for conversions (for some more reader macros: https://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/)
Hello - I’m using Korma, but I need to be able to use the clojure.jdbc libs :row-fn capability in my query as well. I was wondering if anyone has a example of using it in the korma dsl syntax.
@jjconti: I seem to recall that you cannot do that for set literals for some reason - can't remember why. But you can do (into #{} [1 1])
Hi there! Does anybody knows how can I implement forEach cycle from Java 8? Context: I do much work with Apache Spark and there are a lot of examples on Scala or Java 8 where forEach method is used. https://github.com/apache/spark/blob/d83c2f9f0b08d6d5d369d9fae04cdb15448e7f0d/core/src/main/java/org/apache/spark/api/java/function/ForeachFunction.java
I need not reinvent similar cycle in clojure but call java 8 forEach from clojure. Thanks.
this might be a basic question can you get the value from an atom that is defined in another namespace?
Right.
So to be exact - you don't really refer to atoms. (atom something)
creates a value which is an reference type with initial value something
. You then have to bind that value to something like (let [my-atom (atom something)] ...)
or (def my-atom (atom something))
.
If you define your atom in another namespace then usual rules to refer to things from other namespaces apply. Atoms are no different from 123
, "magic"
, {:a 12}
or (fn [a] (* 2 a))
in that regard - they are just values that can be bound to names using let
or def
.
@jaen: Yes, so far our switch from Leiningen to Boot has been a big win /cc @shriphani
I think you’ll start to see more projects with build.boot
files — and possibly supporting both Leiningen and Boot.
I’d like to see a boot-template
ecosystem so I might take a shot at a Boot equivalent to lein new
this week…
Doesn’t it? CIDER supports Boot now… I would have expected the refactorings to work on top of that without needing anything specific to change?
Ah, yes, I’d forgotten just how much it can do these days. I don’t know how it would support that for Boot, given that dependencies can be built dynamically via Clojure code (indeed, we store ours in deps.edn
so it can be edited and manipulated independently, because we also "pin" certain libraries to fixed versions — so we’ll "depend" on version x.y.z and the build script will replace that with the actual version we use).
Part of the problem with Leiningen for us was how comparatively static the project.clj
file was (you could escape evaluation in with ~
and we were already doing that in several places).
Hi - I’m using a forward declaration for a private function and am curious; is there any need to tag the function as private inside of declare
?
it looks like it would just be adding the metadata to the declaration (via https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L217), but I’m not sure