This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-12-09
Channels
- # adventofcode (201)
- # bangalore-clj (5)
- # beginners (90)
- # cider (1)
- # cljs-dev (3)
- # cljsrn (28)
- # clojure (128)
- # clojure-argentina (1)
- # clojure-brasil (15)
- # clojure-dev (9)
- # clojure-greece (18)
- # clojure-italy (11)
- # clojure-madison (1)
- # clojure-poland (19)
- # clojure-russia (28)
- # clojure-spec (33)
- # clojure-uk (26)
- # clojurescript (20)
- # core-async (2)
- # cursive (1)
- # datomic (2)
- # emacs (4)
- # figwheel (3)
- # fulcro (15)
- # graphql (7)
- # hoplon (1)
- # lein-figwheel (2)
- # lumo (2)
- # numerical-computing (3)
- # off-topic (9)
- # re-frame (13)
- # ring (1)
- # shadow-cljs (1)
- # unrepl (1)
- # vim (17)
all functions passed to f-> take a single arg (the stack) as input and produces a stack as output
@qqq right but you could imagine something like [a b c ^{:argc 2} str]
as way to tell the compiler to take 2 args from the stack when applying str to it.
(f-> a b c (mod 2 str)), where mod :: int -> func -> func , specifies how many args to take and use
heh, i sometimes wish clojure had that in core. when mapping over a list of lists (for example) i often want something that takes a number n
and function f
and pulls n
many arguments from each list and applies them to the f
rather than writing the function that unpacks the arguments by hand. it’s easy to write but i sometimes i wish i didn’t have to. 🙂
the model I had in mind was: if you get a constant, you push it, if you get a function, you eval it
if your semantics are "if the top element in my stack is a function, apply it", then you have no way of using a function as a value
the model I had in mind for f->
is:
1. f-> gets a list of args
2. eval each arg
3. if arg is a constant, change it to a push
4. if it's a function, apply it
@qqq let me get back to you. 😉 I've gotta play with my kids right now. I will be back to meditate on this some more. 😄
Hi, I just saw the changelog of Clojure 1.9. Do you know why the deps and cli tools were added to the language ? https://clojure.org/guides/deps_and_cli
as far as I understand, this is a new improvement on resolving dependencies, but what about building clojure apps ?
because clojure.core can't run without the clojure.spec.alpha library that is packaged separately
it's not a build tool, it just helps use deps
the goal was that people should be able to run clojure directly using a simple tool from the clojure team - clj is designed for that, and just that
clj isn't mandatory and isn't a build tool
leiningen and boot are still build tools
it doesn't replace leiningen or boot but there are plans to use it from boot at least
I when I begin using clojure, I was confuse about boot and lein. I didn't know if these tool where the interpreter/compiler
that's a common problem
the goal is to have: 1) clj as the main interpreter, 2) deps.edn as a format to specify dependencies 3) boot/lein as build tool
even if you run boot or lein clojure is still the compiler and runs the repl itself
so they might just "wrap" (1) and (2) from boot/lein instead of providing them as they do now
they might - but you can run clojure 1.9 from lein or boot without clj
they might find it useful, but they don't have to address it - everything still works the old way
what's the best way to get the distinct by value of a collection. (?? [[:a 1] [:b 1] [:c 2] [:d 1]]) => [:c 2]
i've got some really gross partition by, filter, first, second, first threading going on
maybe group-by, then test which values are 1 element long?
yeah but it ain't pretty
partitions (->> edges
(map (fn [kid] [(node-weight adjacency kid) kid]))
(group-by first))
[size distinct-edge] (->> partitions
(filter (fn [[p-size nodes]] (= 1 (count nodes))))
first
second
first)
(->> [[:a 1] [:b 1] [:c 2] [:d 1]] (group-by second) (filter (comp #{1} count val)) (first) (val) (first))
it's more fun to write, but there's also #(= 1 (count (val %)))
which performs better
of course
I'm having a strange problem. I'm working on a problem from the advent of code, and I need to copy an input string from the webpage, and transform it into a data structure. A basic (#{:a :b} :a)
comparison was returning nil, which prompted me to take a closer look at the result of the transformation. If I call (transform raw-input-string)
, the printed result looks fine (and in fact, works fine!), but if I compare the printed result to the value returned by the function call (= (transform raw-input-string) <previous result>)
I get false
!
I'm guessing there's some hidden special characters in there, that get dropped when the output is printed into the repl
Is there a way to remove them..? I'm already removing non-breaking spaces, and using trim (which doesn't really do much I guess)
@kauko (clojure.string/replace "your string" #"[^\p{Print}]" "")
or (clojure.string/replace "your string" #"[^\x00-\x00]" "")
with range of characters (replace 00
with proper values)
I tried the first one, I don't think it did anything. I'm probably not going to bother with the second one for now, since I got it working with that hacky file workaround. Appreciate the help though 🙂
I've never "installed Clojure" before (always used lein) but I was curious - is there an update for MacPorts rather than Brew ?
@octo221 https://github.com/macports/macports-ports/blob/master/lang/clojure/Portfile
version 1.8.0
maintainers nomaintainer
@ghsgd2 yeh I was thinking of Clojure 1.9 the latest
oh I see
I’m not sure what that is in MacPorts, but it’s not published by the Clojure core team
Hi, Clojurians! I have a question about Java Interop. I'm trying to translate some of the examples from [web3j](https://docs.web3j.io/getting_started.html#start-sending-requests) into Clojure. The synchronous requests work fine:
// Java
Web3j web3 = Web3j.build(new HttpService());
Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().send();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
; Clojure
(def http (new HttpService))
(def web3j (Web3j/build http))
(-> web3j
(.web3ClientVersion)
(.send)
(.getWeb3ClientVersion))
; "Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.7.3"
But my asychronous requests aren't working, and I think it has something to do with the Java 8 lambdas:
// Java
Web3j web3 = Web3j.build(new HttpService());
web3.web3ClientVersion().observable().subscribe(x -> {
String clientVersion = x.getWeb3ClientVersion();
...
});
; Clojure
(def http (new HttpService))
(def web3j (Web3j/build http))
(defn callback [x]
(println "received value:" x))
(-> web3j
(.web3ClientVersion)
(.observable)
(.subscribe callback))
; CompilerException java.lang.IllegalArgumentException: No matching method found: subscribe for class rx.Observable
The [rx.Observable docs](http://reactivex.io/RxJava/javadoc/index.html?rx/Observable.html) say the subscribe method takes an argument of type Action1, which extends the Action interface, which extends the Function interface.
Any ideas as to what I should be passing to a Java function that expects to receive a lambda?
Thanks!You need to use reify
but I'm not sure which interface it's needed to implement here
java lambdas are just syntactic sugar, at the bytecode level they're equivalent to anonymous classes there's no way to infer a conversion between clojure functions and Rx functions so you have to explicitly pass an instance of Rx expected type Action1
no, they are not anonymous classes https://softwareengineering.stackexchange.com/questions/177879/type-inference-in-java-8/181743#181743
@leonoel After figuring out which class to import (it was rx.functions Action1
), it worked flawlessly! Going to write up a blog post with my adventures when I have something a bit more substantial, and I will give you the credit for helping me out with this one. Thanks for the lesson!
I have a question;
clojure
(list? (cons 'do '((identity x) bla-bla)))
=> false | In Clojure
=> true | In Clojurescript
I always found it sneaky that a cons
returns something that isn’t a list?
in clj. It can trick you in situations like macros. Especially involving syntax quote because you don’t always know when it might return a cons
. So really I end up just avoiding using list?
for these sorts of things (so mostly just never use it)
@mikerod often when you think you want list?
the right predicate is sequential?
though that is true for vectors
Yeah, I think that's a holdover from lisp? @mikerod
Seems like the real predicate is seq?
, and sometimes sequential?
Often, outside of lisps, list?
implies something that has O(1) counting.
@tbaldridge interesting. I’d have to check out something like Common Lisp to compare on that one.
does anybody know of any nice documentation around creating a custom implementation of Spec/Specize from clojure.spec.alpha? I can find one gist in all the web of someone that's attempted it.
it’s not documented because we don’t want to encourage you to do that
in general, you should either be plugging predicates into the specs (use any predicate you like) or combining the things that are provided, which cover the possible data structures appropriately
while I expect the spec api to stay pretty similar, the internals of spec are going to change, so whatever you write is almost certain to be broken. when we consider spec final, there may be more docs at that time on how to create custom spec types.
What's with those new cli tools released with clojure 1.9? What Gap are they trying to fill?
Have you read https://clojure.org/guides/deps_and_cli and https://clojure.org/reference/deps_and_cli ? They try to answer this question.
@alexmiller skimmed . But, are they trying to replace lein/boot?
They do not build or deploy artifacts
They are for building classpaths and launching Clojure programs
Thanks @alexmiller . I'll read it through.
@scknkkrer The answer to your earlier question -- about the difference in behavior of (list? (cons stuff))
in clj and cljs -- is basically due to how the Cons
type is defined on both sides. In clj, (list? thing)
asks if thing
implements IPersistentList
. clj Cons
is java.lang.Cons
, which does not implement that interface, or inherit from anything that does; that's why it returns false on the clj side. In cljs, (list? thing)
asks if thing
"implements" (`satisfies?`) IList
. cljs Cons
is explicitly defined to implement that interface, so it returns true.
@scknkkrer see https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Cons.java#L17 for the definition on the clj side
@scknkkrer https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L3180 for the cljs
@davidrupp good explanation. That brings up something I’ve wondered - why java.lang.Cons
doesn’t impl IPersistentList
@mikerod because IPersistentList is counted and that demands O(1) counting. Cons cells can be lazy and are O(n) counted.
@tbaldridge where in public interface IPersistentList extends Sequential, IPersistentStack
are they counted?
that's it
yeah all the interfaces are O(1), Clojure papers over that with count
in clojure.core
Either way, I guess I’m getting the general idea that a Cons
can be some unbounded lazy thing, where a “list” is expected to not be, I guess
exactly
all that is a bit cleaner in ClojureScript
sideffect of reimplementing the lib
@davidrupp I looked the documentations before but your message is so clear and it helped me to clear some questions on my mind. If you know any tricks like that. Please mesaage me, I am documenting these tricks.