This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-29
Channels
- # aws (1)
- # beginners (78)
- # boot (27)
- # cider (16)
- # clara (15)
- # cljs-dev (84)
- # cljsjs (13)
- # cljsrn (19)
- # clojure (65)
- # clojure-france (10)
- # clojure-italy (8)
- # clojure-russia (35)
- # clojure-spec (34)
- # clojure-uk (124)
- # clojurescript (50)
- # clojutre (3)
- # core-async (16)
- # data-science (18)
- # datascript (1)
- # datomic (9)
- # emacs (2)
- # flambo (3)
- # fulcro (55)
- # graphql (3)
- # hoplon (4)
- # jobs (2)
- # juxt (21)
- # keechma (6)
- # lumo (73)
- # off-topic (4)
- # om (10)
- # onyx (5)
- # parinfer (1)
- # pedestal (3)
- # re-frame (60)
- # reagent (19)
- # specter (24)
#(into (empty %1) (distinct) (conj %1 %2))
is useful, I guess it’s not in core because when you need it it has bad algorithmic complexity
I guess it could be replaced with an insertion ordered set
is there a line counting program that counts number of functions? (something slightly more advanced than grepping for defn)
I guess def is both binding and assignment, because it implicitly wraps the value in a Var and assign the var a new value if called where a binding for the symbol already existed.
And I guess set! was made to not work on global vars because it wouldn't be atomic and could cause concurrency issues? So instead alter-var-root! was introduced as an atomic way to assign to the root of a global var?
And why wasn't set! used for atoms, when it is used for refs, agents and dynamic vars?
Hum, then the doc is misleading:
Only Java fields, Vars, Refs and Agents are mutable in
Clojure. See for more information.
It kond of imply set! Can be used for assignment to all mutable things, and that only vars, refs and agents are mutable.
set! works with :
- dynamic vars, only if the current thread is running inside a binding block involving this var
- public, non-final fields of java objects
- deftype fields, only if tagged as :unsynchronized-mutable or :volatile-mutable and only if called in the body of a method
- flags defined in clojure.core such as *warn-on-reflection*
etc
I can't speak for the language designers, but my guess is that assignment doesn't really mean anything in multithreaded context because there is a bunch of strategies that can be used to make a mutation visible to other threads - static vars use locks - dynamic vars use a mix of ThreadLocal and volatile - refs rely on STM which ultimately uses locks - atoms use CAS - agents use Executors
TIL the reason why set!
works with compiler flags : it's not a special treatment, it's because they're dynamic and they're bound by the compiler itself when the namespace is evaluated
Ya, just would have been nice for set! to be polymorphic on all those, instead of each having its unique method to do assignment.
(map list [:a :b :c] [:x :y :z :w])
;; or
(partition 2 (interleave [:a :b :c] [:x :y :z :w]))))
;; ?
vararg map-indexed
(map list (range) [:a :b :c] [:x :y :z :w])
=> ((0 :a :x) (1 :b :y) (2 :c :z))
to re-define a multmethod (the dispatch function), am I forced to ns-unmap
first? If I do not the multimethod does not seem to be updated
@hmaurer I believe this is one of the cases where a redefine doesn't just work. Highly recommend using tools.namespace to reload your code.
@hmaurer there is remove-method
and remove-all-methods
If I have preconditions on a multimethod, where should I put them? On the dispatch function?
it depends, is it a precondition that underlies the multimethod itself, or is it specific to some dispatch?
Trying to port a third-party API to Clojure. API was originally written in C, vendor has packaged this as JNI, providing Java API. Vendor's java bin
directory includes .jar
, .dll
, and .lib
files.
I am new to Clojure (longtime Common Lisper), have no real Java background. I got some help on #beginners a while back (https://clojurians-log.clojureverse.org/beginners/2017-08-05.html --- thanks, @noisesmith) but am still stuck. I haven't found a Clojure use case like this by Googling---just on Java-only JARs or on building a JNI from scratch and using that.
I am using lein and CIDER on Windows.
My defproject
form now includes the following.
:jvm-opts ["-Djava.library.path=c:/NeticaJ_Win/NeticaJ_504/bin/"]
:resource-paths ["c:/NeticaJ_Win/NeticaJ_504/bin/NeticaJ.jar"]
My ns
form includes...
(:import [norsys.netica.Environ]
[]
[norsys.neticaEx.aliases.Node])
I am getting errors like this:
edit-server.core> norsys.netica/Environ
CompilerException java.lang.ClassNotFoundException: norsys.netica, compiling:(*cider-repl edit-server*:1:7209)
edit-server.core> (norsys.netica/Environ. nil)
ClassNotFoundException norsys.netica java.net.URLClassLoader.findClass (URLClassLoader.java:381)
Thanks for any insight.norsys.netica/Environ isn’t valid
it would be Environ with those imports
though norsys.netica.Environ is also allowed
Is it possible to have underscores for readability in numeric literals? E.g. 1_000_000
As far as I know Java has this, but clojure throws a number format exception.
it is not a valid number format for clojure
It’s really hard for me to read numbers like this 100000
especially when they get bigger.
Could I do something about it?
=> (long 1e+6)
1000000
this worksthough that means an extra conversion and if your not careful it might do the conversion at runtime instead of compile time
I can live with that, thank you.
there’s also 1e+6M
which is a java.math.BigDecimal
@noisesmith That helps, thanks! Still a DLL issue, though:
edit-server.core> (norsys.netica.Environ. nil)
UnsatisfiedLinkError C:\NeticaJ_Win\NeticaJ_504\bin\NeticaJ.dll: Can't find dependent libraries java.lang.ClassLoader$NativeLibrary.load (ClassLoader.java:-2)
edit-server.core>
yeah, sounds like you need to fix your path for native libs, but that’s something I don’t have much experience with
do you have a sample java command line that is supposed to work with that lib?
Which of these would be more clojury and/or efficient? (into {} (map (fn [k] [(str k) {}]) some-seq))
or (zipmap (map str some-seq) (repeat {}))
?
I was wondering, since the (zipmap (map ...) ...)
appears to iterate twice over some-seq
.
I tend to use juxt
when I use (into {} ..)
(into {} (map (juxt str (constantly {}))) some-seq)
> (transduce (map str) (completing #(assoc! % %2 {}) persistent!) (transient {}) [1 2 3 4])
{"1" {}, "2" {}, "3" {}, "4" {}}
- fixed@noisesmith Vendor instructions to run demo are to run two batch files, in order, from demo
directory. Contents follow.
1:
"C:\Program Files\Java\jdk1.8.0_131\bin\javac.exe" -deprecation -classpath ..\bin\NeticaJ.jar *.java
2: set PATH=..\bin;%PATH%
java -classpath .;..\bin\NeticaJ.jar -Djava.library.path=..\bin Demo
Results:
1: New file Demo.class
.
2: Demo runs fine.
I've been trying to execute my translation of a form in Demo.java
--- new Environ (null);
--- as (norsys.netica.Environ. nil)
.that is the right translation, yes - you should be able to run the exact same commands except pointing to clojure.jar instead of the java files (plus a file running the clojure code you need)
@urzds no because there’s no consensus on what it would do if the key is already missing
(it’s discussed on Jira somewhere…)
@noisesmith Instead of using lein, defproject?
no no I’m saying using java - then when you find what works translate to lein
fundamentally, lein is a tool for managing java deps, so when your java deps are such that lein can’t manage them, you can skip lein.
java -classpath clojure.jar;..\binNeticaJ.jar;src -Djava.library.path=..\bin clojure.main some.clojure.ns
if src
is the dir with your clojure code in it that is
(fix to point to the actual location of a clojure.jar, or copy a clojure.jar to the current ns)
Found the missing dissoc-in
task in JIRA: https://dev.clojure.org/jira/browse/CLJ-1063
@noisesmith Thanks, will try.
@bschrag also you can leave off the namespace arg and just get a bare repl (no line editing and no namespaces pre-required though)
@noisesmith I gather that your some.clojure.ns
plays the role of "script" in documentation from clojure.main --help
:
. For this, I might use my core.clj
, including the ns
form?
no, it’s a namespace arg to clojure.main - I think I forgot the -m
that needs to go before that; so just a string is a file name, -m
is the namespace to find and run (based on classpath) and -e
is just code to eval
@bschrag btw this works
$ java -jar ~/bin/clojure.jar --help
Usage: java -cp clojure.jar clojure.main [init-opt*] [main-opt] [arg*]
With no options or args, runs an interactive Read-Eval-Print Loop
init options:
-i, --init path Load a file or resource
-e, --eval string Evaluate expressions in string; print non-nil values
main options:
-m, --main ns-name Call the -main function from a namespace with args
-r, --repl Run a repl
path Run a script from a file or resource
- Run a script from standard input
-h, -?, --help Print this help message and exit
operation:
- Establishes thread-local bindings for commonly set!-able vars
- Enters the user namespace
- Binds *command-line-args* to a seq of strings containing command line
args that appear after any main option
- Runs all init options in order
- Calls a -main function or runs a repl or script if requested
The init options may be repeated and mixed freely, but must appear before
any main option. The appearance of any eval option before running a repl
suppresses the usual repl greeting message: "Clojure ~(clojure-version)".
Paths may be absolute or relative in the filesystem or relative to
classpath. Classpath-relative paths have prefix of @ or @/
@noisesmith This works (!):
c:\NeticaJ_Win\NeticaJ_504\demo>java -classpath C:\Users\Schrag\.m2\repository\org\clojure\clojure\1.8.0\clojure-1.8.0.jar;c:\NeticaJ_Win\NeticaJ_504\bin\NeticaJ.jar -Djava.library.path=c:\NeticaJ_Win\NeticaJ_504\bin clojure.main
java -classpath C:\Users\Schrag\.m2\repository\org\clojure\clojure\1.8.0\clojure-1.8.0.jar;c:\NeticaJ_Win\NeticaJ_504\bin\NeticaJ.jar -Djava.library.path=c:\NeticaJ_Win\NeticaJ_504\bin clojure.main
Clojure 1.8.0
user=> (norsys.netica.Environ. nil)
#object[norsys.netica.Environ 0x6ca18a14 "norsys.netica.Environ@6ca18a14"]
user=>
Any idea about how to get the same effect with lein?the string you give to classpath can go in :resource-paths and the -D… can go in :jvm-opts I think - you might need a ^:replace
prefix on the jvm-opts value
but I bet there’s something more elegant that lets you leverage the maven ecosystem properly (I’m not super good at the library.path stuff though…)