This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-07-30
Channels
- # announcements (6)
- # bangalore-clj (1)
- # beginners (169)
- # boot (8)
- # calva (20)
- # cider (32)
- # clj-kondo (78)
- # cljdoc (42)
- # cljs-dev (4)
- # clojure (126)
- # clojure-china (35)
- # clojure-dev (5)
- # clojure-europe (3)
- # clojure-italy (40)
- # clojure-nl (15)
- # clojure-portugal (1)
- # clojure-spec (4)
- # clojure-uk (67)
- # clojurescript (89)
- # community-development (2)
- # core-async (34)
- # cursive (46)
- # datomic (14)
- # dirac (1)
- # duct (8)
- # emacs (11)
- # events (5)
- # fulcro (21)
- # jackdaw (14)
- # jobs-discuss (6)
- # off-topic (37)
- # pedestal (24)
- # perun (1)
- # quil (3)
- # reagent (27)
- # reitit (1)
- # remote-jobs (1)
- # shadow-cljs (47)
- # sql (1)
- # vim (9)
- # yada (1)
Does anyone know why not=
was chosen over !=
? My brain just decided to ask itself.
I can’t answer with authority, but I would wager a combination of history and consistency. In most lisps that I’ve experienced, (not ...)
is the negation function. Also in most Lisps “!” never carried the meaning of “not” as it does in C language descendants.
I assumed so @cmack, it's just like removing a paren in (not (..
. There was a lot of new syntax in Clojure however, compared to other lisps.
not necessarily
there is no "edn safe" printing path
https://ask.clojure.org/index.php/1905/there-should-also-be-writing-in-clojure-edn if you want to vote for something
this is a common problem and it doesn't have a good general solution, really it's up to you to ensure you have data that will print to valid readable edn right now
but it seems like something that should have a better answer
yeah. I’m working on a REBL-like app for CLJS, but it requires sending/receiving the datafied form over a wire. not having a reliable way of ensuring something that a user application tap>
s out can be read on the other side is rough
specifically, I had a hugely nested map with a Reagent RAtom like:
{:current-state #<Atom: 111, ...>}
which took a bit of time to troubleshoot. I couldn’t figure out how to get the reader to tell me what form it couldn’t read, eitherwell you shouldn't have that problem in Clojure, as it will fall back to an #object tagged literal (which is still readable!)
so that might be something to change in cljs
I think the issue is that the implementation of -pr-writer
for the reagent.ratom/RAtom
type writes out #<Atom: something>
, which isn't readable
I'm currently calling pr-str
on the whole data structure to as a way to "write" the EDN
it sounds like you're saying that the behavior on the JVM would ignore this implementation and print #object[reagent.ratom/RAtom]
, or I'm using the wrong tool (`pr-str`) to do this?
more specifically, print-method is defined on Object to print in a readable way
Clojure used to print objects without a printer in an unreadable way but we changed that in Clojure 1.6 (iirc)
and cljs could do the same
but if the object has their own implementation of printing, that doesn't apply, right?
this is the fallthrough if no print is defined
user=> *ns*
#object[clojure.lang.Namespace 0x51b01960 "user"]
there is no reader defined for #object, but you can install a default-data-reader-fn to use the built-in tagged-literal
function as a reader
so for my case, the issue is the way Reagent implements printing on their custom atom type. but also that there's nothing that really says that printing should be valid EDN anyway
well #<Atom: 111, ...>
above is not readable
well I'd say it's generally bad to print in a way you know won't be printable
so whoever is doing that shouldn't imo :)
or there should be something additional being done to install a print-method
not sure which is appropriate here
but atoms are a good case where it's probably possible to print something, but is that useful to you?
I'm not sure how useful printing just an atom is for me, except that it happens to be a part of a larger structure that I want to inspect
if you have a stateful atom and print it to a string, does it make any sense to reconstitute it back into an object later when other objects can no longer refer to it
if you're just inspecting, then you probably don't care
atm, I just want to make it passably readable. it doesn't need to hydrate it into an actual atom; just using the default tagged-literal
would be enough for me
hydrating atoms could be useful for saving to disk and then resuming application state on startup, but not something I'm worried about atm
Would a multimethod be faster than the following:
(defn execute-on-type [type x y z]
(case type
:foo (execute-foo x y z)
:bar (execute-bar x y z)))
it would be slower, but it's extensible to new keys without changing its code
multimethods are definitely not there for performance
well with a keyword type, probably multimethods are better
you could make a placeholder type, but it would be clumsy yeah
Assuming there is some requirement to stick with keywords - it just seemed like type based dispatch to me
eyeballing the code for how case vs multimethod are implemented, I think you'll find multimethod to be a little slower, but it will be easier to extend. (case) can use hashing to run against pre-calculated values, whereas best case you get with multimethod is a pass on the initial (=) check in (isa?). I would prefer the multimethod for its easier extensibility (were I on the project).
also case doesn't do the var indirection that multimethods do
which can effect how things can inline when the JIT kicks in
as usual, use appropriate skepticism with microbenchmarks
right - but the initial question was a microbenchmark question (is this dispatch faster than this other one)
http://insideclojure.org/2015/04/27/poly-perf/ <-- blog older than repo timings

but general commentary still valid
Given that (according to the blog) the greater the variety in your uses the less the margin gets, I would be really disinclined to write using (case)
You're also on the order of micro-optimizations here where you're better served by readability.
does anybody know the best way to launch a clojure repl within clojure? I want to make my clojure program into an uberjar that, when run, just dumps the user into a clojure repl in my module and prints a little help message.
start clojure.main as your init class
well maybe I can load my own module, then have it call the thing in clojure.main that launches a repl
Probably, and that's probably what you'll want to actually do anyway since you will want to do setup stuff for the user on startup (like read a config file, do your (requires), etc).
or if you require your module, when clojure.main starts your module will be preloaded - I think there's a way to select the ns clojure.main starts in as well
yeah - It would be more like -i "(doto 'my.ns require in-ns)"
if the -i effects the repl itself
and maybe also -e
for any prep code that shouldn't be run at the top level of that ns
or -i
https://github.com/nrepl/nrepl/blob/master/src/clojure/nrepl/middleware/interruptible_eval.clj#L79
this is what clj
/ clojure
are using also, you could potentially leverage those depending on what you are doing
oh yeah clojure.main/repl
looks easiest, thanks @dpsutton. Now i have to figure out how to exit the one I just launched inside of my repl in emacs...
(exit) is an nrepl feature
control-d makes the repl process stop
(System/exit 0) makes the vm gracefully exit
control-c will also make the repl stop, and shut down the vm, unless you set up a signal handler like nrepl does
oh thanks, I'll just add my own exit
function that calls (System/exit 0)
so the users can exit easily
that's the secret behind the interruptible-eval
function @dpsutton linked to actually - in the big picture it's part of machinery that links a thread you can kill to a signal handler to kill that thread instead of your vm
something I literally used today at work: $ env $(grep -v '#' .env) rlwrap java -cp $(cat class-path) clojure.main
- the class-path file was generated via a previous run of lein with-profile +repl cp
this gives me a repl with all the same definitions and config as my lein / nrepl but without any leiningen or nrepl code running, just clojure.main plus my own code I explicitly run (all this done in order to have a cleaner set of stack traces for a tricky stalling issue)
turned out I was eagerly consuming a lazy-seq backed by a network stream that wasn't receiving input
with nrepl, 9/10 of the stack trace data from jstack
was either leiningen or nrepl code / threads; removing that made finding the real problem much easier
of course I would have the same result out of the box if the project was using clj :D
the :author
field is commonly used on namespaces. is it also used on vars? and why not :authors
?
:author is common in clojure contrib namespaces, I am not sure it is common outside of those, it definitely isn't used in the closed source clojure code I've worked on
I suspect it is :author instead of :authors, because as a feature it wasn't really designed, someone thought "oh, namespaces can have metadata, neat, I'll attach some" and they just picked :author, and others just copied it along
:author in clojure contrib is likely from back when contrib was in svn as a single repo, so without it it was hard to figure out who "owned" a given source file
apparently its use did not catch on like wildfire
my guess is the usage in clojure itself fall in to two camps: projects that moved from contrib in to core (I think this is just clojure.test) and places where stu came along and added it, which I dunno if he was inspired by the usage in contrib, or contrib was inspired by him there
it's kind of important in https://github.com/weavejester/integrant
https://github.com/clojure/clojure/commit/76e7c4317dc3eac80c4908ac5e5fb885e302b2a4 oh, stuartsierra, I had the wrong stu
@emccue the same case as concrete inheritance in eg. java, except not only do you define where implementations are derived from, but also the derivation rules on a method-by-method basis
I've never found it useful in practice myself
https://github.com/clojure/clojure-contrib/commit/b0179b612c0fc7dcc9a4e4115bbbfb1330442109 appears to be the first :author tag in contrib, looks like it was added for the autodoc tool that is used to generate documentation
so it exists for a tool that is used to generate docs for http://clojure.org
@noisesmith yeah but with concrete inheritance in java you maintain method compatability or are ostensibly guaranteed a subset of fields/slots
right - it's not a similar mechanism, but has some of the same justifications / use cases
it's the only real form of inheritance clojure offers beyond mucky stuff in gen-class
(and the weird/buggy proxy-super)