Fork me on GitHub
Garrett Hopper03:03:02

What are people's favorite symbols to use with as->? I kinda like (as-> _), but I'm curious what others' thoughts are.

Garrett Hopper03:03:32

(as-> 1 _
  (* _ 100)
  (/ _ 2)
  (str "100/2" "=" _))

Garrett Hopper03:03:41

It's definitely a deviation from the standard of _ being used for ignoring, which I suppose could lead to confusion.


at work we always use <>. Its distinctive, most probably not conflicting with anything else


I've been using %


I use % too

Garrett Hopper03:03:05

Interesting, I haven't run into either of those.


_ seems like a bad choice to me


everywhere else _ means "ignore me"

👍 16
Garrett Hopper03:03:50

@bronsa That's the one thing I was concerned with.


sorry I didn't read the message where you say exactly that

Garrett Hopper03:03:53

Anyways, if anything thinks of other common symbols, please add them to that issue. I think it's worthwhile seeing what's most common.

Garrett Hopper03:03:14

@bronsa No worries; it's good to know that you had the same thought.

Garrett Hopper03:03:53

% is certainly growing on me. I didn't like it at first, due to possible confusion with anonymous functions, but it feels right.


I use it precisely because it recalls % from anon fns


i guess you can't use anonymous functions in this then


you can - % in the context of #() is a reader macro so they don't conflict


Hmm. I don't like that.


yeah it definitely looks goofy to me too but I haven't settled on anything better.


I agree that _ iss Not The Thing because that's for ignored values. I've seen some people use $ for the purpose.

Garrett Hopper14:03:22

I'm coming to that conclusion. _ is too confusing. Intersting, I haven't seen $ before, but I kinda like it. It feels like shell variables.


I mean, you generally don't do much HOF stuff in -> ime


so the shadowing issue with #() is not problem in practice more often than not


I’ve seen people use <> but I’m not crazy about that either.

Garrett Hopper14:03:07

I'm in the same boat. That seems like the best at the moment, but it still doesn't feel right. What do you currently use for this purpose?


Bleh I don’t have backtick on my phone


That minus the space


yeah the old swiss-arrows library gave you -<> which was as-> <> and that worked but I agree with Tim didn't look great.

Garrett Hopper14:03:35

Thanks for the link. I thought I'd seen a macro like this around somewhere. I've linked this in the discussion here

Busy escaping the comfort zone07:03:57

Hey Clojurians, I'm looking for a detailed reference for core.async I know about and but looking for more detailed coverage


I’m uncertain about the convention to postfix with ?. Would you use it with all boolean values or only predicate functions that return a bool?


you can use it for all boolean values. i've seen it for boolean parameters, let bindings, and option map keys


=> (doc tree-seq)
([branch? children root])


OK, I’ve seen it as well, but thought it was a little counterintuitive. But if it’s expected I guess it’s fine


if you wanted to use it only for predicates in your own code, i don't think anyone would blink twice

👍 4
Ben Hammond08:03:55

can I treat a plain old function map as a protocol? I have this code

(defprotocol Foo
  (bar [this]))

(def foo-impl
  {:bar (fn [this] "beyond all repair")})

(def foo-impl-shim
  (reify Foo
    (bar [this] ((:bar foo-impl) this))))

Ben Hammond08:03:17

(dev/bar foo-impl-shim)
=> "beyond all repair"
as expected

Ben Hammond08:03:37

(dev/bar foo-impl)
java.lang.IllegalArgumentException: No implementation of method: :bar of protocol: #'dev/Foo found for class: clojure.lang.PersistentArrayMap
which seems unfortunate

Ben Hammond08:03:41

is this a side-effect of the way protocols are implemented, they always require a java Class?

Ben Hammond08:03:58

is there something I'm missing?


protocols are for type-based dispatch, not duck typing

Ben Hammond09:03:26

well I was wondering if there was some variant of that would allow me to explicity connect a map with a protocol without having to specify AType


i'm not sure what your aim would be in doing that? protocols do single-dispatch on type; so you must specify a type


they don't mean anything other than that

Ben Hammond09:03:18

it's more a thought experiment

Ben Hammond09:03:39

but I would expect it to provide more runtime flexibility


protocols aren't for that kind of flexibility


multimethods are


from that doc link: "Support the 90% case of multimethods (single dispatch on type) while providing higher-level abstraction/organization"

Ben Hammond09:03:19

so my lesson from that is

protocols are tightly coupled to java Classes and Interfaces due to the way that they manage their dispatch
And there's no getting away from it


everything in Clojure turns into JVM classes/interfaces; protocols are no exception


more precisely, everything in Clojure gets compiled into JVM bytecode

Ben Hammond09:03:49

well yes, but there are often 'pure LISPier' ways to do stuff, as with derive parent/child hierarchies

Ben Hammond09:03:56

but not in this case


ah right, i see what you mean now


all of Clojure's types are JVM types; so anything to do with direct type-based dispatch is going to use those


if you want to use plain maps for dispatch, you can use multimethods

Ben Hammond09:03:39

yeah okay. thanks for your help


no prob 🙂


Does anyone know how to pass properties (like -Dclojure.compiler.disable-locals-clearing=true) to clojure wrapper script?

xtreak2912:03:18 > -O - JVM option aliases Allowed keys in these aliases are: :jvm-opts - a collection of string JVM options If multiple -O alias maps are activated, :jvm-opts concatenate If -J JVM options are also specified on the command line, they are concatenated after the alias options


from what I gather from the docs, use -O:Dclojure.compiler.disable-locals-clearing=true


