#clojure logs

2015-08-18

00:00sdegutisThe connection is stored in a simple var, so basically yeah.
00:02rhg135,(do (def a 1) (alter-var-root #'a inc) a)
00:02clojurebot2
00:02sdegutisjustin_smith: back
00:03justin_smithsdegutis: rhg135 has a good point, you could just use alter-var-root or def
00:03Bronsaew
00:04rhg135I never said it was a good idea
00:04sdegutisWon't that be slower?
00:04rhg135just that it existed
00:04sdegutisAlso Compojure, thus threads.
00:04rhg135exactly
00:05rhg135,(meta *ns*)
00:05clojurebotnil
00:05justin_smith,(meta (the-ns *ns*))
00:05clojurebotnil
00:05Bronsa,*ns*
00:05clojurebot#object[clojure.lang.Namespace 0x62eb0ba1 "sandbox"]
00:05justin_smith,(meta #'meta)
00:05clojurebot{:arglists ([obj]), :doc "Returns the metadata of obj, returns nil if there is no metadata.", :added "1.0", :static true, :line 202, ...}
00:06rhg135,(alter-meta! *ns* assoc ::store-stuff-here-and confuse-people)
00:06clojurebot#error {\n :cause "Unable to resolve symbol: confuse-people in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: confuse-people in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve sym...
00:06rhg135,(alter-meta! *ns* assoc ::store-stuff-here-and-confuse-people)
00:06clojurebot#error {\n :cause "Wrong number of args (2) passed to: core/assoc--4130"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/assoc--4130"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 427]\n [clojure.lang.AFn applyToHelper "AFn.java" 156]\n...
00:06justin_smithrhg135: assoc needs two values
00:06rhg135eh, I probably shouldn't be writing code
00:06justin_smithand they both need to be things that exist...
00:06rhg135,(alter-meta! *ns* assoc ::store-stuff-here-and-confuse-people true)
00:06clojurebot{:sandbox/store-stuff-here-and-confuse-people true}
00:07justin_smithrhg135: heh, I know that feel, I had a large helping of whiskey before leaving work
00:07justin_smithhit a major milestone and had to celebrate
00:07rhg135sad thing is, i'm sober
00:07justin_smithfinally moved the major foundation of our app into onyx for distributed computation - it's like "hey app, welcome to the 21st century"
00:08justin_smithonyx is cool
00:08rhg135I'm just going to update my lazybot fork. that way when I mess up other people can debug for me
00:08justin_smith(inc mdrogalis)
00:08lazybot⇒ 9
00:08rhg135via IRC
00:09justin_smithI did a bunch of lazybot hacking earlier this year
00:09justin_smithbut did not fix the *one thing* that actually needed fixing, somehow
00:09rhg135I a few years ago
00:09rhg135I was meaning to excise mongo, but lazy
00:10rhg135I'd have to rewrite half the plugins
00:10Bronsajustin_smith: the connection issues?
00:10justin_smithyou should totally hook in a dotomic based karma system
00:10justin_smithBronsa: yeah
00:10rhg135I wanted to
00:10justin_smithBronsa: the way it will think it is connected and really be in a void connected to nobody/nothing
00:10rhg135instead I will finish my text generator plugin
00:10Bronsajust immagine how sad and lonely it must feel
00:11rhg135you can call, but nobody replies
00:11justin_smithBronsa: lazybot bugs are how I truly feel inside :(
00:12justin_smithanyway, yeah, never did find a fix for that issue
00:12rhg135my workaround was ping me until I get off my a** and restart it
00:13rhg135eventually I just took it offline
00:14crocketWhy does it take a lot longer to start an uberjar than to start a single script via clojure.jar?
00:14rhg135justin_smith: actually, that datomic idea isn't bad. It'd reminded me I could leave in mongo and move stuff to datomic in time
00:15rhg135no clue
00:28Seylerius,(defn fibber [n] (take n (map first (iterate (fn [[a b]] [b (a + b)]) [0 1]))))
00:28clojurebot#'sandbox/fibber
00:28Seylerius,(fibber 6)
00:28clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
00:29SeyleriusOi.
00:29SeyleriusI really made that mistake?
00:29Seylerius,(defn fibber [n] (take n (map first (iterate (fn [[a b]] [b
00:29Seylerius (+ a b)]) [0 1]))))
00:29clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
00:30Seylerius,(defn fibber [n] (take n (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))))
00:30clojurebot#'sandbox/fibber
00:30Seylerius,(fibber 6)
00:30clojurebot(0 1 1 2 3 ...)
00:30Seylerius,(defn fibber [n] (take n (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1]))))
00:30clojurebot#'sandbox/fibber
00:31Seylerius,(fibber 6)
00:31clojurebot(1 1 2 3 5 ...)
00:31SeyleriusThere we go.
00:32crocketHell
00:35crocketIf I compiled a clojure library for java users, is it tied to a specific clojure version?
00:35Seyleriuscrocket: Pretty sure it compiles the clojure it needs into the jar, so yes.
00:37crocketEwww
00:37crocketIt's going to become large
00:38Seyleriuscrocket: If you're compiling for use by non-clojurists, expect to have to carry around some deps.
00:44rhg135clojure isn't that large anyway
00:45sdegutisSo, swapping out a value for another value inside insert-into-database and update-entity don't sound like terrible ideas performance-wise?
00:46crocketClojure 1.7.0 3.8MB
00:47rhg135that's relatively small
01:53OlajydHi, justin_smith
01:57OlajydHi, TEttinger :)
02:00OlajydTettinger, I want to implement a perl regex pattern in clojure, is this possible?
02:00TEttingerprobably, perl uses a subtly different regex engine, but it's mostly compatible
02:00TEttingerwhat is it in perl?
02:01TEttingeralso, http://www.regular-expressions.info/tutorial.html is an amazing resource
02:04TEttingerOlajyd: there's some further confusion possible because perl 6 (which is kinda in alpha or beta or some prerelease state) potentially can use really really crazy regexes.
02:04OlajydTEttinger, I tried the following: given a perl regex : s/^[PH]*// for the string “hPPHp123hp” i figured a way of doing it in clojur as (clojure.string/replace “hPPHp123hp” (re-pattern “[Pp]|[Hh]”)) :=> “123”
02:06TEttingerdo you want it to ignore case?
02:06OlajydTettinger, yes sure
02:06TEttinger,(clojure.string/replace "hPPHp123hp" #"^[PpHh]*" "")
02:06clojurebot"123hp"
02:06TEttingerif you want it to remove all h and p
02:06TEttinger,(clojure.string/replace "hPPHp123hp" #"[PpHh]" "")
02:06clojurebot"123"
02:06Olajydoh great
02:07Olajydanother use case that seems to confuse me is to replace any possible occurrence with the string “000”
02:09TEttingerso in regexes, which are pretty much their own language, not related to clojure at all (and clojure's regexes are the same as java's), the character ^ means start of string usually. square brackets with some characters inside mean any of those characters will match, once. ^ inside square brackets means anything that ISN'T the characters after ^ in the brackets will match
02:09Olajydso say (clojure.string/replace "hPPHp123hp" #"[PpHh]" “000”) I need it to return ;=> “000123000”
02:09TEttinger* means repetition, 0 or more
02:09Olajydok
02:09TEttinger+ means repetition, 1 or more
02:09TEttingerah ok
02:10TEttinger,(clojure.string/replace "hPPHp123hp" #"[PpHh]+" "000")
02:10clojurebot"000123000"
02:10OlajydGreat
02:10OlajydThanks,
02:11OlajydWill go over the resource you just shared
02:11OlajydI owe u another drink.. :)
02:11TEttingerno prob! regexes are something that I wish they taught whole classes on in colleges, they are extremely useful even to non-programmers (some text editors and even word processors allow regex find/replace, huge timesaver)
02:13Olajydhmm, thanks
02:17TEttingersome of the better tricks with regexes cover stuff that's very difficult with character-by-character processing of a string. within a regex (not a normal string), \b can be very very handy to find word boundaries, and \p{Lu} will find all upper case letters, even ones that aren't in English
02:17MasseR\p? Shouldn't it be \w?
02:18MasseROr maybe even, what's the difference between them
02:18TEttingerMasseR: \w I believe is the same as [A-Za-z0-9_]
02:19MasseRTEttinger: Hmm.. alphanumeric yes, but outside of ascii range
02:19MasseRgrep -E "\w+" --color=always seems to match for both foo0 and föö0
02:19TEttinger&(let [latin1 (apply str (range 32 255))] (apply str (re-seq "\w")))
02:19lazybotjava.lang.RuntimeException: Unsupported escape character: \w
02:19TEttinger&(let [latin1 (apply str (range 32 255))] (apply str (re-seq #"\w" latin1)))
02:20lazybot⇒ "3233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142... https://www.refheap.com/108397
02:20TEttingeroh stupid me
02:20MasseR:)
02:20TEttinger&(let [latin1 (apply str (map char (range 32 255)))] (apply str (re-seq #"\w" latin1)))
02:20lazybot⇒ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
02:20TEttingeryep, ascii only for \w in java
02:20TEttinger&(let [latin1 (apply str (map char (range 32 255)))] (apply str (re-seq #"\p{Lu}" latin1)))
02:20lazybot⇒ "ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ"
02:20TEttinger&(let [latin1 (apply str (map char (range 32 255)))] (apply str (re-seq #"\p{L}" latin1)))
02:20lazybot⇒ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ"
02:21TEttinger&(let [latin1 (apply str (map char (range 32 255)))] (apply str (re-seq #"\p{Ll}" latin1)))
02:21lazybot⇒ "abcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ"
02:21MasseRgrep -E doesn't seem to match anything with \p. I like regex, but too many variations of it :/
02:22TEttingeryeah. \p takes a unicode category code after it in curly bracees
02:22TEttingerL is letters, Lu is upper case letters, Ll is lower case letters
02:22TEttingernot all regex engines implement it, and they all do different unicode versions.
02:23TEttingerjava 9 will support unicode 7.0 sometime next year
02:23TEttingerperl 6 (on one of the VMs it can run on) supports Unicode 8.0
02:23TEttingerperl 6 also has some really really weird and useful extensions
02:24TEttingerIIRC, \c[APOSTROPHE] is another way of matching the ' character, and it's especially useful when your editor thinks any ' is a string starting
02:25TEttinger\c[SIGN OF THE HORNS] is the metal fingers gesture introduced as an emoji in unicode 8
03:09varniegood day.
03:11varnieI have a question about reduce. suppose I have a function which recursively traverses directory, finds specific files and calculates, the count of lines in them. this function returns total count of lines in files. My question is - wouldn't (reduce + ...) produce a lot of "thunks" and, thus, gobble up a lot of memory?
03:13varnieI can show my code snippet to clarify what I mean.
03:30luxbockgfredericks: sorry if you my question earlier was unclear, I'll try to describe my use case
03:31luxbockmy program deals with trees that are "drawn" from rules and a root-node
03:31luxbockand I'd like to use test.check to test properties of the trees
03:32luxbockso to generate them, I need two generators, one for the rules and one for the root-nodes
03:33luxbockhowever these trees can grow quite large depending on the rules and the root-node
03:33justin_smithvarnie: reduce doesn't need to build thunks, because all it needs is the accumulator
03:33justin_smithvarnie: and in the case of reduce + the accumulator takes up very little RAM
03:34justin_smithvarnie: nothing is executed out of order, so there are no thunks to keep around
03:34varniejustin_smith, I want to understand what happens when the depth of execution is big enough.
03:34justin_smithvarnie: reduce doesnt do "deep"
03:35justin_smithvarnie: at each step, the execution so far is cleaned up and replaced by the accumulator
03:35varniewe enter the directory which contains N subdirectories, in order to perform outermost reduce + we need to traverse all of them and calculate their output "result value".
03:35luxbockso in order for my tests to fail early, I'd like to generate the properties of the rules and the root-nodes so that they result in smaller trees at the beginning, and then grow larger and larger
03:35luxbocki.e. that's what I meant with shrinking
03:36varnieand only when we have a list of result values, say (100, 200, 0, 20, etc), the outermost reduce + will fire. or am I wrong?
03:36justin_smithvarnie: there is never a list of results
03:36justin_smithvarnie: + is applied at every step
03:36varniejustin_smith, can you have a look at my code?
03:36justin_smithvarnie: it's late and I'm just having a bit of insomnia but I'll give it a try
03:37luxbockthis would be really easy to do if I can define a generator that chooses elements from a collection, choosing the earlier elements more frequently at the beginning
03:37varniejustin_smith, thank you. one moment please...
03:37luxbockdoes `gen/one-of` already do that?
03:37justin_smithvarnie: but reduce does not hold onto the individual results before applying its accumulation - it's appled and the input is forgotten at every step
03:37varniejustin_smith, here it is: http://pastebin.com/Nja2D7xe
03:38varniejustin_smith, as you already know, I am a newbie, so... ;)
03:39justin_smithvarnie: at line 14 the "reduce +
03:39justin_smithsorry
03:39justin_smithat line 14, the reduce + realizes one item of your map at a time
03:40justin_smiththe map returns a number and all other information from that call realizing that item is thrown away
03:40varnieokay. can you say, what are the drawbacks of my approach? what could be done better in other words?
03:40justin_smiththe number is added to the total you have so far, and the previous total is thrown away
03:40varnieI see.
03:41justin_smithvarnie: I think it's easy to be confused by "reduce +" because + can take more than two args, and in that case it calls reduce
03:41justin_smithvarnie: but when you use "reduce +" you only call + with two args each time
03:42varniewill it be better to rewrite it using loop/recur and accumulating an atom value during each step?
03:43justin_smith,(reduce (fn [acc i] (print "element " i " ") (+ i acc)) 0 [1 2 3 4 5])
03:43clojurebotelement 1 element 2 element 3 element 4 element 5 15
03:43justin_smithvarnie: does the above help?
03:43varnieI know what it does. you mean that I might rewrite my program in that way?
03:44justin_smithvarnie: regarding loop + atom, absolutely not. First off you don't need loop for this, second off if you are using a loop you don't need an atom - you would just pass the updated value to recur
03:44justin_smithvarnie: I was just demonstrating that at each call reduce gives two numbers to +
03:44justin_smithvarnie: and all previous steps are gone
03:44varnieah, that's right.
03:46justin_smithvarnie: and just a couple of style things - you can use import and that way you don't need to type out the full package to use a method
03:47varniejustin_smith, yes, but as for "org.apache. ...." it doesn't work from "lein repl" if I do "(load-file my-app.clj"). (currently I don't have a project for it)
03:47justin_smithand you might want to reduce your repetition by binding something like "file-object (io/file file)" in the let block
03:47justin_smithvarnie: sure, but import doesn't change this at all
03:48justin_smithvarnie: you need to set up your classpath, whether you use import is orthogonal to that
03:48varniejustin_smith, I'll check it out.
03:48justin_smithvarnie: you'll find that in clojure not having a project is the hard way to do things, as soon as you have deps
03:49varniehaha, correct
03:49varnieI decided to start from something simple, but it turned out it is not *that* simple.
03:49varniehaving a project would be way better.
03:50justin_smithvarnie: yeah, the simple thing is to define a project (unless you know classpath building like the back of your hand)
03:50varniejustin_smith, what are the other ways to rewrite my program?
03:52justin_smithvarnie: on line 24, where you look at "last s" this is O(n), here I am sure this does not matter because it's not like you'll have paths thousands of letters long, but since a string is counted it is much faster to use .charAt based on the count
03:52justin_smithwhich is O(1) rather than O(n)
03:53justin_smithvarnie: in general, be suspicious of "last" unless the argument is a lazy sequence (in which case O(n) is your best / only option)
03:53varnieI see. but this function execute 1 times only.
03:53varniein my current program, I mean.
03:53justin_smithyeah, like I said, it likely does not matter here
03:53justin_smithsince the strings are probably very short too
03:53justin_smithjust something to note in general, last is usually not the right thing for anything counted
03:54justin_smith,(counted? "hello")
03:54clojurebotfalse
03:54justin_smithoh wait, I should have remembered that bit of silliness
03:54justin_smithanyway, a string is effectively counted, heh
03:54varniecounted? : ""Returns true if coll implements count in constant time""
03:54justin_smithright
03:54justin_smithin other words we know the count without counting the items by hand
03:55justin_smithwhich means we can probably look up an item without going through them one by one
03:55varnieyup, I got it.
03:57justin_smithvarnie: also, "remove-last-slash" is not needed - you might like it for aesthetic reasons, but /usr/foo/////bar is a valid path, and is equal to /usr/foo/bar
03:57justin_smithunless commons.io is applying restrictions beyond that of the system
03:59justin_smith,(require '[clojure.java.io :as io])
03:59clojurebotnil
03:59justin_smith,(io/file "/////user//////bin///////////ls")
03:59clojurebot#object[java.io.File 0x573cf76b "/user/bin/ls"]
04:00varnieokay. I agree.
04:02justin_smithvarnie: otherwise, modulo camelCase naming (we usually do kebab-case instead), looks fine
04:02justin_smithone pragmatic reason for kebab-case for clojure bindings, is that if we see camelCase we know it's a method of some Object we are using
04:03justin_smithmakes code easier to read
04:03varnieone more question - here I used "isString" which is "(string? path)". I use it to be sure that "(.is Directory (io/file path))" doesn't throw an exception.
04:03varnieI wonder what is a proper way of handling wrong input? say, I execute (count-lines "php", 123)
04:04varniewhere 123 is "path"
04:04justin_smithyou already have a :pre block
04:04varnieyes, that too. but is it ok?
04:04justin_smith{:pre [(not (clojure.string/blank? extension)) (string? path)]}
04:05justin_smithyou can have as many conditions as you like in there, and since the code doesn't work if path is not a string, you may as well make it a pre-condition
04:06justin_smithjust remember that pre-conditions are assertions, and like all other assertions can be turned off at runtime, so use them to detect programmer errors and not exceptional runtime conditions
04:06varnieso, I remove my (let [isString ....]) and leave only pre-condition
04:07varnieone more pointer - I suspect that my count-lines-in-file function might throw some exception if the passed file couldn't be open.
04:08justin_smithvarnie: yeah - whether you want to leave that as an exception for the caller (they asked for information that couldn't be given) or just return 0 for files you can't open via a try/catch is up to you
04:09varnieand, possibly, not only this particular exception ;)
04:09justin_smithsure, you could even try/catch/throw if you want a more specific error in that case
04:13varniejustin_smith, thanks for your help
04:13justin_smithnp, glad I could be of assistance
04:14TEttinger(inc justin_smith)
04:14lazybot⇒ 284
04:14justin_smith(identity amalloy)
04:14lazybotamalloy has karma 293.
04:16luxbockwhen I implement a protocol from another namespace, am I supposed to use the of the class or the var of the protocol in the spec declaration?
04:18justin_smith(ns foo (:require [bar.baz :as baz])) (defrecord quux [] baz/SomeProto ...)
04:18justin_smithso really as neither
04:18justin_smithas the protocol :)
04:19justin_smithbut yeah, expect it to be resolved the same way any symbol pointing to a var would
04:20luxbockalright, I'm having some issues with defining the protocol as a schema, to avoid the issue of circular namespace definitions, if you still remember me asking about that earlier
04:21luxbockso trying to track that down
04:21justin_smithoh, yeah. I'm not as familiar with using protocols in schemas (but I'd expect it would work...)
04:21luxbockit works, sometimes, which is why this is so annoying
04:24justin_smithluxbock: what about defining a schema for the protocol, that validates whether the item implements said protocol? https://github.com/Prismatic/schema/wiki/Defining-New-Schema-Types
04:25luxbockjustin_smith: thanks for the idea, I said schema but I'm actually using https://github.com/roomkey/annotate which is very similar
04:25luxbockbut I said schema since I figured more people would know of it
04:25justin_smithoh - well at that point I'm even less helpful
04:26luxbockfwiw I think your suggestion is how annotate attempts to use it
04:26luxbockI'm guessing the issue is related to the order in which the namespaces are loaded
04:27justin_smithluxbock: also, looks like the trick with annotate would be to make a "type" for your protocol, that extends Typeable, and returns true if the arg implements said protocol?
04:27luxbockall of my other namespaces use my schemas namespace, so it gets required there, but my test namespaces don't
04:27justin_smithhttp://roomkey.github.io/annotate/annotate.core.html#var-Typeable
04:29justin_smithluxbock: or it looks like you could use (Pred (partial satisfies? MyProto))
04:29luxbockjustin_smith: I think annotate already does that for me
04:29luxbocklike I said, it works sometimes :)
04:30justin_smithluxbock: OK, I made that suggestion based on the fact that their documentation made no mention of supporting protocols
04:31justin_smithbut if it only sometimes works automatically, it couldn't hurt to try doing it by hand, no?
04:32luxbockyeah, I'll give that a try next, I'm currently investigating if requiring my schemas-namespace in my generators namespace would do the trick
04:37luxbockyeah the problem is that for some reason the records that I define are not implementing the protocol
04:39luxbockbut they do so when I define them in the namespace where the record-type is defined
05:15fdijaHi! Is it possible to start a NREPL session from lein run? I want to start my app in a terminal, have it init it's UI there, and then connect my editor (emacs) to it with nrepl (Cider). Is that possible?
05:16phillord"lein repl :headless" ?
05:17phillordor you can launch nrepl from within the application. I do that here...https://github.com/phillord/protege-nrepl
05:18phillordbut in this case, it's because I couldn't work out how to launch the application in any other way
05:18schmirfdija: and then M-X cider-connect
05:19phillordor you could launch the nrepl in the normal way with leiningen, then launch the application directly either by calling it's main method, or doing App a = new App() depending on how your application initializes
05:21phillordIn your case, you have a clojure app I guess. So, why not start nrepl in the normal way (i.e. let cider do it) then call launch the app from inside the REPL
05:24fdijaThank you all! I can connect now. What seems to be working is to in my terminal run `lein repl :headless`, and in my repl run (-main). I'm writing a terminal-based text editor, and am writing the side-effect-heavy rendering code. So nice to not be running blind.
06:32Olajyd,(clojure.string/replace "hPPHp123hPHp" #"^[PH]+" "")
06:32clojurebot"hPPHp123hPHp"
06:39Olajydcan somebody help me with this (clojure.string/replace "hPPHp123hPHp" #"^[PH]+" "") I want the result to be “hp123hPHp”
06:40nickenchuggetshi
06:42jeayeOlajyd: Seems like you want #"PPH"
06:44oddcullyjeaye: no i think OP wants the first occurance of any [PH]-chain removed
06:47oddcully,(.replaceFirst "hPPHp123hPHp" "[PH]+" "")
06:47clojurebot"hp123hPHp"
07:23nickenchuggetshmm
07:23nickenchuggetshaving some trouble accessing a dependency
07:23nickenchuggetsI got lein set up
07:23nickenchuggetsran lein classpath, and it looks as though the dependency I've specified is on the classpath, as a jar file
07:24nickenchuggetsI'm a clojure newb btw
07:25nickenchuggetsI wonder if I need to lein javac
07:25nickenchuggetsthis is what I'm trying to do: https://gist.github.com/brlafreniere/abee9b5fa78babf5902f
07:26nickenchuggetsthis is the library I'm trying to use: https://github.com/Raynes/irclj
07:30nickenchuggetshmm, clojure is funky :P
07:32vijaykirannickenchuggets: may be a bit more context will help - where's your clj code ?
07:32nickenchuggetsI used lein to generate an 'app' structure
07:32nickenchuggetsso it's in the standard places mostly
07:33nickenchuggetssrc/cljbot/core.clj
07:33nickenchuggetsI see "Hello World" when I do lein run
07:33nickenchuggetsso I think for the most part things seem to be working
07:33nickenchuggetsbut I can't seem to load that library, irclj
07:34nickenchuggetsin the lein repl or in my src/cljbot/core.clj file
07:34nickenchuggetsand I do have it listed in my project dependencies
07:34nickenchuggetsand it appears to have installed when I run lein run
07:35nickenchuggetshmm, yeah, tried lein deps... all dependencies appear to be installed
07:36nickenchuggetscan't (require '[irclj.core :as irc]) in lein repl
07:36nickenchuggetshmm, I have an idea
07:36nickenchuggetshaha
07:37nickenchuggetshooray!
07:37nickenchuggetsI fixed the problem
07:38nickenchuggetsI looked up the library on clojars.org
07:38nickenchuggetsand saw that it suggested a different version
07:38nickenchuggetsinstead of the version I was using
07:38nickenchuggetsso I used the version suggested on clojars.org for that library, and it appears to be working now
07:39nickenchuggets:)
08:36TMA(inc rubberduck)
08:36lazybot⇒ 5
08:41nickenchuggetshehe
08:41nickenchuggetsso I'm new to clojure, and it's kinda neat
08:44gfredericksluxbock: there are a couple issues you're hitting I think
08:46gfredericks1) is that gen/one-of and gen/elements do not grow from the beginning of the collection, which is because they both use gen/choose (which doesn't grow). I have in test.chuck an alternative to choose that *does* grow, so you could use it in your own version of gen/elements and gen/one-of if you wanted https://github.com/gfredericks/test.chuck/blob/5ed96e279334dfe47df9c9646b060d7fecf73ebf/src/com/gfredericks/test/chuck/generators.clj#L197
08:47gfredericks2) is that it sounds like you're making a recursive generator, which can be tricky w.r.t. sizing. have you looked at the built-in helper for recursive generators?
08:56neurostormI have a vector with ["123" "#234" "#232" "324" "232" "#23"] and need to join lines starting with # with the prev line, so the result should be ["123#234#232" "324" "232#23"] , how can this be done?
09:07hyPiRionneurostorm: https://www.refheap.com/108426
09:08neurostormThx!
09:13dabdwhat are the advantages of clj's PersistentVector implementation over an implementation based on skew binary random access lists?
09:14dabdI was reading this post http://cstheory.stackexchange.com/questions/27820/is-there-a-purely-functional-vector-with-o1-access-to-the-front-and-back-but-o and the poster mentions it can be faster than the clj's implemention.
09:15neurostorm'(reduce
09:15neurostorm (fn [col i]
09:15neurostorm (let [last-idx (- (count col) 1)]
09:15neurostorm (if (= (first i) \#)
09:15neurostorm (assoc col last-idx (str (nth col last-idx) i))
09:15neurostorm (conj col i)))) [] ["a" "b" "#c" "d" "#e" "#f" "g"])
09:20hyPiRiondabd: cache and linear type utilisation mostly. PersistentVector has O(1) for last, and transients provide way faster batch modifications.
09:22dabddoes the latest PersistentVector implementation use RRB-trees?
09:24hyPiRiondabd: core.rrb-vector gives you concatenation functions -- see https://github.com/clojure/core.rrb-vector
09:29dabdhyPiRion: I was wondering if those improvements made it into the PersistentVector implementation
09:31dabdbut I see it is interoperable with the original PersistentVector implementation
09:32hyPiRionyeah, it's essentially just a set of functions that works over PVecs and RRBs without any (notable) penalty
09:33Diabolikdoes anyone have any suggestions for projects for a complete newbie to do as a first project?
09:33Diabolikim a rails dev by trade if that helps
09:44gilliardDiabolik: I would think you could get a good feel for the language by trying some of the problems at http://4clojure.com
09:46magnarsI made a screencast making a game with Clojure and ClojureScript: http://parens-of-the-dead.com Hopefully it'll show how quick and fun it can be to use our language of choice. :-)
09:50stainnice!
09:50stainyou put some effort into this
09:51stainwhat is that funny unicode-shell, btw?
09:51wasamasalol, mutations ahead
09:51wasamasathat does indeed sound scary
09:52magnarsstain: the shell is zshell with oh-my-zshell
09:52magnarsgotta stay away from those mutations :)
10:08stainmagnars: so when you first did this.. did you actually do the static HTML/CSS first and then write all the cljs afterwards, or is that just for the screencast?
10:09magnarsyeah, I created some dummy HTML in an index.html file, and wrote the CSS and images for that.
10:11stainyeah, so you could prototype the view without thinking too much about the logic yet
10:11magnarsexactly
11:02jaaqo#join WordPress
11:04rhg135I see
11:06noncomin clojure seesaw, there is the bind concept which allows controlling canges of values in atoms and such through gui, ok. but is there any concept for the reverse? i.e. if i change the value of the atom - can i make it so that the gui automatically reflects the change?
11:07matthavenernoncom: check out 'add-watch'
11:07noncomoh, ok, so atom watches are the way..
11:08matthavenerother that wrapping the atom update in your own abstraction to coordinate handling changes.. yep, as far as i know :)
11:09noncomi see... sadly this implies much manual work.. unless i write some automation macros for that..
11:09noncomi hoped there is something inside seesaw to make it work already..
11:09noncombut okey, i can manage :)
11:09phillordI am trying to add tools.nrepl to an existing maven build without changing the pom (i.e. as a per user setting). Anyone know if this is possible?
11:10noncomphillord: ummm not sure, but maybe pomegranate is what you need?
11:11noncombut it will require to have it itself in the deps..
11:11phillordif pomengranate were in the pom.xml then yes, it would be, but it isn't. And if I knew how to add pomengranate without changing the pom, then I could just do the same with tools.nrepl
11:11noncomwell, you could extend the classpath for the jar on launch
11:11phillordhow?
11:11clojurebotwith style and grace
11:12noncomeither via java standard method or..
11:12phillordI've thought about settings.xml but that only allows you to changes I don't want to change
11:12noncomhttps://clojuredocs.org/clojure.core/add-classpath
11:12noncombut that's deprecated, idk if it works
11:12phillordparent projects seem a way forward
11:13phillordoh, sorry, I don't have Clojure either
11:13noncom?
11:13phillordI want to add a clojure repl to an existing Java app
11:13noncomah
11:13phillordor rather Java build
11:13noncomoh
11:13noncomwell, i would do it the other way around
11:13noncomadd the java app as a lib to to clojure
11:14phillordI could create a maven plugin that would do this, but then I can't add that either, since maven does not allow me to change that either.
11:14noncomjust start the clojure as usual, but linking the java app jar to it via the classpath (see java cli options for that)
11:14noncomthen you can start clojure and import all your java stuff
11:15phillordyes, I guess that is possible, although I have to create a new clojure project for every maven project to which I want to connect
11:15noncomnot sure. you're saying you already have the java app jar?
11:16noncomwhy not just create a .bat or .sh for every java jar? (or even all of them)
11:17noncomjava -cp clojure.jar clojure.main file.clj
11:17noncomthi sis the default command to launch clojure throught cli
11:17phillordno, I have a maven project with Java in it. Maven lets me run it, no worries. I want to run a clojure nrepl with maven, so that the clojure nrepl process has the environment of the Java project. Then I can use the nrepl to introspect over the java project.
11:18noncomyou could do something like "java -cp java-app.jar nrepl.jar clojure.jar clojure.main file.clj"
11:18noncomnot sure for the exact syntax of -cp though
11:18phillordI'm trying to add interactivity to a java development environment for Emacs
11:18noncomyes, i understand...
11:18phillordnrepl seemed like a nice option -- all working but I have to change the pom
11:19noncomwhy not 1) launch clojure project with nrepl 2) link your java app ?
11:19noncomthink of your java app as a library...
11:19phillordbecause I don't want to build the Java project to jar every time, and anyway, the java app will be in a set of libraries.
11:20phillordI need to be able to recompile the Java and update the repl
11:20noncomrecompile java with a running nrepl without restarting jvm?
11:20phillordyes -- that's been done (vinyasa does it)
11:21noncomok, was going to suggest vinyasa :)
11:21phillordmy roadblock is just getting maven to add nrepl (and my middleware) to the project
11:21noncomhmmmm and your java project also epends on loads of libraries, right?
11:21phillordexactly
11:22noncomuh..
11:22phillordalthough if pomengranate can add a "live" dependency -- i.e. a project directory rather than a fully build maven artifecact it might work.
11:23phillordit's very frustrating -- although that is a common emotion when working with maven
11:23rhg135You can do so through the class path option
11:24phillordrhg135 I can add a directory in this way, but I need to add a project with all of it's dependencies also
11:25noncomlook at this: https://github.com/cemerick/pomegranate/blob/master/src/main/clojure/cemerick/pomegranate/aether.clj
11:25noncomdoes it look like it could work for you?
11:26rhg135Is there a way to get the class path from maven?
11:26gilliardhttps://maven.apache.org/plugins/maven-dependency-plugin/build-classpath-mojo.html
11:29phillordgillard: again, same chicken and egg -- only works if the dependency plugin is installed.
11:29phillordnoncom: yes, it may be possible -- launch clojure then fix it up so that it looks like the project.
11:29gilliardyou can just run mvn dependency:build-classpath without changing the pom.
11:33phillordgillard: okay, that might help. I run clojure with nrepl, then run maven to get build classpath, then add all of these to the clojure repl with pomengranate. Messy, but doable.
11:34noncomif you do not change the libraries too often, maybe you can formulate the project.clj deps out from the java app pom
11:34noncombut that is not a very functional approach.. rather it could save time, but i am not sure..
11:35noncomhey, you could also make a whole tool out of that. i am sure that could be useful to other people too
11:35phillordI've been the route before of trying to understand the maven pom. It's a terrible mess with no defined semantics and things never work as you expect.
11:36blkcatxml, barf.
11:37noncomwell, maven helps completing some really complex tasks..
11:37noncomi am sure if anyone could come up with something more simple, it would have been adopted already worldwide..
11:37phillordXML is just a syntax -- it's the total absence of clear meaning that is problem. If maven had documentation that were, well, comprehensible it would be okay.
11:37noncomthey say gradle is not that bad for interfacing with maven
11:38phillordnoncom: I agree -- the only worse thing than using maven for building java is managing java dependencies without maven.
11:39gilliardha. nicely put.
11:39noncomyeah
11:39noncomwhich is really strange because in reality, the dependencies are just a simple tree
11:41phillordnot really, noncom
11:42noncomyeah, there are goals and conditions and stuff..
11:42noncombut..
11:42phillordyou are forgetting time -- so, a dependency on "Clojure 1.2" is actually a dependency on 1.2 *or later*.
11:43phillordI will have a think on the awful ness of getting maven to report it's dependencies
11:43phillordmight be easier.
11:43gilliardThe dependency plugin has a few goals which might be useful.
11:43Olajydhow can I convert a string in to a verctor of strings given “ig” => [“i” “g”]?
11:43justin_smithphillord: it's not even as simple as that - because it won't look for "or later" unless some other dep demands it
11:44justin_smithOlajyd: what's the separation rule?
11:44justin_smith,(mapv str "ig") ; if the rule is "one string per letter"
11:44clojurebot["i" "g"]
11:44phillordjustin_smith: that's my point -- it's actually a named directed graph, not a tree.
11:45Olajydjustin_smith yea sure
11:45noncomwtf.. http://joxi.ru/V2VnD95s5anW2v
11:45justin_smithphillord: right, agreed 100%
11:45Olajydjustin smith I have a problem in clojure and wish you could help me out?
11:45justin_smithnoncom: wow, your client doesn't handle smart quotes at all :)
11:45justin_smithOlajyd: you can go ahead and answer the question, and I am sure someone will try to answer
11:46noncomseems so :) idk even what that means
11:46Olajydok
11:46phillordanyway, thanks for all the help -- I will consider the options.
11:47justin_smithnoncom: http://i.imgur.com/FKwOTwk.png
11:47justin_smith"smart" quotes
11:47noncomwow, haha )
11:47noncomcreepy
11:47justin_smithinfamously inserted by some osx irc clients
11:47justin_smithand of course totally breaking code examples
11:48justin_smithOlajyd: oh where I said "you can go ahead and answer the question" that's weird and I meant "you can go ahead and ask the question" - you don't need to ask permission to speak on IRC
11:48Olajydhahhaa
11:48Olajydgotcha
11:50Olajydimplement a function that transforms a string by applying a regular expression to it. The first match is replaced by the replacement string. Replacing all matches can be achieved by using the 'g' (global) qualifier. This function allows virtually any perl-syntax regular expression to be applied
11:50Olajyduse cases:
11:51OlajydTo remove all occurrences of a 'P' or an 'H' at the beginning given a string “PH123p” => “123p”
11:52oddcully,(.replaceFirst "hPPHp123hPHp" "[PH]+" "")
11:52clojurebot"hp123hPHp"
11:52OlajydUse case 2: To do the same as above but to catch both uppercase and lowercase P's and H's at the beginning and replace them with 000: given a string “PHpp123p” => “000123p”
11:53justin_smithOlajyd: I'd look at the various regex functions (they are grouped in one section on http://conj.io ) - with the right combo of them I am sure you can make some progress
11:53Olajydaite thanks
11:54justin_smithOlajyd: also you could look at cond for handling the command switches like "g"
11:55Olajydoddcully, the use of P and H actually mean all capital letters and not necessarily P and H
11:55oddcullyi just mentioned it again on your previous question, since it was lost in disconnection
11:56Olajydjustin_smith does that also apply for the use of the “i” flag in the regex?
11:56Olajydoddcully I’m sorry I didnt see it
11:56justin_smithOlajyd: yeah, I would use a regex to pull out the flags/options from your command, then use cond to figure out how to process the string given the flags
11:56Olajydoh great
11:57Olajydso I would create someting like isGobal? predicates right
11:57justin_smithI assume you also know how to use "let"
11:57justin_smithOlajyd: yeah, something like that
11:57Olajydor something like isCaseSensitive? predicates too
11:57Olajydok
11:59Olajydjustin_smith I’m sorry but what exactly is the differene between [A-z]+ and [A-z]+
12:00oddcullylooks the same to me
12:00justin_smith,(= "[A-z]+" "[A-z]+") ; a typo I am sure
12:00clojurebottrue
12:01noncomwhen using grid layout, is there a way to force column width with seesaw?
12:04Olajydjustin_smith so exactly how can I check if an element exist in a vector?
12:05Olajydusing the ‘’some” method
12:06oddcullyOlajyd: when i don't know if there is something around for my case, i consult http://conj.io/ and try a few "words" that might match my usecase
12:06Olajydoddcully thanks buddie
12:51shiranaihito"halp." .. i'm having mysterious trouble with protocols / records - "class not found" or something, and now i'm trying to ":aot :all" in my lein project because i have no fucking clue what's wrong, but that's not working either: Compiling c2d.db.entity
12:51shiranaihitojava.io.FileNotFoundException: Could not locate c2d/db/entity__init.class or c2d/db/entity.clj on classpath
12:51shiranaihitowhy does compiling a namespace require some sort of already-compiled thing for the namespace being compiled?
13:00OlajydHi, justin_smith
13:01OlajydHi, oddcully
13:05shiranaihitoany educated guesses as to what the fuck is wrong with my code? (yes, i'm a bit irate.. :p) .. what's the most common "mistake" people make with protocols and records that would lead to a class not being found?
13:07rhg135aot
13:09shiranaihitorhg135: you'll have to be a bit more specific.. consider that i have no clue about the low-level details related to aot compilation and its relationship to protocols and records etc, and i don't even care.. i just want to get stuff done
13:10justin_smithshiranaihito: the most common problem is code being reloaded
13:10justin_smithshiranaihito: you'll end up with two classes with the same name, that are not the same class
13:10shiranaihitofor example, apparently now i have a record that gets instantiated (potentially just fine), but when its used in a call to a protocol it implements.. nothing happens.. and now i'm not even getting any error messages anywhere
13:10Olajydjustin_smith help me optimize this code please..
13:11Olajydjustin_smith, (defn apply-regex
13:11Olajyd "Function to transforms the contents of a column by applying a regular expression to it"
13:11Olajyd [ row input ]
13:11rhg135usually aot compilation (or stale classes) messes it up
13:11Olajyd (let [{:keys [ col replacement qualifier]} input
13:11Olajyd isCaseSensitive? (some #(= "i" %) (mapv str qualifier))
13:11shiranaihitojustin_smith: i'm not using a REPL though.. can something get reloaded in a problematic way anyway?
13:11Olajyd isGlobal? (some #(= "g" %) (mapv str qualifier))
13:11justin_smithOlajyd: if you just ask your question someone can probably help, I'm in the middle of trying to help shiranaihito at the moment
13:11Olajyd val (if (and isGlobal? isCaseSensitive?)
13:11Olajyd (clojure.string/replace (get row col) (re-pattern "[A-z]+") replacement)
13:11Olajyd (if (and (false? isGlobal?) isCaseSensitive?)
13:11Olajyd (clojure.string/replace-first (get row col) (re-pattern "[A-z]+") replacement)
13:11Olajyd (if (and (false? isGlobal?) (false? isCaseSensitive?))
13:11Olajyd (clojure.string/replace-first (get row col) (re-pattern "[A-Z]+") replacement)
13:11Olajyd (clojure.string/replace (get row col) (re-pattern "[A-Z]+") replacement))))]
13:11Olajyd (assoc row col val)))
13:11Olajydok gotcha
13:11justin_smithOlajyd: please don't paste multiple lines of code into IRC
13:12oddcullyplease don't paste large code snippets in here
13:12justin_smithuse a pastebin site
13:12justin_smithrefheap.com is good
13:12shiranaihitoOlajyd: try www.refheap.com
13:12rhg135refheap ftw
13:12OlajydOk let me try that
13:12justin_smithshiranaihito: yes, bad things can happen if protocol definitions are reloaded and you have objects around that implement the older version of the protocol - even if the definition did not change
13:13shiranaihitojustin_smith: how/why would the definitions get reloaded?
13:13justin_smithshiranaihito: what happens is then when compiling the namespace, a class is generated, and a new class is generated when you reload the namespace
13:14Olajydso after pasting in pastebin do I post the link here or how will you get to see the code?
13:14shiranaihitojustin_smith: do you mean at runtime.. ? i'm not using a repl.. ? what kind of situation are we talking about
13:14justin_smithshiranaihito: ring projects are set to auto-reload. If nothing is reloading your namespaces there is also the issue of AOT - where you can have some objects using the AOTd protocol and some using another definition loaded at runtime
13:14justin_smithshiranaihito: I'm trying to describe the common case, but there are a few ways this can bite you
13:14shiranaihitojustin_smith: i'm actually not using ring - i've set up my own cute little web framework on top of an embedded Jetty
13:14justin_smithOK
13:14oddcullyOlajyd: yes, paste the link
13:15Olajydhttps://www.refheap.com/108436
13:15justin_smithOlajyd: the reason I suggested cond earlier is because it works out better than having if inside if inside if
13:16Olajydok
13:17oddcullyOlajyd: that mapv in the let is copy-and-paste; use a let for it. but if you are just interested if there is a letter in the string you might as well just use .indexOf
13:18justin_smithOlajyd: instead of (if a b (if c d (if e f g))) you can have (cond a b c d e f :else g)
13:18justin_smiththe transformation is pretty simple
13:19shiranaihitojustin_smith: so what's a typical problem with protocols and records when no reloading is involved?
13:19Olajydoddcully this is how I plan to call the function (apply-regex ["PPP123p" "1"] {:col 0 :replacement "000" :qualifier "ig”})
13:19justin_smithshiranaihito: the protocol is redefined, but the record is still extended to the older protocol (pre-redefinition), and this breaks the protocol mechanism
13:20justin_smithshiranaihito: since protocols have an interplay between ns/var level stuff and classes
13:20shiranaihitojustin_smith: i've run into something before, but not like this.. at some point, i think the solution to some protocol-related problem was to require the related namespace .. but this is different
13:20justin_smithshiranaihito: OK
13:20shiranaihitojustin_smith: damn you read fast.. :x
13:21shiranaihitojustin_smith: how would i end up in a situation like you described?
13:22justin_smithshiranaihito: if you had a definition of the protocol visible thanks to AOT, then you had a namespace that used the protocol but did not require the protocol's namespace, so it used the AOT generated class, then another ns required the protocol namespace, causing a new class to be generated
13:22justin_smithshiranaihito: by any chance do you extend the protocol in any namespaces that do not require the ns implementing the protocol?
13:23shiranaihitojustin_smith: and just to be clear, we're not talking about anything related to reloading code now.. ? :P
13:23shiranaihito(runtime etc)
13:23justin_smithat this point, no, not at all
13:23shiranaihitook, cool
13:23oddcullyOlajyd: i am talking about things, that are used over and over in the code (like (mapv str qualifier) and (get row col))
13:23justin_smiththis is an interaction between the AOTd protocol class and the version created when the namespace is loaded at runtime
13:24oddcullyOlajyd: don't copy that down. if it's used twice its a candidate for a let
13:24Olajydoddcull gotcha
13:24Olajydoddcully gotcha
13:24shiranaihitojustin_smith: i only extend the protocol in the namespace it's defined in.. i'm just using it from another Lein project, where the lib containing the protocol is a dependency
13:26justin_smithshiranaihito: hmm, that should just work then
13:26shiranaihitojustin_smith: yeah.. this is the most mysterious situation i've been in with Clojure.. and most of my troubles have been related to protocols.. :X
13:35Olajydoddcully can you help me check out if this is ok https://www.refheap.com/108438
13:36Olajydjustin_smith if you are not in the middle of something can youalso help me check https://www.refheap.com/108438 out too :)
13:37justin_smithOlajyd: in general, it's good to use not instead of false? unless you know that your input is always a boolean
13:37justin_smithOlajyd: because in most things in clojure, both nil and false are considered "falsey"
13:37justin_smith,(false? nil)
13:37clojurebotfalse
13:37justin_smith,(if nil :huh? :OK)
13:37clojurebot:OK
13:38justin_smithit acts like false even though it is not false? - so it's usually better to use not instead of false?
13:38shiranaihito,(false? nil)
13:38clojurebotfalse
13:38justin_smith,(not nil)
13:38clojurebottrue
13:39Olajydjustin_smith was thinking the isCaseSensitive ans isGlobal will always return a boolean
13:39shiranaihitoso false? only evaluates to true for the actual "false" value, but not nil even though both are falsey?
13:39justin_smithyeah
13:39shiranaihitohmhm.. that's kind of unintuitive
13:39justin_smithOlajyd: oh, right, that's true. But "not" is still more idiomatic than "false?" generally
13:39Olajydok
13:40Olajydjustin_smith and more additions or subtractions ;)
13:40justin_smith,(some #(= \i %) "hi")
13:40clojurebottrue
13:40justin_smiththat way you don't need qailifier-vec
13:40justin_smith*qualifier-vec
13:41Olajydjustin_smith thanks… more corrections please :)
13:41snowellshiranaihito: false? is the same as (= false). It's not a test for (not true)
13:41snowellThat would be not :)
13:41shiranaihitosnowell: i get that it works the way it's intended to work.. i just said it's kind of unintuitive :p
13:43snowellWell I was used to Oracle PL-SQL, where (nil == nil) and (nil != nil) both return false. So I guess after that anything can make sense
13:44justin_smithshiranaihito: yeah, which is why "false?" should almost always be pre-emptively replaced with not
13:44shiranaihitojustin_smith: yyep :p
13:44justin_smithshiranaihito: we should keep a community blacklist
13:44justin_smithflatten, false?, partition
13:44justin_smithI am sure there are others
13:45shiranaihitojustin_smith: oh :p .. i didn't know flatten and partition were Bad somehow
13:45justin_smith~flatten
13:45clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
13:45shiranaihitowhat's the problem?
13:45oddcully,(some #{\i} "ho")
13:45justin_smith~partition
13:45clojurebotnil
13:45clojurebotpartition is probably not what you want; see partition-all.
13:45oddcully,(some #{\i} "hi")
13:45clojurebot\i
13:45justin_smithoddcully: that's fancy, but slower than the = check
13:46oddcullyi suggested indexOf above ;P
13:46justin_smith:)
13:46justin_smith(inc oddcully)
13:46shiranaihitojustin_smith: ok but what's wrong with using flatten instead of concat, for example, even if you only need to flatten one level?
13:46justin_smithshiranaihito: ##(flatten {:a 0})
13:47justin_smith,(flatten {:a 0})
13:47clojurebot()
13:47justin_smith,(flatten "hello")
13:47clojurebot()
13:47shiranaihitowtf
13:47justin_smith,(apply concat {:a 0})
13:47clojurebot(:a 0)
13:48shiranaihitojustin_smith: so why does stuff disappear?
13:48justin_smithshiranaihito: also only the end user of a function knows whether "you only need to flatten one level" - so if you are writing a function someone else might use, you are severely restricting their data representation if you use flatten
13:48justin_smithshiranaihito: as the factoid mentions, imagine if your base case is a list or vector
13:49justin_smithshiranaihito: stuff disappears because flatten "takes a nested combination of sequential things" and I guess {:a 0} and "hello" are not sequential things
13:50shiranaihitojustin_smith: alright, but i wasn't thinking about it from a library author's viewpoint.. just some random situation where you personally have a choice between flatten and whatever.. but it does look weird when stuff disappears like in your examples
13:50justin_smithshiranaihito: which is why concat is almost always the better choice
13:50justin_smithit's more controlled too, which means it is more flexible
13:57sdegutisWhat's a noble alternative to select-keys that includes nil keys?
13:58justin_smith,(select-keys {nil "OK" :a 0 :b 1} [:b nil])
13:58clojurebot{:b 1, nil "OK"}
13:58sdegutisMy current solution is just ##(select-keys (merge {:a nil :b nil :c nil} {:a 1 :b 2}) [:a :b :c])
13:58sdegutisjustin_smith: Sorry I meant absent keys.
13:59justin_smith,(let [wanted [:a :b]] (merge (zipmap wanted (repeat nil)) (select-keys {:a 0} wanted)))
13:59clojurebot{:a 0, :b nil}
14:00sdegutisSo you'd use the same basic technique?
14:00justin_smithwith less manual repitition, yeah
14:00sdegutisRight.
14:00sdegutisI wasn't sure how to manually create a map of nils for all given keys.
14:00justin_smithI mean that version could easily become select-all-keys or something
14:01justin_smithyeah, zipmap is probably the best bet for making that map
14:01sdegutisWell I only need it in one function so far.
14:01sdegutisThanks bro.
14:01justin_smithnp
14:03sdegutisOh wow. Turns out that's what I was already using too.
14:03justin_smithhah, figures
14:03sdegutisI had this: (defn- entity-equals [a b] (let [a (merge (zipmap (keys b) (repeat nil)) (select-keys a (keys b)))] (= a b)))
14:04sdegutisYours is way better tho.
14:04sdegutisCloser to the metal.
14:04justin_smithuh... if you say so
14:05sdegutisYours being this: (defn- select-all-keys [m ks] (merge (zipmap ks (repeat nil)) (select-keys m ks)))
14:05justin_smithright
14:05sdegutisI'm totally using yours now, it's simpler.
14:06sdegutisOkay, I had two idiotic functions scattered in my tests: entity-matches? and entities-match? ... the former is completely removed from all my code!
14:06sdegutisNow to finish the latter... :D
14:26gfrederi`tcrawley-away: ping
14:31sdegutisIT WORKED!!!!!!
14:38sdegutisFinally got rid of functions that have been bugging me for 2 years.
14:39sdegutisTons of them too.
15:26crazydiamondHi. What do I need to use cljc files? I'm trying to include ns from cljc file in cljs file, but got an error "No such namespace"
15:34gfrederickscrazydiamond: you have to be using clojure 1.7
15:35crazydiamondgfredericks, and I'm doing so
15:36gfredericksthat's the only requirement I know of; you might check your cljsbuild configuration for source paths
15:36gfrederickscrazydiamond: oh you might also need a recent version of cljs
15:36crazydiamondaha
15:39crazydiamondgfredericks, thanks, I'll check cljs version too. I'm using boot instead of lein, but it operates much the same
15:40gfredericksboot can build it!
15:40gfredericks~boot
15:40clojurebotTitim gan éirí ort.
15:40gfredericks~boot |can build| it!
15:40clojurebotIn Ordnung
15:42TEttingerclojurebot: boot is where you hide the bodies... of Maven POMs, before you bury them forever.
15:42clojurebotOk.
15:42justin_smith~boot
15:42clojurebotboot is where you hide the bodies... of Maven POMs, before you bury them forever.
15:43TEttingerI've not had the best experience with maven
15:44snowellGradle makes maven a little more palatable
15:44snowellThen again, so does lein
15:45TEttingerI really have not liked gradle in the time I've had to use it with certain java libs
15:45TEttingerit's much much slower than maven
15:45snowellHmm, not sure I've really seen that
15:46snowellThen again the only non-trivial migration I've done to gradle was from ant
15:46snowellSo basically anything was better
15:48justin_smithif boot wants to take off, some sci-fi author needs to write a sequel to Leiningen vs. the Ants culminating in Boot wearing aliens that defeat Leiningen in a battle of wits.
15:48TEttingeralso at least when this particular library switched to gradle (because android was moving that way, really), the IDE integration was really abysmal
15:48TEttingerevery other IDE update would break gradle integration, no matter what IDE
16:15tcrawleygfredericks: pong
16:24sveri1TEttinger gradle 2 has sped up a lot of things and agreed the IDE support is bad, as long as the console does not count as IDE where it shines :-)
16:25TEttingeryep. it's definitely gotten better, I just wish lein or boot had something that was similarly succinct in the java-world
16:28oddcullyit got "better" with recent intellij - if you generate some xmlblobs for intellij to tell it: you don't have a clue whats going on, right? better keep out of it - ymmv
16:30TEttingeryeah, that's what I always do now.
16:31TEttingerit's a pain when you need to change gradle and IDE settings to do certain things and project file regen is needed
16:33oddcullyif its vital i extract the fragments from the .ipr file and inject them in the idea task
16:35sveri1hm, we encountered problems with eclipse, but all of them were solvable
16:38sveri1mostly related to target platforms
17:27gfrederickstcrawley-away: is it possible to use immutant.messaging w/o using jboss?
17:42jcrossley3gfredericks: sure
17:42jcrossley3depending on your definition of 'jboss' :)
17:46jcrossley3gfredericks: everything here (and more) works standalone, i.e. not deployed to wildfly (formerly known as jboss): https://github.com/immutant/feature-demo/blob/master/src/demo/messaging.clj
17:46jcrossley3you can check that project out and just 'lein run'
17:47jcrossley3or more specifically, 'lein run -m demo.messaging'
18:11jbordengood afternoon.
18:13jbordenI was wondering if there is a library for modifying your source code (clj,cljs) using a lein exec script or other method. e.g. I have a user.clj file which will send out an email when a new user is added to the system. I want to comment out the line that sends out the email for development and testing purposes but leave it in production.
18:14jbordenbasically, I want to be able to modify the source code and have different versions for 'development' and 'production'. Does anyone know of a library or lein plugin that does that?
18:21eriktjacobsenjborden Why do you want to modify the source code, instead of the more standard approach of using an environment variable or filesystem config?
18:22eriktjacobsenput a file in “/etc/jborden.config” for instance that has either “production” or “development” inside (or perhaps even email specific settings?) and have the program read from that at run-time to determine behavior
18:27jbordeneriktjacobsen: So have an environment variables, say 'send-email?' , and a bunch of if statements in the code that (if (send-email?) (send-email args)) ?
18:28eriktjacobsenYou could, or simply have an environment variable that sets things either to “dev” or “prod”. Here is some code from a project:
18:28eriktjacobsenhttp://pastebin.com/5F1iZAR3
18:29eriktjacobsenset-env! sets an atom, so rest of program can just do a check on (if (= @env :prod))
18:29eriktjacobsenbut basically, yes
18:31eriktjacobsenif you want finer grain stuff than simply “dev/prod”, I’d recommend you use a filesystem config file that contains a map of variables, either serialized clojure (pr-str) or json, and then you load that as a map so you can pull out specific stuff and don’t have to juggle multiple environment variables
18:33jbordenso I would basically keep my environment variables in a map and just set the environment I am in with a System/setProperty ?
18:35jborden{ :dev {:param1 "value"} :prod {:param1 "different-value"}} (System/setProperty "environment" ":dev")
18:37jbordenOK I will do that if it is the more standard way of doing things, makes more sense than modifying the entire source tree because you can see what is going on
18:38jbordenthanks eriktjacobsen
18:40eriktjacobsenjborden: multiple situations so going to restate for clarity…. the System/getenv is reading environment variables, so for instance you wouldn’t set that in the code, but you’d do something like “export PARAM=prod;java -jar asdf.jar (or lein run)” and then once that env is read into an atom (or whatever), all your conditional statements would be checking against either dev / prod. The second situation would be where
18:40eriktjacobsenyou’d want finer grain control over stuff, in which case you would skip the environment variable and not care if you are in dev / prod at all, but rather have specific things like email in the config file (on the filesystem, separate from your deployed jar), then the conditionals inside code would work off that config map
18:54rhg135well, now my lazybot has datomic backed karma semi-working
18:55rhg135etting the schemas from the plugins was a pain
19:20justin_smithrhg135: I can't think of the last time someone took a joke I made that seriously
19:20rhg135I seriously was meaning to go to datomic
19:20justin_smithoh, OK
19:42sotrhRavenhello everyone
20:07gfredericksjcrossley3: okay, good to know, thanks!
20:14rhg135https://github.com/rhg/flutterbot/tree/datomic I was serious
21:07justin_smith,(whither)
21:07clojurebot
21:07justin_smith,(whither)
21:07clojurebot
21:07justin_smith,(repeatedly whither)
21:07clojurebot(⤉ ⬆ ⇍ ⇃ ➱ ...)
21:17justin_smithI should have named it ddr
21:54TEttinger,(defn ddr [] ((comp symbol str char) (rand-nth (concat (range 0x2190 0x2200) (range 0x27f0 0x2800) (range 0x2900 0x2980)))))
21:54clojurebot#'sandbox/ddr
21:54TEttinger,(repeatedly ddr)
21:54clojurebot(⇐ ⟷ ⥹ ⇓ ⇞ ...)
21:55justin_smith(inc TEttinger)
21:55justin_smith(ddr)
21:56justin_smith,(ddr)
21:56clojurebot
21:56TEttinger,(ddr)
21:56clojurebot
21:56TEttingerhow'd you do yours, justin_smith?
21:56justin_smithI really don't know how to do some of these dance moves
21:56TEttingerhaha
21:56justin_smithTEttinger: much stupider
21:56justin_smith,(ddr)
21:56clojurebot
21:56TEttingeryours can do some symbols mine can't
21:56justin_smithTEttinger: I had found a page with every unicode arrow like thing, and just made a string
21:56TEttingeroh yes
21:56TEttingerthat is an option I considered
21:57justin_smithTEttinger: http://copypastecharacter.com/arrows
21:57justin_smithTEttinger: the best version would condense all the ranges on that page, of course
21:57TEttingerthere are many arrows in weird unicode categories that aren't arrows, supplemental arrows A, or supplemental arrows B
21:58TEttinger,"\u27ac"
21:58clojurebot"➬"
21:59TEttinger,"\u2b90"
21:59clojurebot"⮐"
21:59TEttingerthat's a tricky ddr move
21:59TEttinger"slip and fall"
23:57justin_smith,(->>[[8592 8703][9027 9032][9036 9037][9039 9040][9043 9044][9046 9047][9166][9650][9654][9660][9664][9735 9736][10132][10136 10159][10161 10174][10224 10239][10496 10538][10541 10569][10578 10619][11008 11025]](mapcat #(apply(fn([x][x])([x y](range x (inc y))))%))(map char)(apply str))
23:57clojurebot"←↑→↓↔↕↖↗↘↙↚↛↜↝↞↟↠↡↢↣↤↥↦↧↨↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇫⇬⇭⇮⇯⇰⇱⇲⇳⇴⇵⇶⇷⇸⇹⇺⇻⇼⇽⇾⇿⍃⍄⍅⍆⍇⍈⍌⍍⍏⍐⍓⍔⍖⍗⏎▲▶▼◀☇☈➔➘➙➚➛➜➝➞➟➠➡➢�
23:57justin_smithTEttinger: ^
23:57justin_smithTEttinger: I used a sort / reduce to generate those number ranges of course
23:58TEttingerah nice
23:58TEttinger,(char 11025)
23:58clojurebot\⬑
23:59TEttinger,(map int "➢�")
23:59clojurebot(10146 65533)
23:59TEttingerah, you got cut off and utf-8 took over
23:59justin_smithoh yeah that must have happened somewhere