This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-17
Channels
- # bangalore-clj (4)
- # beginners (60)
- # boot (63)
- # cider (2)
- # cljs-dev (22)
- # cljsrn (3)
- # clojars (32)
- # clojure (133)
- # clojure-gamedev (1)
- # clojure-germany (17)
- # clojure-italy (1)
- # clojure-russia (11)
- # clojure-serbia (16)
- # clojure-spec (35)
- # clojure-uk (75)
- # clojurebridge (1)
- # clojurescript (83)
- # community-development (25)
- # core-async (43)
- # cursive (15)
- # datomic (28)
- # emacs (2)
- # fulcro (108)
- # graphql (5)
- # hoplon (15)
- # lein-figwheel (6)
- # leiningen (39)
- # lumo (106)
- # new-channels (1)
- # off-topic (4)
- # om (26)
- # om-next (53)
- # onyx (46)
- # other-languages (2)
- # perun (1)
- # protorepl (5)
- # re-frame (13)
- # ring (18)
- # ring-swagger (1)
- # rum (6)
- # shadow-cljs (82)
- # spacemacs (19)
- # specter (5)
- # sql (3)
- # test-check (31)
- # unrepl (12)
- # untangled (2)
- # vim (109)
@rcolyer sorry to hear about RSI đ I've owned those mentioned Microsoft and Kinesis in the past (circa 2011). I found them dangerously misleading - I've used Apple keyboards since 2013 - zero pain now, zero contortions (un-natural movements)
I have used Emacs this whole time. It hasn't been a factor of pain, given that since day one I rejected the emacsy way of using the keyboard. all my shortcuts are in the form: command-s ctrl-a alt-e etc. simple stuff. particularly good that one can use three modifiers easily, in Mac
you may read a little about my approach (and my real list of shortcuts) in https://github.com/vemv/.emacs.d . my config is not shareable as of today, but I'm working towards that. anyone interested can ping me
--- in general I think I have quite a story to tell, about how I beat wrist pain. Like, it really hurted a few years ago, felt how my career was at risk. did lots of research and found some really good advice buried in a sea of workarounds. as a sad trivia, the only people I've ever met with RSI (or similar) were clojure programmers. and I couldn't really share my advice with them, because normally you can't tell people they're just wrong
--- this "good advice" is a bit complex to tldr, I guess I could record a 20m video for anyone interested
is there a way to alias a namespace without requiring it?
Maybe clojure.core/alias can do that? Not sure.
e.g. (alias 'str 'clojure.string) followed by (doc str/join) gives docs for clojure.string/join
thatâs a red herring - clojure.string is loaded during startup. alias requires the namespace to be loaded to be able to alias it. So the answer to the original question is no. But you can work around that with a call to create-ns
first
I have a naming question. I am genuinely tempted to mix camelCase with - . Here is the problem> Suppose I have an object, say update-event then, I have other functions: update-event-new update-event-process update-event-do-foo-bar but then it's not clear to me where the "noun" and the "verb" are separated. Whereas, if I named my event updateEvent then I ca ndo updateEvent-new updateEvent-process updateEvent-doFooBar however, Clojure seems to uniformly dislike camelCase
Clojure doesnât care what you do, but other people might :)
why do you need to repeat âupdateEventâ in all those names?
it seems like the Protocol naming convention sets precedence that it's 'okay to have camelCase for multi word nouns"
protocols create Java interfaces under the hood so they steal Java style naming
or at least many people follow that
you only really refer to protocols by name when you implement them though
most clojurists do not use camelCase for nouns, they use kebab case
I have a lot of functions of type signature verb :: foobar -> ... -> ... -> ... -> foobar so I like to have functions of name foobar-verb1 foobar-verb2 foobar-verb3 when 'foobar' and 'verbi' both contain dashes, I find it awkward to read
that seems more verbose than most clojure code
why not just (defn verb1 [foobar])
https://stuartsierra.com/2016/01/09/how-to-name-clojure-functions has a lot of good advice
@alexmiller: the suggestion there seems to be lots of small namespaces, and not repeat namespace name
I like his suggestions
I don't think I've ever used camelCase in Clojure
I also prefer verbs in front
like a command/imperative
but when I see what you've written above, the first thing that pops into my head is "that's a namespace"
that is, a common prefix for top-level definition names
but the nice thing is it splits the two pieces with a different character, /
that could solve the readability issue you're having
I think I'd solve it how the CSS people do: update-event--new
. But I'd also avoid this problem in the first place by not doing this.
I'm writing some "scripts" that will help to check a few things like status of database tables or marathon tasks for example
the scripts now simply do log/error
on errors and log/info
otherwise, however it would be also nice to keep track of all the errors in a data structure
(which is computed across different functions), and exit with failure Exit code in case anything failed
any suggestions about how to do that?
the easiest way would be to use an atom
maybe, but it would have to be shared across different namespaces or being passed in from core.clj
Hi guys I need your help.
I want to make a clojure query, but the :where conditions are condition. SO i used cond->.
this works well. but now my problem is that I want to make a clojure function call inside a (â) or quote.
(defn foo [num]
(inc num))
(def query â[:find ?e
:in $
:where ])
(cond-> query
(some-condition)
(conj â[? :data/number ?number])
(some-other-condition)
(conj `[â(> ?number (foo 2))]))
I get this result:
[:find ?e
:in $
:where [? :data/number ?number]
[(> ?number (clojure.core/unquote (foo 2)))]]
What I am trying to achieve is this:
[:find ?e
:in $
:where [? :data/number ?number]
[(> ?number 3)]]
Can anyone please help
This will work:
(cond-> query
(some-condition)
(conj '[? :data/number ?number])
(some-other-condition)
(conj `[(~'> ~'?number ~(foo 2))]))
You could write a little helper function to make this easier though.
;; NB: Only use this when you specifically want a list (ie. code).
;; Normally prefer using conj on a vector.
(defn append [coll & xs]
(concat coll xs))
(cond-> query
(some-condition)
;; This is probably supposed to be ?e and not just ?
(conj '[?e :data/number ?number])
(some-other-condition)
(conj [(append '(> ?number) (foo 2))]))
In clojure I do same transformation to the var and then want to store the result by same name. Is this ok to do so? I don't want to invent new var names for this. Eg. (let [address (cleanup address)] address)
That's fine. It's a local though, and not a var. Vars are the things that def
and defn
create at the top level. You shouldn't define those more that once (except at the repl, when developing).
why do i get an invalid number exception for 0x1.0p-53
?
but it works in java
clojure docs say "As of version 1.3, Clojure provides full support for JVM primitive values, making it possible to write high performance, idiomatic Clojure code for numeric applications."
so if it did accept more literals for primitives, you wouldn't say that support for primitives has been improved?
Feel free to file a ticket - Java has added stuff over the years and I donât see any reason we shouldnât track their literal
Hi everyone, I have an interview coming up for which the recruiter told me to prepare for datastructures questions. I know I should review them, but I'm loathed to learn about mutable versions as I never use them anymore đ Id much rather learn about immutable implementations so that at least its relevant to my interests. How come there are so many tutorials for mutable but not immutable datastructures
Moreover, its actually not natural to create a mutable datastructure in clojure i find
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java#L18-L26
Thanks @nha looks good
I'm thinking more along the lines of if asked to implement a binary tree, how would i implement a persistant version
https://www.codewars.com/kata/functional-binary-trees I think that was the exercise
This looks great đ
i wish there were more like this
but yes this is the sort of thing im looking for
Hello! Are there libraries that manipulate plain datastructures in the fashion of Datomic pull syntax?
I saw this, but seems not quite alive
Thanks!
3 days ago, @fabrao and @reborg had an exchange about transduce-ing a transformation. I found the exchange interesting and helpful for learning transducers, and I thought it might be useful to stick it somewhere more enduring than this Slack channel. So, with their permission, I wrote it up and posted it to StackOverflow [1]. One of the side benefits is to have more Clojure content on StackOverflow, which will help us look better next time they analyze languages. I welcome others to similarly capture interesting or useful content from here to StackOverflow. (Or even go the other way and post a question there first, linking to it here.) Totally voluntary, of course, but I think it might benefit our broader community. Cheers! [1] https://stackoverflow.com/q/47358416/202292
Starting to like transducers are lot now: https://stackoverflow.com/a/47354316/6264
Iâm wondering on which kind of things you can apply them also, instead of collections, text files, SQL results?
When files are loaded, when does macros expand? Would my macros expand before earlier def ? And in my case, before earlier spec s/def ?
so a single form is compiled to bytecode at a time, and macroexpansion needs to happen before bytecode can be generated, so macroexpansion is a form (a top level form, at a time)
Oh, ok, and in order from top to bottom in the file, and then for each top level form, it goes inner form to outer form?
macro expansion happens outer to inner (I could mixing this up, but I don't believe I am)
this is way something like (when-let (some-macro-that-expands-to-a-binding-vector) ...) doesn't work
Ya, I guess it does, when you have a macro inside another, and call macroexpand-1, you only see the outer one expanded.
I'll get us back on topic, why is it discouraged to wrap macros in functions to allow to compose them?
Like how apply-macro says its madness: https://clojure.github.io/clojure-contrib/apply-macro-api.html
The guidance I've always felt I got from the Clojure/core folks was: always write functions first, then use macros only to provide syntactic sugar (or to achieve something that is impossible in a function -- but even then, use the macro to translate it to a function call).
A use case I find commonly is I want to extend an existing macro. So I want to maybe transform the input to the macro, before sending it to the macro. I can't, because I can't evaluate the args to the macro, so I'm always stuck having to write a macro that wraps the other macro.
Not that itâs convenient, but you can. I mean the with-
kind of macros which is 90% of the macros I write.
> I'm always stuck having to write a macro that wraps the other macro Right, because "macros don't compose". If a macro really is just a thin syntactic wrapper to a function, then you can compose functions and then write just a thin veneer macro around it -- wrapping the functionality, not the other macro.
Ya, and I've trying that more so now, to have my macro implementation be full of normal functions, and the macro just does the unorthodox composition of them. But I think when you want to extend a macro in some other lib, like a core macro, its more confusing to me, though maybe I need to just start digging into those * functions inside, and see that I can use those directly or within my macro, avoiding the need to wrap the macro.
I guess I'm trying to understand why macros don't compose. Could they compose? Is there other constructs out there that are different to macros, yet offer similar benefits but also compose
All I do is (s/and the spec from s/keys and another predicate that needs the same input to s/keys.
Macros are all about the evaluation model. If you understand that, you will know how they can compose. I've written about this here, in case it's helpful: http://blog.altometrics.com/2016/04/a-few-tips-for-writing-macros-in-clojure/
What they usually mean with âmacros donât composeâ: https://softwareengineering.stackexchange.com/questions/222559/is-it-fair-to-say-that-macros-dont-compose
And I was like, why can't this be a function, and its because I can't pass the arguments to a function to the s/keys macros
This is a specific case where the implementation of the macro is just wrapped around a function. Alex has acknowledged that and has said a more programmatic API is coming. This is just alpha at the moment.
I guess I've been reading a bit about rebol: http://blog.hostilefork.com/rebol-vs-lisp-macros/
And I've noticed that one of the limitations of macros from composing in Clojure is that they evaluate at compile time. They act like a pre-processor, and don't have runtime context.
And so, you can pass quoted code to functions, and then the function can choose to eval it, but eval also runs without context, so the code you pass quoted does not carry an environment, all bindings are lost.
But why doesn't Lisps also allow a way to pass code with its environment, like Rebol does? It seems like it could be an interesting thing.
This is a specific case where the implementation of the macro is just wrapped around a function. Alex has acknowledged that and has said a more programmatic API is coming. This is just alpha at the moment.
Now, functions can be passed with an environment, but they can't be transformed before being evaluated, so again its limiting in some ways.
Ya, it might be overkill, and having all these different meta programming construct could get confusing and make things worse, but I'm having fun thinking about it đ
sometimes a good answer is to make a macro that returns a function - the function captures your locals nicely and lets others pass in values
it tends to elegantly solve the âI would use eval but it loses contextâ issues if you generate functions and pass in the locals
it looks like (let [some-f (eval form-for-f)] (some-f local1 local2))
Interestingly, it appears this is an old idea called FEXPRS, and people talk about it: http://wiki.c2.com/?RuntimeMacro and https://en.wikipedia.org/wiki/Fexpr
yeah, they are very very slow
they mean you need interpreted instead of compiled code
Ya, I can see that, as there is no way to know the order in which things will end up at runtime
It appears that I can use a qualified keyword for a namespace that: 1. does not exist 2. exists in project, but is not yet loaded (to avoid circular dependency) Are there any gotchas I should be aware of concerning these ?
The only "gotcha" I can think of is when you use something like ::alias/name
and it will depend on having the alias
defined as an alias for the actual namespace qualifier.
copying aliased stuff into a ns without an alias throws like 5 reader errors in succession
ah, but since I'm not requiring the namespace (to avoid circular dependency), I'm doing :foo.bar/kw-name
if everything is namespaced by :Account/permissions
and :Account/username
it can get a little tiring, and your code can get a little wide. So its nice to use
(create-ns 'HumanName)
(alias 'HN 'HumanName)
Yeah, we have ws.domain.member
and usually alias that to m
so we have ::m/id
etc instead of :ws.domain.member/id