That doesn't work, unfortunately.

Alex Miller (Clojure team)12:03:01

should be -J-Dclojure.compiler.disable-locals-clearing=true


Made it work: clojure -J-Dclojure.compiler.disable-locals-clearing=true

Alex Miller (Clojure team)12:03:13

-O is for activating jvm opt aliases


Thanks Alex 🙂 For some reason, I first tried -JDclojure...


How are people using protobufs in their Clojure apps? Do you just compile the classes manually? clojure-protobuf et. al. don't really seem to be maintained anymore, and i'm always finding version conflicts with other libs that use protobufs.


Riemann being one such lib


@danielstockton Good question, and I echo your sentiment of unmaintained libraries. I am using protobuf in my starcraft II AI clj project. It's way hacky what I did.. But it works out in the end: - I generated the java classes with the proto cli. - Use the main (dated) repo that does clj<->java protobuf stuff '(org.clojars.ghaskins/protobuf "3.3.1-1") It started giving me trouble with some of the used syntax in my the SC2 api proto files. Specifically some kind of enums/oneOf IIRC. - Found/editted .ebnf of .proto and read all the proto specs. Turned those into Clojure.specs. - Wrote a function that reads namespaced datastructures (based on these clojure.spec) and creates the related java builders and calls the setter methods, using reflection and string guessing of the method names.. - The deserializing works with the protobuf library, just not namespaced but that's okay.


Still working a lot on it. But the proto pain is gone and haven't had any issues with my hacky approach for a while. Spec is really awesome here. I can use cider to walk through the spec, even when that spec spans multiple files, can just walk the nodes 🙂.


Oh nice, my stuff started working with the ghaskins protobuf lib (i was using flatland version). Thanks!

🎉 4

I think they've updated it to proto3 and it doesnt have a dependency on lein-protobuf anymore


Good to hear! Smooth sailing from now on 🤞

🤞 4

hi everyone. what code editors / IDEs do you use for clojure?


Intellij IDEA + Cursive


I already used it for Java, Ruby and Python, so finding a plugin that did Clojure as well was ace. Pity I had to pay extra for it though 😉


I think I’ve tried everything but can’t settle down with one 😄


I’m a vim guy and I’ve been using Spacemacs


vim + vim-surround + vim-parinfer


There's a few vim guys in this team using... fireplace I think


vscode + parinfer + Clojure (Lisin)


In a former life I was a sys and net admin, so I prefer to keep my vim plugin free. Then I can just copy my .vimrc to any server and it works as I expect




I’ve tried that too, but I really really like the parens editing functionality in Spacemacs. it really speeds things up. but Spacemacs looks horrible 😄 no matter what theme I use, it’s just .. I don’t know


@U7ESY38HJ also use spacemacs, love it but agree that it looks pretty bad. If you like dark themes, have you tried sanityinc-tomorrow-bright? It's in the themes-megapack config layer. That one looks decent to me. The other sanityinc themes are okay, too


Thank you, very nice theme indeed!


I’m considering Emacs now but I’m so used to vim keybindings, it’s so difficult to switch


Emacs + Evil mode is what you want for the bindings


I tried plain emacs but could never get it set up how I wanted it, I'm a Vim fan and settled on Spacemacs


(may go back to Vim though some day soon...)

Michael Fiano16:03:41

I use both Emacs and Vim for a few different Lisp dialects including Clojure, and while I really love vim after using it for a couple decades, I will say that CIDER and the Emacs tools for working with Lisp are much better and more mature. So I tend to use both 😞


I use nc and rebel-readline 😉


Atom is coming along. I do most of my repl interactions outside the editor, so I just need convenient paren management in my editor


I may try out zoakes nightlight thing sometime


if you think spacemacs is ugly, you're not gonna like vanilla emacs


but this might be better in #beginners


There's also an #editors channel for general IDE/editor discuss...

cursive 4

do leiningen exclusions work for plugins?


I was so close to actually using juxt in a real scenario:

(defn abbrev-full-name [name]
  (let [[fst sur] ((juxt first last) (clojure.string/split name #" "))]
    (apply str fst " " (subs sur 0 1))))

(abbrev-full-name "luke horton")
=> "luke h"
(abbrev-full-name "luke w horton")
=> "luke h"
(abbrev-full-name "luke a  bc  def     horton")
=> "luke h"
(abbrev-full-name "luke")
=> "luke l" ;;; noooooo!
Can anyone think up a functional way around this that doesn’t predicate on something cheesy like (if (< (count name) 2) ...?


I wish there was essentially something like fnil but more like … fnot-the-right-number-of-args?


I like how str can ignore nil, so when inside str is sometimes useful:

(defn abbrev-full-name [name]
  (let [parts (clojure.string/split name #" ")]
   (apply str (first parts)
    (when-let [lst (last (rest parts))]
     [" " (first lst)]))))


hehe, I’ll never be able to use juxt 😞


Oh... yeah, juxt is worth striving for, just because. 🙂


Here, using juxt. It is always wort it

(defn abbrev-full-name [name]
  (let [[fst sur] ((juxt first (comp last rest)) (clojure.string/split name #" "))]
  (apply str fst (when sur [" " (first sur)]))))


hehehe, nice


This seems interestingly related to Rich's dependency talk with the "give different/incompatible modules different names"


As it seems to force the major/compatibility version number into being part of the name of the module


Not surprising. Pushing versions into the module system is kinda the only way to really get this right.


does [1 2] waste 30 * 4 = 120 bytes of memory since we create an array that can hold 32 refs, but only use 2 of them?


oh, TIL, I never noticed that optimization