This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-10-07
Channels
- # aleph (1)
- # announcements (2)
- # babashka (1)
- # beginners (49)
- # calva (1)
- # cider (5)
- # clj-kondo (14)
- # cljdoc (11)
- # cljsrn (6)
- # clojure (120)
- # clojure-austin (1)
- # clojure-europe (6)
- # clojure-finland (3)
- # clojure-italy (29)
- # clojure-nl (6)
- # clojure-spec (38)
- # clojure-uk (14)
- # clojurescript (65)
- # code-reviews (8)
- # cursive (20)
- # data-science (1)
- # datascript (5)
- # datomic (57)
- # emacs (6)
- # figwheel-main (2)
- # fulcro (32)
- # funcool (1)
- # jackdaw (7)
- # jobs (3)
- # joker (7)
- # kaocha (8)
- # keechma (3)
- # nrepl (7)
- # off-topic (25)
- # quil (3)
- # re-frame (10)
- # reagent (43)
- # remote-jobs (1)
- # ring (1)
- # shadow-cljs (173)
- # sim-testing (1)
- # spacemacs (1)
- # sql (3)
- # tools-deps (34)
Can you just up-arrow/ctrl-r/m-p through your history?
@kulminaator source
is implemented to look up the source file containing the code and extract it. it's not designed to find repl created fns
I have made this simple desktop wallpaper. Helps me keep focused on studying clojure. Enjoy!
I have a cljc
file where I do #?(:cljs (:import goog.string.StringBuffer))
and then later use that as a replacement for StringBuilder
. However, I have a type hint in the arguments box of a function where I send an instance of this. Like so:
(defn- foo [ast ^StringBuilder string-builder] ...
Things work, but it feels like I could be tripping up the ClojureScript compiler this way… Any ideas what I could do about it?No, it won't, you can't use reader tags for metadata like that – you'll get a parse error about how the tag does not apply to anything (or something like that). You'd need to something like #?(:clj ^StringBuilder string-builder :cljs string-builder)
Howdy! Anyone ever built a duo out of a rust binary and a clojure uberjar? I’m interested how would one ship that into [canary] production [without Docker if possible].
You might wanna take a look at the embedded java postgres builds on top of. It's a java library for running binaries. I forget what it's called.
@U1SPRM8LE cool, thanks for a lead!
Yandex has a pg which uses https://github.com/flapdoodle-oss/de.flapdoodle.embed.process
yeah, thanks mate! They all seem to be a provisioning wrapper around a bundled binary. Which is a way to go.
Which is the main program, the Rust binary or the Clojure jar? If the Rust binary is the main program you can just use JNI from Rust to load the JVM shared library, provide an interop interface between the languages and start your Clojure code. JNI works the other way around too if the Rust binary is a shared library. https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html
If you are concerned about packaging: 1. If the Rust binary is a library it can be packaged in the Clojure jar as a resource, unpacked at runtime and loaded with System.load. 2. If the Rust binary is the main program... I don't know. I have very little Rust knowledge. But theoretically you can always bundle resources inside any executable file so it should be possible to have a single file distribution for that too.
@dominicm You mean by using the language interop features? Or did you think about native image? I don't think native image supports actually having compiled LLVM code as a guest language so even if you can compile the Clojure jar to an executable the Rust code might run slow when called in that scenario.
But if you are running on the GraalVM and not native image SubstrateVM then it might be plenty fast and probably an easier option than my suggestions.
Yeah. That is why I mentioned packaging a library as a resource and native image. The deployment is usually the issue and native binaries or at least having a single jar makes that much easier. I would love to be able to deploy a single executable with many languages in it. Hoping for an improvement in native image for that.
@U89UL6P9P the jar is the main one. Rust bin is a slave server. They talk via websocket. So I think the about packing the bin into a jar as a resource yes, as a start. Thanks!
@miikka, @dominicm: The first thing I tried was to just conditional the hint. That didn’t work and I ran out of ideas. 😃 The latter suggestion works great. Thanks!
Huh, I didn't realize that the metadata reader worked as a group not as an individual thing.
Yeah... It makes sense to me in the code-is-just-data sense but it's super annoying when you have to conditionally tag a lot of forms.
Which mechanism of polymorphism do you use most in UI? I tend to prefer multi methods, because they feel more natural, but maybe I get it wrong? I try to avoid giving functions as parameter in the rendering function, but am I mistaking?
(print-table [ {:a {:b 1 :c 2} :d 3} {:a {:b 4 :c 5} :d 6} ] [ [:a :c] :d] ) Result would be :a :c + :d +++++++++++++++ 2 + 3 5 + 6
I don't know the answer to your question. You may have already considered this, but you could write a function that creates a new map from your existing one, and then call print-table on that?
@andy.fingerhut Yes I am considering that.
The normal Clojure print-table might also work with a key of the form [:a :c]
-- worth a test, anyway if the output from that meets your needs.
For example, the current print-table implementation can already do this:
user=> (pp/print-table [[:a :c] :d] [ {[:a :c] 2 :d 3} {[:a :c] 5 :d 6}])
| [:a :c] | :d |
|---------+----|
| 2 | 3 |
| 5 | 6 |
Keys in maps can be arbitrary Clojure collections.
As far as other 3rd party libs for printing tabular data, I am aware of these two, but not whether they already do what you want. You might want to scan the examples in their docs to check: https://github.com/cldwalker/table https://github.com/joegallo/doric
(clojure.pprint/print-table [:a [:c :d]]
[ {:a 1 :b 2 :c {:d 3}}
{:a 4 :b 5 :c {:d 6}} ]
)
Right, that doesn't already do what you want, but if the map were manipulated via some other code to produce one that had keys [:c :d]
with the values you wanted to see in the table, then calling print-table on that modified map would print what you want.
Thanks @andy.fingerhut
cool. Check out the small set of functions in namespace clojure.set for some that may be useful for what you are doing. They are pretty basic.
Wrote a lib recently to leverage spec for a looser form of multimethods. It's part idea-sketch, part pun, part maybe useful? See code examples in tests. https://github.com/den1k/defmostly
When using multimethods is it always required that an implementation namespace is required at some stage? I have a few multimethods which spread their defmethod
implementations over several namespaces and I am finding (rather annoyingly) that these need to be required before use otherwise the dispatch clause simply will not be found. I haven't tried this in a running jar yet, only in testing/REPL but I am finding this to rather limit the openness/extensibility in that I need to be aware of the callpoints of the multimethod to make sure that the clause has been actually added to the system.
Does the same happen when one compiles this down to an uberjar or is it enough then to simply require the namespace that holds the defmulti
declaration?
Thought as much. I wonder if given this it is better to simply place all the dispatch clauses in the same namespace as the multimethod declaration - that way, it's just one import away. How do folk usually do it here - single or multiple implementation namespaces for multimethods?
I don't use multimethods a ton, but in the past my conclusion was the way to structure things is as a diamond shape: namespace spi contains the defmulti, namespaces impl1 and impl2 require spi and contain defmethods, namespace interface requires impl1 and impl2 and defn's a wrapper around the defmulti
the diamond shape gives you a place to require all the implementations and also avoids circular dependency issues people stumble into with multimethods
depends on the use case. if you are using multimethods primarily to create a fixed set of polymorphic behaviors, then putting them all in the same place is easiest. if it's designed to be an open system, then it might make more sense to rely on some higher level of control to know how to declare the method and say which namespaces to load.
and agreed on the @hiredman's structure
What kind of higher level of control do you mean @alexmiller?
someone that is deciding what to load
either a fixed set of ns'es or possibly even an open set defined in config
I've done that with multimethods too, defining basically an interface as a group of multimethods and having some kind of config file that says which implementation of that interface to use and which namespace to load to get it
So either application specific (config.edn), or deriving implementation from keyword namespace (like integrant)?
I think, for that kind of plugin thing I was doing then with multimethods, I would prefer a protocol now
Would be nice to have something in core, for libraries to load their extensions automatically if they're entirely about multi methods. But could be fixed in user space if library authors defining the multi methods could be brought on board.
Are you talking about a set of methods in a single library or open set? If the former, that seems like a lot of complexity for something with a current simple solution. If the latter, how do you know where the extensions are?
No, the latter. A "blessed" solution. I think something like data_readers.clj but for indicating multimethod extensions could work, although it would be duplicative of what's there.
Java actually has a way to do this now via service loaders
really as a way of finding implementations of an interface
uses manifest annotations
yeah, I mean the mechanism and constraints are a bit different, but same idea
https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html
by the way, Ruby/Rails has this via the Gemfile's require: false
option. In clojure, this would correspond to setting a flag on a dependency vector's metadata.
And it also has initialization order problems lol
it doesn't seem like the gemfile require thing is the same thing
seems like that's at the library/module level and we're talking about the ns level
there are things like this already (provided or optional scope in maven for example)
I assumed that the gemfile manifest indicated which modules to load. Maybe I'm wrong.
https://stackoverflow.com/questions/4800721/what-does-require-false-in-gemfile-mean yes
Now that protocols can be attached to data, I also quite like the idea of using protocols.
multimethods and protocols both have the same issue of loading extensions, so I'm not sure it makes a difference
Some good tips here. True about protocols having the same issue, but that is typically something that I don't tend to hit as I tend to only have two implementations of any given protocol, but several dispatch clauses for a multimethod.
Hi. I'm trying to type hint a HashMap<String, byte[]>. How can I do that ? I'm doing this because Clojure's automatically picks the wrong static method (same method name, also accepts a HashMap, but with keys of a different type).
generics are mostly a fiction of javac, they only exist as an annotation in the bytecode, which most code never looks at
clojure type hints don't do generics at all
(they can hint ^HashMap but not the specialization)
can Java even do what you're describing? two methods that differ only in the generics?
can you point to public javadoc or anything?
yes you're right, my bad, they do differ by name, I guess I rushed and misinterpreted the error I got, sorry.
(if-let [{:keys [x y z]} {:not "what ~you~ i expect"}] "yep" "nope")
always bites me. (evals to "yep")maybe it makes sense if you think like (if-let [[x y] some-vector)
vs (if-let [[x y] nil)
might help looking at macro expanded too:
(let*
[temp__5718__auto__ {:not "what you expect"}]
(if temp__5718__auto__
(let*
[map__64993
temp__5718__auto__
map__64993
(if (clojure.core/seq? map__64993)
(. clojure.lang.PersistentHashMap
create
(clojure.core/seq map__64993))
map__64993)
x
(clojure.core/get map__64993 :x)
y
(clojure.core/get map__64993 :y)
z
(clojure.core/get map__64993 :z)]
"yep")
"nope"))
👼 if i'd find code that looks like that written by me i would just delete it and write it again ... (regarding that if-let from above)
too old to puzzle around complicated blocks
anyway i must not be the only one because it was a pattern i found in code contributed to an open source project i maintain. fooled us both 🙂
rewritten:
(let [{:keys [x y z]} {:not "what you expect"}]
(if (and x y z)
"yep" "nope"))
What library would y'all recommend for HTML parsing?
Thanks! Works great