#clojure logs

2016-04-11

00:00amalloy(reverse []) => (nil)
00:00justin_smithamalloy: good point
00:00justin_smith,(def myrev (partial into ()))
00:00clojurebot#'sandbox/myrev
00:00justin_smith,(myrev (range 10))
00:00clojurebot#error {\n :cause "Unable to resolve symbol: myrev in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: myrev in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: myrev in this...
00:00justin_smith,(def myrev (partial into ()))
00:00clojurebot#'sandbox/myrev
00:00justin_smith,(myrev (range 10))
00:00clojurebot(9 8 7 6 5 ...)
00:00justin_smithnot lazy though
00:02amalloyreverse never is
00:02lewis,(first (sorted-set 5 7 2 7))
00:02clojurebot2
00:03mmercersorted-set is a binary tree, and set is?
00:04lewisjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentTreeSet
00:05amalloyyou asked this 8 hours ago, mmercer. what was unsatisfying about the answer?
00:06lewisamalloy: justin_smith: my reserve do not work on sets
00:06lewiss/reserve/reverse*
00:06justin_smithlewis: call seq before destructuring
00:06justin_smithor use first/rest instead of destructuring
00:07sdegutisSo, the past few years, there's been songs that I liked and I was like "Wait a second! This is a guitar song!! I CAN PLAY THIS!!!" But then I looked up the chords and it was non-standard tuning, and I didn't trust my crappy old guitar to be able to be tuned back.
00:07sdegutisBut now, I have a semi-okay guitar, and a tuner thing on it, so I realized I can play things like Bon Iver's Skinny Love now, stuff with alternative tunings!
00:07sdegutisWhich is cool... except I can't remember ANY of those songs from the past that had alternative tunings.
00:07justin_smithsdegutis: one guitar for each song
00:08sdegutisAnd I didn't keep track of them either.
00:08sdegutisSo I like have no idea what songs those were which I want to play which have alternative tunings.
00:08sdegutisAnd I'm just sort of hoping I eventually come across them, even though I can't remember how I came across them before (none of the songs in my iTunes library fit the bill).
00:11lewisjustin_smith: thanks
00:12lewisjustin_smith: following my example, im reading other solutions
00:12lewisreduce #(conj %1 %2) () - i understand this
00:12lewisreduce conj () - I dont understand this
00:13amalloy#(conj %1 %2) is just conj
00:13justin_smithlewis: what is the difference between #(conj %1 %2) and conj?
00:13justin_smithahh, sniped :)
00:13amalloyyours was in the form of a quetion though, so you win
00:13amalloysocrates had it right
00:13sdegutisamalloy: that's not true, conj can take more than 2 arguments
00:14justin_smithamalloy: it's defensive, that way I learn something if they are onto something I missed
00:14troydmI have an transient vector, and I want to drop last element from it, how do I do that without converting it to persistant and back?
00:14sdegutisjustin_smith: mark this day, the first time amalloy has been wrong about something in clojure
00:14justin_smithsdegutis: in a reduce there's no difference though, because reduce always gives you two args
00:14sdegutiscorrect
00:16amalloycan anyone think of an exception to "reduce always gives you two args"?
00:16lewisconj is the function without arguments, justin_smith: so reduce pass the arg by default
00:16justin_smithnot me
00:16tolstoyreduce-kv?
00:16justin_smithlewis: what does "the function without arguments" mean?
00:17amalloy,(reduce #(conj %1 %2) ())
00:17clojurebot#error {\n :cause "Wrong number of args (0) passed to: sandbox/eval27/fn--28"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: sandbox/eval27/fn--28"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 28]\n [clojure.core.protocols$iter_reduce invokeStat...
00:17lewis,(reduce #(conj %1 %2) () [ 1 2 3 4])
00:17clojurebot(4 3 2 1)
00:17lewis,(reduce conj () [ 1 2 3 4])
00:17clojurebot(4 3 2 1)
00:18lewisjustin_smith: it means the operator
00:18justin_smithwhat?
00:18clojurebotwhat is seq
00:18lewis(operator operand1 operand2)
00:18justin_smithlewis: a function is a function
00:19justin_smithlewis: I have no idea what you mean by "function with no args" in this context - conj always needs args
00:19lewisi meant without operands*
00:19justin_smithdo you mean a bound function rather than a literal?
00:19justin_smithwhat? it has operands
00:19justin_smithit just doesn't have a literal inline notation
00:20justin_smithbecause it's a definition and not a function literal
00:20lewiswithout explicit operands then
00:20justin_smithlewis: conj is conj, conj called with two args and #(conj %1 %2) always do the same thing
00:20justin_smith(if called with the same two args)
00:22justin_smith#(conj %1 %2) is a sugar for (fn [x y] (conj x y)) which is just an elaborate way of calling conj, and can usually be replaced by conj itself (unless you are trying to be stricter about argument count or something)
00:22sdegutisoh man
00:23sdegutisAre there any more big surprises in store for Clojure?
00:23sdegutisAll sorts of cool things were happening, things like destructuring were invented.
00:23sdegutisNow it's, like, "we're adding a socket config to make things a little easier"
00:23tolstoyYou mean, what would a Clojure 2.0 be?
00:24sdegutisWell I dunno, versions these days are weird.
00:24sdegutisI just mean, compare Clojure 1.0 to Clojure 1.5, big changes happened. Now look at Clojure 1.5 compared to Clojure 1.8, not a whole lot in comparison. Mostly transducers.
00:24lewisjustin_smith: I see/ i got confused
00:26sdegutis(doc fold)
00:26clojurebotGabh mo leithscéal?
00:26sdegutisclojurebot: just print the damn doc please
00:26clojurebotExcuse me?
00:26sdegutis,(doc foldcat)
00:27clojurebotCool story bro.
00:27sdegutisclojurebot: you're a real jerk
00:27tolstoyFor some reason I think the defprotocol in 1.2 was the biggest deal, but just subjectice.
00:27clojurebotGabh mo leithscéal?
00:27sdegutistolstoy: also destructure was around then
00:27sdegutistolstoy: before then there was literally no destructuring anywhere
00:27justin_smith,(require 'clojure.core.reducers)
00:28clojurebot#error {\n :cause "Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath."\n :via\n [{:type java.io.FileNotFoundException\n :message "Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath."\n :at [clojure.lang.RT load "RT.java" 456]}]\n :trace\n [[clojure.lang.RT load "RT.java" 456]\n [clojure.lang.RT load "RT.java"...
00:28justin_smithsdegutis: fold is in reducers, I dunno why clojurebot doesn't know about reducers?
00:28sdegutisyeah weird
00:29tolstoysdegutis: The reason I was thinking protocols were a big deal was that it made (or was a step) toward making clojure-in-clojure possible.
00:29justin_smithtolstoy: sure, but there's no rush to make clojure-in-clojure happen
00:30sdegutistolstoy: oh i see
00:30tolstoyjustin_smith: Right. But (subjectively) that 1.2 release seemed significant because of that new abstraction.
00:30sdegutistolstoy: only the compiler could be rewritten in clojure, not the runtime, which isnt super useful for any particular reason
00:30tolstoyAlthough "starts-with?" and "ends-with?" in clojure.string hit me where I live most of the time. ;)
00:31sdegutisI'd much sooner prefer to have a Clojure in C, with a small compiler and runtime similar to Lua's -- which I was trying to work on but I don't get paid to do it and have no actual use for it so I put it on indefinite hold
00:31sdegutis... but it would be cool as heck.
00:31tolstoyThere's pixielang. Sorta close.
00:32rhg135if by close you mean in the same universe :P
00:33justin_smithrhg135: I can't think of a language more similar to clojure that is not a fork of clojure
00:33rhg135A while ago I had to embed in a C app
00:33rhg135it was scary
00:33tolstoyI think pixielang has a nice FFI to C, no?
00:34rhg135does it?
00:34justin_smithI've seen nicer, but I've seen worse too
00:34rhg135that's nice
00:34rhg135FFI from C though...
00:34tolstoyOkay, I mean, it has one.
00:35tolstoyI once tweeted "I hope someone does a Clojure on top of Swift." Baldridge responded, "I'm tempted." I'm still hoping.
00:35sdegutistolstoy: kinda sorta
00:36sdegutistolstoy: the whole fun of writing a language that bridges to C though is that you then have access (assuming you build a decent FFI) to *way* tons of cool libs
00:36sdegutistolstoy: thats not true with swift
00:36tolstoyWell, okay. But Swift boils down to LLVM. Is there no interop with C?
00:37sdegutistolstoy: its kind of there but its 1-way and terrible
00:37justin_smithsdegutis: on one side it's very easy to interact with c, but you inherit all of c's problems, on the other side, you don't deal with c's bs, but it's hard to interoperate (or at least computationally expensive with all the boxing/unboxing and manual tracking of which values c keeps track of and which your language does)
00:38justin_smiththere's a lot of room in the middle, but the best spot is subjective (but langs that can parse .h files are handy)
00:38sdegutisheh
00:38sdegutisjustin_smith: until you start dealing with C macros and # includes etc
00:39sdegutisand include-guards
00:39sdegutisoh man
00:39ben_vulpessdegutis: stahp
00:39sdegutisyou're basically writing the CPreP
00:39ben_vulpesplz no bully
00:39ben_vulpesthere's also clasp if one wants a llvlisp
00:39sdegutisman i just wanna find those songs
00:39justin_smithsdegutis: there's langs that find ways to do it, and it makes using c much easier.
00:39sdegutisjustin_smith: i kind of admire lua's approach but hated it as an end user
00:40sdegutisthey're just like "we dont care"
00:40sdegutis"about anything. at all."
00:40ben_vulpes"hey man"
00:40ben_vulpes"programming's just strings"
00:40sdegutishaha
00:40sdegutisstringly typed
00:40sdegutisoh yah that reminds me i came up with a good solution to stringly typed map keys
00:40ben_vulpes"just concatenate your calls together at runtime and eval 'em"
00:40ben_vulpes#yolo
00:40sdegutis(defaccessor foo)
00:41sdegutisit expand to (def foo :foo)
00:41sdegutis:D
00:41sdegutisim not joking, i literally did this for work last week.
00:41sdegutisits there in production right now.
00:42ben_vulpessdegutis: b-but why
00:42justin_smith(defmacro defidentity [sym] `(def ~'sym ~sym))
00:43sdegutisi just kept feeling anxious every time I typed (:videos-service env) and was wondering if it was plural or singular
00:43justin_smithit's a layer of error-checking you don't get for keywords, yeah
00:43justin_smithmaybe someone will even find a valid usecase for defidentity
00:43sdegutisjustin_smith: your version is broken
00:43justin_smithit's something different
00:43sdegutis,(defmacro defidentity [sym] `(def ~'sym ~sym))
00:43justin_smithsdegutis: given foo, it should define foo to be foo
00:43clojurebot#'sandbox/defidentity
00:43sdegutis,(defidentity foo)
00:44clojurebot#error {\n :cause "Unable to resolve symbol: foo in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: foo in this conte...
00:44justin_smithsdegutis: foo has to exist
00:44justin_smith,(def foo 1)
00:44clojurebot#'sandbox/foo
00:44justin_smith,(defidentity foo)
00:44clojurebot#'sandbox/sym
00:44sdegutis,(defidentity foo)
00:44clojurebot#'sandbox/sym
00:44justin_smithoh, that's broken
00:44sdegutissee thats what i said
00:44sdegutisi use the ~' trick often
00:44sdegutisso i know it when i see it
00:45sdegutisand yes i know its a literally terrible practice and amalloy would have a heart attack if he ever saw code like it
00:45sdegutisbut it works
00:45sdegutis,sym
00:45clojurebot1
00:46sdegutisjustin_smith: what were you actually going for tho?
00:46sdegutisi cant even imagine what the code was sposta be
00:46justin_smithsdegutis: (definidentity foo) should become (def foo foo)
00:46sdegutisthat sounds 110% useless
00:46justin_smithit was meant to be
00:46ben_vulpes,(defidentity :h)
00:46clojurebot#'sandbox/sym
00:46sdegutis,sym
00:46clojurebot:h
00:46justin_smithyeah, it's broken
00:47sdegutis,(defmacro defidentity [sym] `(def ~sym ~sym))
00:47clojurebot#'sandbox/defidentity
00:47sdegutis(defidentity foo)
00:47sdegutis,(defidentity foo)
00:47justin_smithyeah, that's the right definition
00:47clojurebot#'sandbox/foo
00:47sdegutis,foo
00:47clojurebot1
00:47sdegutis,(defidentity :g)
00:47clojurebot#error {\n :cause "First argument to def must be a Symbol"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.RuntimeException\n :message "First argument to def must be a Symbol"\n :at [cloju...
00:47sdegutishahaha def sucks
00:48justin_smithsdegutis: oh! not totally useless - it replaces the previously useful metadata with new misleading metadata
00:48justin_smithsdegutis: eg. the source line etc.
00:48sdegutishahaha
00:48justin_smithalso probably eliminates a docstring
00:48sdegutisdefobfuscate
00:48sdegutis,(defidentity map)
00:48clojurebot#error {\n :cause "denied"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojureb...
00:48sdegutishaha jerk clojurebot
00:49tolstoyMaybe use the name "definitely"?
00:49sdegutis;D
00:51justin_smithsdegutis: re-reify
00:53tolstoyre-iffy
00:59rhg135,(defn obfuscate [v] (alter-meta! v (constantly {:macro (:macro (meta v))}))
00:59clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
00:59rhg135,(defn obfuscate [v] (alter-meta! v (constantly {:macro (:macro (meta v))}))
00:59clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
01:02bmukI'm trying to write a function which, given a seq of directories, returns a flat collection of all the files below those directories. Obviously this calls for recursion, and my insinct is to use cond, check the base case (seq is empty), and reduce the results. As I understand it, the JVM performs poorly with this kind of recursion. What is the best and most idiomatic way to do this?
01:02clojurebotI don't understand.
01:03rhg135,(meta #'map) ; I think I broke clojurebot
01:03clojurebot{:macro nil}
01:04tolstoybmuk Have you tried file-seq?
01:06tolstoyOh. Hm. Doesn't answer the question, I guess.
01:06bmuktolstoy: I wasn't aware of it but it looks promising
01:06tolstoy(mapcat #(file-seq %) [dir1 dir2])? Something like that?
01:08rhg135self-calls in lazy-seqs are ok iirc
01:08bmukthat looks like exactly what I need
01:08mmercerclojure newb.. is there a difference between #(file-seq %) and just file-seq?
01:09bmukmmercer++, exactly what I was about to ask. Or 'file-seq or something. Ran into that issue when trying to (map .getPath '(file1 file2))
01:09rhg135yes, one takes only one arg (but I think file-seq does anyway) and that first fn has different metadata
01:09tolstoy(mapcat #(file-seq (java.io.File. %)) ["bin" "Desktop"])
01:10rhg135#() expands to (fn [] ()) which creates a new function
01:10bmukrhg135 I know that, but why can't I just pass map the .getPath function?
01:10tolstoyYeah, I always to the #() thing until I all of a sudden see it's not necessary.
01:10rhg135by new function I mean a clojure.lang.IFN object
01:11rhg135methods aren't objects, bmuk
01:11bmukahh. My java knowledge is limited. .NET dev by day
01:12bmuknot even sure if C# methods are objects
01:12rhg135(.method x) is sugar for (. x (method)) and in the jvm you can't pass around methods, just objects
01:13rhg135so you can pass around an IFn object that calls the method, but not the method itself
01:13rhg135(doc memfn)
01:13dysfunmethods are just too attached to objects, you can't separate them as such
01:13clojurebot"([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn. name may be type-hinted with the method receiver's type in order to avoid reflective calls."
01:14rhg135,(memfn toString) ; thusly
01:14clojurebot#object[sandbox$eval48$fn__49 0x5743a3c1 "sandbox$eval48$fn__49@5743a3c1"]
01:14rhg135,(macroexpand-1 '(memfn toString)) ; rather
01:14dysfunrhg135: hrm, didn't know about memfn, neat!
01:14clojurebot(clojure.core/fn [target76] (. target76 (toString)))
01:15bmukyeah, this is really good info, thank you
01:15rhg135it's a very nice thing
01:15bmukI had heard before that clojure could compile to CLR as well, is that still a thing?
01:16dysfunwe've had a few discussions about that recently actually
01:16dysfunit's not what i'd call 'actively maintained'
01:16dysfunit still sees the occasional commit, but it's more a labour of love than something i'd deploy to production at this point
01:17dysfunhowever if in particular you wish to make games, arcadia is a clojure wrapper for unity
01:18bmukwell we're thinking about using clojure where it makes sense for us in production, if that ever means we could benefit from that I'd be happy to submit PRs for any bugs I find
01:18bmukat this point CLR interop isn't something I really need since I'm calling a json api anyway
01:19dysfunwell personally i'd love to see the CLR clojure get some more weight behind it :)
01:20dysfunscala abandoned their effort at .NET a few years ago, so clojure is basically the only JVM lang that also supports .NET basically in any fashion at all right now
01:20rhg135now that the CLR is OSS I can possibly work on it
01:20dysfunor the only one anyone has ever heard of, anyway
01:20bmukthat's what I was about to bring up
01:21rhg135before thenI'd have to sell a bit of my soul to MS
01:22bmukalthough you only get the benefit of OSS CLR if you upgrade your project to the latest .net, which has a lot of changes so it's an undertaking
01:22bmuklol yeah
01:22dysfuni considered it too, then i realised that the JVM is really very good and that .NET isn't offering me anything over that
01:22bmukdysfun, I think the utility is really more for MS shops that would like to incorporate clojure
01:22dysfunyes, absolutely
01:23rhg135also before then the only way to use it was to pay MS for windows, or hope mono has no bugs besides those in CLR (lmao)
01:23dysfunand sounds like you're one of those
01:23dysfuni thought mono *was* a bug?
01:23bmukhaha
01:23rhg135hence the lmao
01:24dysfuni think mono is a major reason why i don't like a standard linux desktop
01:24rhg135or even better, hope wine has no bugs (lmao-er)
01:24dysfunKDE is fugly and every GNOME distro either ships banshee (GTK#) or something ancient and shit for music
01:24rhg135I don't use mono except for writing C#
01:25rhg135KDE doesn't even use mono iirc
01:25bmukI'm a minimalist so I pretty much only use emacs, firefox, and terminal applications when in linux lol
01:25rhg135I just use an xterm with vim...
01:26dysfunwell, right now, i've got a terminal, emacs and firefox open...
01:26rhg135heh
01:26rhg135same here actually
01:26bmukthere's actually a pretty good music program for emacs
01:27rhg135except for the vim inside the remote connection in my terminal
01:27dysfuni haven't even plugged in my amp yet so no music on my desktop
01:27rhg135I had to fix a bug in my remote cloudbot
01:27rhg135because hot-reloading python is a great idea
01:28dysfundon't go there :)
01:28dysfunnaw, for real OOM action you need a JVM
01:28bmukdysfun: for when you plug in your amp: https://github.com/dbrock/bongo
01:28ben_vulpesi want my next computer to completely eschew audio
01:28dysfunbmuk: ta!
01:28rhg135I'm running this on a rpi model 1; any leak = OOM
01:29ben_vulpesaren't there consumer electronics for that?
01:29dysfunben_vulpes: for playing music? yes, i have a mac laptop here
01:29bmukrhg135: what is the feasibility of running clojure on an rpi?
01:29dysfunalthough itunes has started to suck since Steve Jobs died
01:29ben_vulpesi was thinking about the handheld devices...
01:30ben_vulpesdysfun: iTunes was rotting on the vine five years ago.
01:30ben_vulpesif not seven.
01:30rhg135bmuk: very feasible. It runs fine
01:30dysfunno, it was *ok* a few years ago
01:30dysfunrecently they just change everything for the sake of change
01:30ben_vulpesmuch like winamp, it achieved adequacy at its task and was bloated beyond recognition by user experience experts.
01:30dysfunand i'm finally going to finish writing my media organisation tool because i'm annoyed with it
01:30ben_vulpesdysfun: you don't say!
01:30rhg135just be careful with the ram, bmuk
01:31bmukI still have winamp installed solely for milkdrop
01:31rhg135no leaks
01:31ben_vulpesi just started a project out of rage at itunes and friends
01:31rhg135rage projects are nice
01:31dysfunbmuk: did you know milkdrop was created by some nutjob evangelical who wanted to stop people doing drugs by giving them pretty pictures without hallucinogens?
01:31bmukrhg135: that's what I was worried about. Probably a noob question but would running cljs under node alleviate some of that (v8 mem performance vs JVM)?
01:31rhg135that's why com.rhg135/killslack exists
01:32dysfunbmuk: if i were deploying to raspi, i'd use cljs
01:32rhg135you know, bmuk, I dislike cljs
01:32ben_vulpes> pretty pictures
01:32bmukdysfun: I did not know that lmao
01:32rhg135it's a neutered clj imo
01:32ben_vulpes> hallucinogens
01:33ben_vulpesmyeah because /that's/ what that's about.
01:33dysfuni dislike using a binary oracle jvm just to get acceptable performance of my clojure :)
01:33ben_vulpeswebstack
01:33ben_vulpesbest tech is proprietary
01:33ben_vulpes> jvm
01:33ben_vulpes> datomic
01:33dysfunbmuk: i don't think he anticipated that immediately everyone seeing milkdrop thinks "cool, wish i was on acid"
01:33dysfunthe jvm is not proprietary
01:34bmukI think that's called the barbra streisand effect
01:34dysfunslightly different thing, but yes
01:34tolstoyIs the Oracle JVM faster then OpenJDK?
01:34dysfunon ARM, yes.
01:34bmukcljs is useful because it runs client-side. I have no alternative client-side language with hot reloading and meta programming capabilities
01:35dysfunbmuk: much as i'm loathe to admit it, javascript fits that bill
01:35bmukI guess it would have to lol
01:35ben_vulpeshey
01:35ben_vulpeshey
01:35dysfunnot that i'm saying you should use js. nobody wants to
01:35ben_vulpeswhy not put the jvm in the browser
01:36tolstoyheh.
01:36dysfunbecause it would be a security nightmare. so glad they NEVER DID THAT.
01:36ben_vulpesno it'll be fiiine!
01:36ben_vulpeshahaha
01:36rhg135meta-programming in cljs? only at compile time
01:37bmukmeanwhile the captive portal at my old college was a java web app. NBD lol
01:37dysfuni can top that
01:37dysfunwhen i was over at nokia, we had to use this thing that was an activex control
01:37dysfunand on top of that it was completely shit
01:37bmukrhg135: I guess since I don't know it that well I'm assuming it has feature parity with clj
01:37rhg135keep the delusion, man
01:38rhg135you'll be happier
01:38dysfunrhg135: er, well since cljs is self-bootstrapping, it's not out of the question...
01:38ben_vulpesjavascript is an amazingly flexible language
01:38rhg135to be fair, people can get far with it
01:38tolstoyI worked at a place that went from Java Applet -> Perl webforms -> emailed Excel spreadsheets for procurement
01:38bmukhaha well no matter how behind it is I think I'd prefer writing cljs over Razor code
01:39ben_vulpesmy boss once made me implement a full delegate pattern in javascript
01:39rhg135dysfun: true, but even then it isn't now
01:39rhg135I mean noreified namespaces pfft
01:39dysfunheh, i was reading the gang of four this weekend ("Design Patterns"). I don't miss thinking in OO terms.
01:40jeayeUsing clojure clr, I can say (.name (first foo)) but I can't say (map .name foo), since .name ends up not being found.
01:40jeayeHow can I do it?
01:40dysfun#(.name %)
01:40jeayeAh, dirty
01:40jeayeWorks, thanks.
01:40rhg135js is a lisp in algol clothes more or less
01:40dysfunor memfn
01:41bmukfor a while when I started this job it was really hard for me to make my brain grok OOP again
01:41rhg135one of those mutable-happy ones
01:41dysfunrhg135: it's really not. lisp is all about the values
01:41rhg135js has values
01:41ben_vulpes> js is a lisp
01:41ben_vulpesOHOHOHO
01:41ben_vulpesHAW HAW HAW
01:41tolstoyJavaScript Isn't Scheme: http://journal.stuffwithstuff.com/2013/07/18/javascript-isnt-scheme/
01:41ben_vulpesman i don't know shit about shinola and even i find that entertaining
01:42rhg135it's the closest to in the mainstream rather
01:42ben_vulpessure
01:42dysfunwould just like to point this out at this point. McCarthy is pretty much the expert on lisp http://www.defmacro.de/?p=13
01:42ben_vulpesjust like "american cheese" is the closest to tillamook aged white cheddar
01:42ben_vulpesdoesn't make it fucking /cheddar/
01:42rhg135that stuff is disgusting
01:43tolstoyBut it's yellow-orange.
01:43ben_vulpesbut hey
01:43ben_vulpesit's "cheese"
01:43rhg135"american cheese"
01:43ben_vulpeslike js is "lisp"
01:43rhg135"cheese"
01:43bmukwhat happened to the lisp machines? Why would anyone ever move from having all the benefits of lisp all the way down to not having them?
01:44rhg135performance? maybe
01:44rhg135but lol
01:44dysfunbmuk: that's a surprisingly long story. suffice to say that in the end, efficiency won out
01:44ben_vulpesvery long story, but the long and short of it was that usg dole ran out.
01:45ben_vulpesi can play the unsubstantiated historical claims game too, dysfun !
01:45dysfunand these days we can have whatever environment we like, so long as we build it in software
01:45bmukdo you see us returning there at some point or does that even matter in our post-virtualization era
01:45ben_vulpes> whatever environment we like
01:46bmukexactly ^
01:46ben_vulpescategorically untrue.
01:46dysfunben_vulpes: but it's such a dull story. you really don't want me to
01:46ben_vulpesshow me a language that doesn't need bounds-checking.
01:46dysfunagda
01:46ben_vulpes(or perform it under the hood!)
01:46dysfunassembler
01:46bmukjust because an environment doesn't exist doesn't mean it cannot be done
01:47bmuktheoretically software can do anything
01:47dysfunanything 'technically feasible', yes
01:47ben_vulpesexcept for halt the processor, a la lisp machines.
01:47dysfunoh, you want to bring back the HCF instruction?
01:47ben_vulpesjust the H part
01:47tolstoyI think the era of an environment vs a collection of specialzed tools is over, alas.
01:47ben_vulpeschip could motherfucking loop in place
01:48dysfunyou do realise that the lisp machines weren't exactly fast, don't you?
01:48dysfuni can emulate one in software hundreds of times faster than they ran
01:48ben_vulpesofc
01:48ben_vulpesi have done some amount of research dysfun
01:48ben_vulpesdoubtless not as much as you
01:48dysfunhardware design is hard. ultimately we had to make computers dumber and more flexible
01:48ben_vulpesyou might even have been so lucky as to have worked with them!
01:49ben_vulpesnah, cheap micros for the masses one out.
01:49dysfuni have not worked with a lisp machine, but i've been doing lisp for a looong time ;)
01:49rhg135computers are rather fast these days to the point that I prefer working code
01:49ben_vulpeswe didn't "had to" anything.
01:49dysfunwe really did
01:49dysfunsociety demanded we have more computational power, and it needed to be provided
01:50ben_vulpeswhat "society" what "demand"
01:50ben_vulpesYours,
01:50ben_vulpesSociety
01:50ben_vulpes"a million chickens"?
01:50dysfunthere was a market for computational power. the demand increased and so people provided
01:50dysfunand the lispms weren't very good at it
01:50ben_vulpesgoodness, no
01:51dysfunand you could not have had a 2GHz lisp machine even if they'd kept plugging away at it
01:51ben_vulpesnor were gothic cathedrals frequently defensible castles.
01:51tolstoyAh, come on. The demise was part hardware, sure, but also no one really wanted a Big Environment (like Smalltalk, etc).
01:51dysfunyou're like my flatmate. he has a huge pile of antiquated hardware and goes on about how great it was. meanwhile i just want to get my work done
01:51tolstoyIMHO, Lisp Machine/Smalltalk --> Excel.
01:52ben_vulpesdysfun: you use vim, iirc?
01:52dysfuntolstoy: forth was the start of that
01:52dysfunben_vulpes: emacs.
01:52ben_vulpeshuh i wonder who i was thinking of
01:52dysfuni think justin moved to vim recently
01:52ben_vulpesdysfun: i don't object to the getting of work done!
01:53dysfunno, i mean i'm a pragmatist
01:53ben_vulpesheck, i work in clojure and don't crucify myself on cl or haskell or something.
01:53dysfuni have a lovely laptop, but it's not up to developing clojure, so i stole my flatmate's desktop
01:53ben_vulpesit's just hard to live on the c machine with sockets and what have you and read about how the lisp machines would let you talk directly to the nic
01:53dysfunhaha, most of my work is in clojure, but the last week i've been doing a lot of haskell
01:54ben_vulpesor the wonders of the symbolics typesetter, or the distributed lisp persistence layers they built...
01:54ben_vulpesand i see...mysql. postgresql. mongo.
01:54dysfunhave you looked at what they did for smalltalk?
01:54ben_vulpesfucking indesign
01:54ben_vulpesnah, symbolics depressed me enough
01:54ben_vulpesi know a guy who still works in smalltalk!
01:54ben_vulpesloves it. works on his own.
01:54dysfunsmalltalk had many good object databases
01:55dysfunprobably still does
01:55dysfunthere are still smalltalk implementations that cost money
01:56ben_vulpesbut the root of my gripe with compute is the end user development environment
01:56dysfunyup, it's terrible. but a lot of people are working on fixing it
01:56dysfunand clojure fares better than most
01:56ben_vulpesdunno about "fix"
01:56ben_vulpesseems rather unmendable from this novice viewpoint.
01:57dysfuni don't believe that to be the case
01:57ben_vulpesbut hey, clojure's a decent set of tentacles with which to wrassle the beast.
01:57ben_vulpesdysfun: but it's a matter of /belief/
01:57ben_vulpesneither of us are going to stake the next 20 years on making it happen, i don't think.
01:57dysfunyeah, but i've been programming for 16 years. i know what's possible by now
01:58dysfunand i put an enormous amount of time into open source work with one of the goals being to improve the development experience
01:58ben_vulpeslikely just a failure of imagination on my part.
01:58dysfunit's just something that comes with time
01:58dysfunand learning a lot of languages
01:58ben_vulpesdysfun: how've you been driving it forwards?
01:59ben_vulpesmore languages
01:59tolstoyWere Lisp Machines (etc) really about "software development", or were they just super sophisticated shells for people who needed to get other stuff done?
01:59ben_vulpesdysfun: ^^ ?
01:59tolstoyScientists, etc?
01:59ben_vulpes(i always imagined the latter)
01:59dysfunwell for a start, i've been working on a clojure llvm backend that has full tracing of what optimisation does to the code
01:59ben_vulpeswooooooooee
02:00dysfuntolstoy: they saw the beauty in what mccarthy did and thought "hey, this is a great why to think about code". but all code was academic back then really
02:00tolstoyYeah. So I think Excel is the spiritual successor, more than OSX, Windows, etc.
02:01dysfuni don't think there is a spiritual successor
02:01dysfunthe one thing we have truly lost is everything being a function
02:01tolstoyBut that's from a dev perspective, I'm talking a user/customer perspective.
02:01dysfunimagine if all applications were split into screens, android-style and each one was a function call away
02:02dysfunnow pretend you've made the UI over functions much easier, and suddenly the user can do a lot more
02:02tolstoySpiritual successor != better, just that it lest people do all the calculations, graphing, etc, etc, they want without "programming" with text files.
02:02ben_vulpesimagine if you could get into the guts of eg solidworks
02:02dysfunwe make enormous mistakes assuming that people who use excel are not good with technology. you'd be amazed what users do
02:03ben_vulpeshand-cranked asm too
02:03dysfuntolstoy: right, but the closest i can come up with is 'office'
02:03dysfunif anything, emacs is more of a spiritual successor
02:04dysfunbtw, if you want to know how good your software is, try and teach someone who is a non-programmer how to use it and then watch how they use it
02:04dysfun(for end user facing things)
02:05tolstoyI think that's a little bit what Brett Victor is after. Not better programming tools for programmers, but more appropriate idioms for getting work done that are, kinda, programming in the way Excel sorta is.
02:06dysfunhrm, i hadn't come across him, but i'm now reading his website. thanks :)
02:06tolstoyI remember trying to help someone get started with Java (back in the Ant days) and after hearing myself speak, I realized it was bat-sh*t insane. ;)
02:07dysfuni think it was feynman who said "if you can't explain it to a child, you don't understand it"
02:07tolstoyHe's the guy that inspired some of the early LightTable work, before it went all traditional.
02:07dysfunbefore it became a bit disappointing? yes.
02:08tolstoyI could explain it, I just realized that Java had so many, "Download this, okay, create a dir like that, okay, type this and this and this, then whatever.xml and, a couple of hours from now, you should be able to print hello."
02:08bmukwhat is the benefit of LightTable over emacs? Is it just that it sets everything up for you?
02:08rhg135Speaking of which, what happened to the author?
02:08dysfunbmuk: emacs is more powerful by far. lighttable is 'easy'. some people prefer it.
02:08tolstoyOf LightTable? Chris Granger (ibdknox) has a startup working on a new way for "regular people" to interact with data. Called Eve, or something like that.
02:09dysfuneve is disappointing too
02:09rhg135Yeah, but that was years ago
02:09dysfuni appreciate they've made a pragmatic decision that will allow them to get to market quicker, but they shouldn't have
02:09rhg135I'd not be surprised if he rage quit
02:10dysfunhis blog has been stagnant since Eve 0
02:11rhg135Indeed
02:11bmukI've often thought of emacs as the *best* interactive environment for text, but why do you think we still use text for programs? Is editing a string of characters really the most intuitive way to tell the computer what you want it to do?
02:11tolstoyHe tweets about it ever now and then.
02:11dysfunbmuk: no, but every time someone has tried graphical programming (i'm trying too!) it's come out shit
02:12tolstoyI bet non-text programming is really something that should be tuned to domains, rather than general purpose. Like that Brett Victor dynamic design language for circuits.
02:13dysfunyes, that's the area i'm heading in at the minute
02:13bmukI like the lego/puzzle approach that scratch has, but I've never actually used it
02:13dysfuni don't know how it's going to work for clojure, but for example in C++ you might have a "create new" > "Observer Pattern"
02:13dysfunyeah, the scratch blocks are a nice refinement. i've stolen them of course
02:14dysfunbut i also decided mutable variables had to go
02:14bmuktolstoy that sounds more feasible, I just think of all the times people are going to have to create interactive environments for each domain and I cringe. Repeating work bothers me
02:14bmukI think that's what drew me to macros, sometimes I can't really abstract this away with a function, I need something more powerful
02:15dysfunmacros are where graphical programming really falls apart for me
02:15rhg135You could have a core to build them with
02:15rhg135Sharing code ftw
02:15tolstoyIt seems much more difficult to "draw" a while loop, but using something to drag/drop to create music, better.
02:15bmuka DSL for making interactive graphical DSLs
02:16rhg135Exactly
02:16rhg135That's not confusing at all
02:16bmukclojure seems like you could have a map -> filter -> reduce pattern that is graphically represented somehow
02:16dysfunone of the things that's pissed me off doing this actually has been that GUI libraries fucking suck.
02:17dysfunit's very difficult to experiment when the libraries are so tedious to use
02:17bmukdysfun: why use GTK/QT at all, use HTML+CSS
02:17dysfunwell, that's what lighttable did
02:17dysfunbut i don't want to be tied to a browser
02:18tolstoyOSX has some sort of graphical thing you can use to hook up elements here to there ... quartz composer? Is that it?
02:18dysfunotherwise i wouldn't be doing an llvm backend for clojure
02:18bmukwhat do you mean "tied to a browser"?
02:18tolstoyKind of a neat visual language: (not that I understand it).
02:18dysfuntolstoy: are you thinking of automator?
02:18dysfunquartz composer is for building special effects
02:19tolstoydysfun That too, but I was thinking the graphical thing.
02:19tolstoyhttps://en.wikipedia.org/wiki/Quartz_Composer#/media/File:QuartzComposerSnowLeopard.png
02:19tolstoyJust an example of a specialized visual language, not general purpose, of course.
02:20dysfunoh there are many langs like that
02:20dysfunif you look on the code golf stack exchange, you'll see a few crop up on random questions
02:20bmukdysfun: wouldn't something like react-native divorce you from the browser?
02:21dysfunbmuk: i really haven't played with it
02:21bmukunrelated, where is mapcar? I'm getting unable to resolve symbol
02:21dysfunfor $startup, i'm encapsulating the bulk of the logic into a library and building a GUI for each supported platform separately
02:22dysfunthere isn't a mapcar in the standard library that i'm aware of
02:23bmukI'm an idiot. I meant mapcat, but I typed mapcar XD
02:23dysfunif you're using it to 'stripe' multiple lists, map supports that natively
02:23dysfunoh heh
02:25dysfunyou may also like http://conj.io/
02:25bmukthat's awesome, thank you
02:25bmukI've been using https://clojuredocs.org
02:26dysfuni tend to use ctrl-f rather than grimoire search though
02:26dysfunthe clojure cheatsheet is my fallback if arrdem breaks grimoire
02:27bmukI'm pretty sure I have grimoire in my editor already. Not sure how to use it though
02:28bmukhttps://github.com/syl20bnr/spacemacs/tree/master/layers/%2Blang/clojure
02:28bmukcider grimoire. I had no idea what it did until now
02:28dysfuncool :)
02:29dysfuni keep putting off changes to my emacs config because it sucks programming an inferior lisp
02:29bmukI used to make my own config by hand, but spacemacs does everything I want it to do. My config now consists only of enabling modes
02:30ben_vulpesimagine my surprise when i discovered that "superior lisp interaction mode" did not mean "a mode for interacting with a superior lisp"
02:30bmukBut I'm the weird variety that loves modal editing
02:31ben_vulpesbmuk: were evil-mode a little better, and were i to spend more time in non-lisps...
02:31dysfundon't most vim-using lisp programmers spend 50% of their time bouncing on the % key?
02:32bmukmaybe it's because I don't use enough of vim's features, but evil-mode is more than sufficient for me. I'm comparing it to Visual Studio's vim plugin though
02:32bmukdysfun: you can still use emacs chords in normal mode
02:32dysfunvim plugin is a comparatively easy proposition. an emacs plugin is basically impossible
02:33bmukplus there is a lisp-mode where you can structurally edit
02:33dysfunparedit?
02:33clojurebotparedit is not for everyone, but what you need to understand ís how to become the kind of person that paredit ís for.
02:34dysfunparedit would be for me, but i can't be bothered to learn it
02:34bmukhttps://github.com/syl20bnr/spacemacs/blob/master/doc/DOCUMENTATION.org#editing-lisp-code
02:35dysfuntbh a lot of internal emacs stuff needs overhauling a lot
02:35tolstoyI enabled paredit, then eventually learned on of the commands, and, centuries later, a second command. Still seems worth it just for the paren matching.
02:35bmuktrue. Isn't someone writing it in clojure?
02:35dysfunDEUCE? Yeah, but he wasn't getting anywhere last i checked
02:35ben_vulpesbmuk: lol
02:36bmukthere's also yi
02:36dysfunproblem he figured out is "if you can't run elisp, it isn't emacs". so he's spent a lot of effort there
02:36tolstoyAren't the making progress converting the underlying interpreter to Guile Scheme?
02:36prohoboatom is the new emacs
02:36prohoboexcept slow
02:36prohoboand buggy
02:36tolstoy*shudder*
02:36dysfunand browser-bound
02:37prohobobut it IS genuinely nicer
02:37dysfun(yes, it's still a browser if your app is a single-purpose browser)
02:37prohobothe UI is worth it imo
02:37bmukeven if you also provide a terminal interaction mode?
02:37prohobojust, dear god, dont do any remote work
02:37bmuk(not saying atom does this)
02:37ben_vulpesprohobo: single threaded?
02:38dysfunbmuk: you know, terminals are better at that
02:38prohoboben_vulpes: i think so, but it has these git extensions that require practically a full FS refresh on filesave
02:38bmukno, I mean you can use the GUI mode (single purpose browser), or the cli app
02:38prohoboso its easy to lock up your entire editor when saving something remotely
02:38bmukwhich both connect to a server running locally
02:39bmukthink emacsclient
02:39dysfunit's definitely about time that emacs became concurrent
02:39dysfunand got PCRE support
02:39prohoboi could never get minimap to work properly on emacs -_-
02:39dysfuneven still, all those libraries wouldn't get ported
02:40ben_vulpesit's pretty easy to lock emacs up too, fwiw
02:40prohobohehehe, u said "even still"
02:40prohobolike an italian mobster
02:40dysfunit's honestly a case of someone is going to have to quietly build a better thing and port the libraries themselves and then release it upon the world
02:40dysfunbut that's an impossible ask
02:40dysfunso we'll just keep using broken emacs
02:40bmukwhy quietly?
02:40prohobouse broken atom, maybe it will outpace emacs
02:41dysfunbecause it's a problem that needs hammock time
02:41dysfunand you can't have hammock time once it's unleashed upon the world
02:41dysfunwell, if it *is* actually better, anyway
02:41bmukI'm suggesting develop it OSS so you have help
02:42VapeNayshso i wrote a function that uses re-seq to convert matches into a new datastructure and do things to them
02:42VapeNayshmy test is comparing the result of this to another known value
02:42bmukhammock time -> document strategy -> github -> profit?
02:42VapeNayshand it appears to be failing because the first value is a lazy sequence still
02:42VapeNayshwhich is confusing
02:42dysfunbmuk: basically the plan, yes
02:43dysfunfor everything i do
02:43VapeNayshthe returned value looks good except its apparently wrapped in a lazy seq
02:43dysfunwell, i add "make it usable" to that list before github usually
02:43dysfunVapeNaysh: code?
02:44VapeNayshone sec
02:44VapeNayshhttps://gist.github.com/hderms/0429d709f6e511fc0ce8435088c284dd
02:44VapeNayshthis is some of it
02:44dysfunbmuk: i like to demonstrate the feasibility of something with some useful code before i publish
02:45dysfunVapeNaysh: you're comparing a set to a seq
02:45bmukmakes sense. Before I had a job I just used github like my private git server that just happened to be public
02:45VapeNayshyeah i'd like to return a set instead of the seq
02:45VapeNayshexpected: (= (str->pieces "Q2") #{[2 100] [2 101] [3 100] [3 101]}) actual: (not (= (#{[2 100] [2 101] [3 100] [3 101]}) #{[2 100] [2 101] [3 100] [3 101]}))
02:45dysfun(into #{} ...)
02:46VapeNayshahh ok
02:46VapeNayshgreat
02:46VapeNayshclojure is very elegant just challenging to learn idioms
02:46bmukso file-seq doesn't appear to be traversing child directories?
02:47bmukwait maybe I didn't reload my repl
02:48VapeNayshso (into #{} (str->pieces ...)
02:48VapeNayshright?
02:48clojurebotright is not wrong
02:48dysfunbmuk: try this http://raynes.github.io/fs/me.raynes.fs.html#var-iterate-dir
02:48dysfunVapeNaysh: yes
02:48VapeNayshit doesnt appear to be working
02:48VapeNayshits wrapping it with another set now
02:49VapeNaysh actual: (not (= #{#{[2 100] [2 101] [3 100] [3 101]}} #{[2 100] [2 101] [3 100] [3 101]}))
02:49bmukdysfun: I was using an old name for my function that was still left around in my repl
02:49bmukI'm pretty sure this works
02:49dysfunrepaste the code. you've probably gotten the arrow positioning wrong
02:49VapeNayshHERE WE GO
02:49VapeNayshoops
02:49VapeNayshi think i needed to apply
02:50dysfuni commented a suggestion on your post
02:51dysfunoh wow. i forgot the markdown syntax
02:52VapeNayshdysfun: replacing (into #{}) in your example with (apply set)
02:52VapeNayshworked
02:52dysfuncool
02:52VapeNayshthanks though
02:53VapeNayshis that code relatively idiomatic though or does it look bad
02:53VapeNayshlike threading macro, etc...
02:53VapeNayshusing maps and anonymous functions
02:53dysfunwell, i'd write it differently, but i'd need to see make-piece's code to give good advice
02:54dysfunthe art of good example code is giving something runnable so we can play with it in a repl
02:54VapeNayshwhat kind of changes woud you make
02:54dysfunwell for a start i'd abstract out that function in the middle
02:55bmukhow does this look so far: https://gist.github.com/bmuk/5899d95b6d510441f35993ab771ae6e2
02:56dysfunbmuk: well i'd rip out half of that code and use the 'fs' library i linked you to earlier, otherwise good
02:57dysfunexists? and directory? are already written for you and expand is subsumed by another function
02:58bmukthe library you linked to earlier?
02:58dysfun> bmuk: try this http://raynes.github.io/fs/me.raynes.fs.html#var-iterate-dir
02:58bmukexists? and directory? are already in the standard library?
02:58bmukhttp://clojure-doc.org/articles/cookbooks/files_and_directories.html
02:58dysfunno, they're in this library 'fs'
02:59bmukahh ok
02:59ben_vulpeshttps://github.com/Raynes/fs
02:59ben_vulpes?
02:59dysfunyes
02:59ben_vulpeshttps://github.com/Raynes/fs/blob/master/src/me/raynes/fs.clj#L148 << classy
03:00ben_vulpeswelp tooling day is complete
03:00ben_vulpesi have independent jvms for cljs and clj
03:01ben_vulpesthere is even a figwheel for normals
03:01ben_vulpesMY WORK HERE IS DONE
03:01ben_vulpes... for tonight.
03:03bmuknoob question, I can just :require [me.raynes.fs :as fs] after putting it in my project.clj? (I guess my real question is do you always remove the /)
03:03dysfunin this case, yes
03:03ben_vulpes[me.raynes/fs "1.4.6"]
03:03ben_vulpeswat
03:04dysfunhowever, there is not necessarily a mapping between the artifact name and the namespace
03:04dysfunben_vulpes: group-id/artifact-id
03:04ben_vulpeshttps://github.com/Raynes/fs/blob/master/README.markdown#the-most-recent-release
03:04bmukwhere is the namespace documented? Usually the README has had some example that I get it from but there was none in this case
03:04ben_vulpesbmuk: just start reading through fs.clj
03:05dysfuneither the README or the source files
03:05ben_vulpesor http://raynes.github.io/fs/
03:05dysfunthe README links to the API docs. i linked you earlier too
03:05dysfunthe api docs tell you what ns something is in
03:06ben_vulpessemi relatedly, is it not possible to get a line link to a markdown file in github?
03:06dysfuni've always assumed it wasn't, but if you find out it is, let me know :)
03:06ben_vulpesa brief investigation indicates that it is not
03:07ben_vulpesthanks obama
03:07bmukah okay. I know there has to be a way to automatically reload and require everything in cider on save, I'm getting tired of typing (require 'doc-generator.core :reload)
03:07dysfunhooks?
03:08ben_vulpesbmuk: if you're using cider, why not C-c C-k to load the file
03:08bmukI'm only familiar with mode-hooks but I guess there's probably a save hook as well
03:08dysfunbmuk: what is this json you're generating docs from btw? i'm curious (since i've got a docgen tool on the go)
03:11bmukI'm experimenting with the idea of rewriting our web app in cljs (since it's already a separate project from the core web service anyway), but our api is undocumented. So I added a finally block in the ExecuteOperation method (called for every api operation) that converts the request and response objects to json and logs them to a file
03:11bmukwith some other meta data that will probably evolve as this doc-generator does
03:12bmukI wanted to just start in on the cljs but proxying IIS from a VM to my macbook and sending incorrect json over and over again just to hit some breakpoints to see what was even going on was a nightmare lol
03:13bmukit wouldn't have been that big of a deal if our request and response objects were simple and flat, but they're pretty complicated
04:08ridcullydysfun: paredit and that sexp-somethingsomething plugin help to don't have to fall back to crude %
04:14dysfun:)
05:10qsysmust be easy: how to go from [2 3 5 7] to [2 5 10 17] (each time: get next and add it to the result so far)
05:11luma,(reductions + [2 3 5 7])
05:11clojurebot(2 5 10 17)
05:12qsyslol, easy it is :p
08:56russellwWhat is the recommended way to write parsers in clojure?
08:59kwladykarussellw do not write, use something what was done :)
09:01russellwkwladyka, well, if existing ones don't do what I need :)
09:02lumahttps://github.com/Engelberg/instaparse
09:03Glenjaminwhat is it you want to parse?
09:04russellwGlenjamin, dimacs, tptp, smt-lib
09:05Glenjamini expect using the existing java parsers as a base will be the best bet there
09:07russellwFrom a quick skim thus far, the dimacs parsers seem to be unmaintained, dimacs and smt-lib are syntactically simple enough that it's not worth incurring a tricky dependency for, the tptp parser doesn't seem to be currently maintained either and is missing some features and is written with a Java parser library, so a one-shot effort of just writing a TPTP parser in clojure seems likely to pay
09:07russellwoff better than dealing with that on an ongoing basis
09:08Glenjaminwhat does it mean to maintain a parser for something like that?
09:08Glenjamindo the formats change?
09:08russellwtptp certainly does
09:09Glenjaminthat seems a bit silly
09:09russellwNot disagreeing about that, but it's not up to me
09:09Glenjaminmm
09:09Glenjamini'd have assumed enough people were interacting with such things via java that you'd at least to be able to get some classes representing the data :(
09:10russellwYou can for some input files but not for ones that use language features the parser doesn't support
09:12russellwluma, thanks, that looks interesting. If I understand correctly, for a nontrivial language, you write the grammar in a text file - presumably lein can package a text file into an uberjar? instaparse wants to read the text file at runtime, but hopefully that only takes a few milliseconds, no significant performance impact?
09:12lumayep
09:13russellwCool, I'll try it out, then
09:13lumaif you already have your language in EBNF, you should be able to plug it directly into instaparse
09:23irctcHow to do the equivalent of int i = (int)l where l is a long in Clojure?
09:24Glenjamin,(int 100)
09:24clojurebot100
09:24Glenjamin(doc int)
09:24clojurebot"([x]); Coerce to int"
09:25irctc,(int Long/MAX_VALUE)
09:25clojurebot#error {\n :cause "Value out of range for int: 9223372036854775807"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Value out of range for int: 9223372036854775807"\n :at [clojure.lang.RT intCast "RT.java" 1205]}]\n :trace\n [[clojure.lang.RT intCast "RT.java" 1205]\n [sandbox$eval71 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval71 invoke "NO_SOURCE_FILE" -1]\n [clojure.la...
09:25irctcSo, it's not the same
09:26Glenjaminwhat does int cast do in java?
09:26Glenjamin(doc unchecked-int) you probably want this then?
09:26clojurebot"([x]); Coerce to int. Subject to rounding or truncation."
09:26Lewix,(int64 100)
09:26clojurebot#error {\n :cause "Unable to resolve symbol: int64 in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: int64 in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: int64 in this...
09:27Lewix,(long 100)
09:27clojurebot100
09:27Lewix,(long Long/MAX_VALUE)
09:27clojurebot9223372036854775807
09:27Lewixirctc: hew you go
09:27irctcI want the bottom 32 bits
09:30irctcyes, unchecked may be working
09:31Glenjaminlooks like it: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L1451
09:31irctcyep -- thanks!
09:32Lewix,(bit-shift-left LONG/MAX_VALUE 15)
09:32clojurebot#error {\n :cause "No such namespace: LONG"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such namespace: LONG, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "No such namespace: LONG"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]...
09:33Lewix,(bit-shift-left Long/MAX_VALUE 15)
09:33clojurebot-32768
09:33Lewix,(bit-shift-left Long/MAX_VALUE 14)
09:33clojurebot-16384
09:33Lewix,(bit-shift-right Long/MAX_VALUE 14)
09:33clojurebot562949953421311
10:22meliponeHiya! I have an incanter question
10:25meliponeI am getting an error with incanter 1.9 on the principal-components with the Iris dataset as in the example given in the documentation
11:16clgvhello, how exactly do you tell leiningen to work with metadependencies where maven central contains only a pom file with information about the other needed artifacts?
11:18TimMcYou just include the coordinates of that metadependency, yeah?
11:20clgvTimMc: well, it did not fetch anything but complained "Could not find artifact org.uma.jmetal:jmetal:jar:5.0 in central"
11:21clgvTimMc: providing [org.uma.jmetal/jmetal "5.0" :extension "pom"] just makes Leiningen happy enough to not complain, but none of the artifacts is fetched
11:22TimMcInteresting.
11:30TimMcCan reproduce with 2.6.1
11:51TimMcclgv: Looks like half of this is discussed at https://github.com/technomancy/leiningen/issues/1451
11:51clgvTimMc: ah thank you
11:52TimMchttps://github.com/technomancy/leiningen/issues/1866 is linked from that, might be the same issue or different
11:52TimMcI think different.
11:53clgvwell, manual deps then...
11:53clgvluckily there are only 4 of them ;)
12:00Glenjaminwhy would they do that?
12:00Glenjamin(have a pom-only thing)
12:31bsimaDoes anyone know of any custom core.async buffer types? I'm thinking about creating a buffer that interfaces with kafka logs, thus creating an immutable channel
12:31bsimathis is the only one I've found so far https://github.com/steveyen/ago/blob/master/src/ago/core.cljs#L102-L147
12:36dysfunumm, why would it be a buffer?
12:36dysfunthe purpose of a buffer is to... buffer
12:37dysfunif you wanted to treat kafka as a queue, you would instead connect a kafka client to a channel
12:37dysfunso that each time you became aware there was something for the taking, it placed it onto the channel
12:39dysfunand for publishing, you would publish to a channel and the kafka client would transmit it
13:00bsimadysfun: If I can mimic the core.async api, then I can reuse a lot of code
13:01bsimain development I use channels to pass maps between components, but in prod I want this data to be stored in kafka
13:02bsimayeah its kinda blurring the lines between "queue" and "channel" and "log", but I don't think thats a problem
13:09tolstoyMaybe make a super set abstraction with core.async and kafka implementations?
13:19sdegutisGood evening.
13:20sdegutisHow is it?
13:23dysfunbsima: it's not an idiomatic way of modelling it
13:23dysfunthe idea of channels is to disconnect the sender from the receiver. that you happen to put another process is a non-event. your application code remains otherwise the same
13:31sdegutisWhat is Up?
13:31dysfunthe sky?
13:31dysfunthe opposite of down?
13:32Glenjaminbsima: dysfun one of the best explanations of the difference I've heard was that channels cannot fail
13:32Glenjaminbut as soon as you put a network in there, you have problems you now need to deal with
13:32russellwFor a function that takes a filename as input, parses the contents of the file and returns a syntax tree, what's the typical/idiomatic name for the function? load-foo, parse-foo, read-foo, something else?
13:33dysfunGlenjamin: i'm not going to pretend the picture is perfect, but better to deal with that in one place
13:33Glenjamin(foo/parse) perhaps?
13:33sdegutisdysfun: no its a movie
13:33Glenjamindysfun: i guess that depends on whether you plan to make every component optionally in another process
13:33sdegutisOne which I will not say whether it is good or bad, because I refuse to pass judgement on such a crappy movie.
13:34russellwGlenjamin, ah, so use the fully qualified name and let the module name be the root? That makes sense, thanks
13:34dysfunGlenjamin: we're not erlang
13:34dysfunsdegutis: how many litres of beer does it take to make it watchable?
13:35sdegutisdysfun: nobody counts in litres anymore, its the 90s man
13:35dysfunlitres are a much better unit than pints. they're a lot bigger for a start
13:35sdegutisget with the times dude
13:35sdegutisnobody counts in pints anymore, what is this medieval yourup?
13:35dysfunare you drunk again?
13:35sdegutisGood evening. How are you all doing this fine day?
13:36sdegutisdysfun: i dignify to refuse that with an answer
13:36dysfunhard day at work, was it?
13:37sdegutisOur CEO and I just had a nice long meeting.
13:38sdegutisAfterwards I sent an email suggesting we may want to make use of more agile ways of communication, to increase productivity in development and other areas of our respective tasks.
13:39sdegutisAgile is big here, so he agreed and we're going to move forward with this, and benefit from it all around.
13:39sdegutisSo yeah, it's been a productive day.
13:39sdegutisI'm about to start programming in a minute.
14:10utoHow I merge two maps while preserving the order? Basically (merge {:a 1 :c 2} {:d 3 :b 4}) returns {:a 1 :b 4 :c 2 :d 3} but I want {:a 1 :c 2 :d 3 :b 4}
14:10opqdonutmaps don't have order
14:11opqdonutthough there is sorted-map
14:11opqdonutif you care about order you should probably use a sequence of pairs
14:12rhg135ordered-map too
14:13opqdonutrhg135: where is that?
14:14rhg135I don't remember exactly
14:16tolstoyhttps://github.com/amalloy/ordered
14:16opqdonutright
14:19tolstoyGood code there to help figure out what you have to do to implement something that satisfies map.
14:20russellwHow do you get instaparse to ignore whitespace between tokens?
14:22sdegutisuto: or you can turn a map into a sequence of map-entries
14:22sdegutis,(map-entry? (first {:a 1}))
14:22clojurebottrue
14:22sdegutis,(map type {:a 1})
14:22clojurebot(clojure.lang.MapEntry)
14:23sdegutis,(map type {:a 1, :b 2})
14:23clojurebot(clojure.lang.MapEntry clojure.lang.MapEntry)
14:23sdegutisuto: you'd probably turn them into a coll of map-entries by sorting it
14:23sdegutis,(->> {:a 3 :b 2 :c 1} (sort-by val) (map type))
14:23clojurebot(clojure.lang.MapEntry clojure.lang.MapEntry clojure.lang.MapEntry)
14:24sdegutis,(->> {:a 3 :b 2 :c 1} (sort-by val) (map (juxt identity type)))
14:24clojurebot([[:c 1] clojure.lang.MapEntry] [[:b 2] clojure.lang.MapEntry] [[:a 3] clojure.lang.MapEntry])
14:24sdegutisThere there.
14:32sdegutis(doc val)
14:32clojurebot"([e]); Returns the value in the map entry."
14:32sdegutis(doc key)
14:32clojurebot"([e]); Returns the key of the map entry."
14:38lokien_Heyy guys, is there any list of functions/macros everyone should know? Like "top 100 functions" or something?
14:39russellwlokien, http://clojure.org/api/cheatsheet
14:41lokien_russellw: that's like "every function"
14:41lokien_but probably I'm wrong
14:41russellwI don't think it's quite every function, though it is impressively comprehensive for such a compact document
14:43lokien_I'd like something different, but thanks, still
15:06kwladykaI wrote article when use vars, atoms, agents, refs and async. I share it with you http://clojure.wladyka.eu/posts-output/2016-04-06-concurrency.html Please give me feedback if all is clear. Maybe i can improve something? It is very complex topic and i want stay with short text. What do you think about flowchart? Do you agree with it? Any idea how can i do it better?
15:09kwladykaI feel i can do it better but i need some feedback :)
15:14Glenjaminkwladyka: i'd say the var example, while it works, isn't very representative
15:15kwladykaGlenjamin do you prefer example with binding or what kind of example?
15:15Glenjamingenerally vars are only used at the top level, and are there to make late binding work when evalling stuff at a repl
15:15Glenjaminin practice, they don't really change at runtime i'd expect
15:17kwladykagenerally this article don't explain all possibilities and power of them. As i mentioned on the beginning. It is more to which one should i choose for me, then about how to use it in most powerfull way. I guess then i can write separate topic for each of them. But from other side maybe i should give more examples...
15:18Glenjaminthe examples you have are fine, i just think the vars example is showing something that no-one really does
15:20kwladykayes, but it showing technical aspect how it is working. Can you propose better example?
15:20Glenjamini wouldn't categorise a var as a concurrency construct at all actually
15:21Glenjaminyour flow chart is correct that if the data ever changes, you shouldn't use a var
15:21kwladykabut what i saw people ask what to use and also include varts to the question
15:22Glenjaminmy usual advice is: use an atom until it doesn't work
15:22amalloythe ref example is bad, because (println "read, foo:" @foo "bar:" @bar) isn't enclosed in a dosync
15:22kwladykahaha ;)
15:22amalloyso you might read inconsistent values
15:23kwladykaamalloy but alter is in dosync. How can i get inconsistent values then?
15:23amalloyyou can read foo, then a commit happens, then you read bar
15:23kwladykait is exactly to show that alter will commit when dosync end
15:24amalloytry throwing a (Thread/sleep 5000) in between those two derefs
15:24kwladykaamalloy it is exactly about that it can't happen
15:24kwladykait is why to use refs
15:24amalloythen it is exactly wrong
15:24kwladykadid you read text?
15:25kwladykawhat is wrong there
15:25kwladyka?
15:25amalloydid you try my suggestion?
15:25kwladykahang a sec
15:27kwladykaamalloy between which one? In println?
15:27amalloyyes
15:27amalloyin the "read", not "updated", thread. the one that's not in dosync
15:28amalloydosync/alter guarantee that if you take a snapshot of the world at any time, all refs will be in a coordinated state. but you don't do that: you take *two* isolated snapshots, with your two derefs
15:28amalloyhow can the runtime possibly know you intend those two to be coordinated
15:29kwladykaoh because println don't read them in the same time, it is very small chance for that, but it is. Thanks for suggestion.
15:29kwladykaof course not in this example, because alter run longer, but generally i can do better example
15:30kwladykathx
16:25kwladykaI just did new version http://clojure.wladyka.eu with some improvements
16:31kwladykaWhat do you think now about flowchart?
16:35lokien_kwladyka: as a still learning person, thank you for that
16:36kwladykalokien_ nice to hear that :)
16:38TimMckwladyka: You might talk about how it is unsafe to modify vars from more than one thread at once, and modifying them at all is generally not something to rely on.
16:38lokien_kwladyka: can you make more posts like this in the future? I feel like they're needed in the community, as we don't have anything like that yet
16:39kwladykaTimMc it is good idea, but i am not sure it will be still in the topic
16:39kwladykalokien_ i am trying but it consumes so much energy and time :)
16:40lokien_kwladyka: keep going, I believe in you :)
16:40kwladykalokien_ i can recommend also read article how to improve algorithm speed, that was my mile stone in clojure.
16:40TimMckwladyka: As it is, it looks like you are putting vars on the same level with constructs that are used as data structures, and that might mislead someone into trying to use set! to bash on vars
16:40lokien_kwladyka: 4 boring classes tomorrow, I'm sure I'll read that :D
16:41TimMcOh good, you do cover that in the flowchart.
16:41kwladykaTimMc is good or bad? :)
16:42kwladykaTimMc can you propose better example for vars?
16:42TimMcThat's good, I think it would be better to include a very short statement in the vars section about how vars are not generally intended for modification.
16:43TimMcIn the flowchart, I don't think the non-idempotent functions branch should lead to refs.
16:43TimMcSame for the long-running functions branch. Refs can have contention, just like atoms.
16:43TimMc(Well, differently than atoms, actually.)
16:46kwladykamaybe i should add additional condition but not sure what should be the question
16:47kwladykaTimMc what i now refs retry when read the same ref more then one time if it was alter on that ref during that. Any other cases?
16:48kwladykabut generally read the same ref in dosync more then once is not something common
16:48kwladykai don't know other cases when ref retry
16:51TimMckwladyka: Refs are modified optimistically. If two threads try to modify the same ref during concurrent transacations, one backs out and retries.
16:52TimMcIf there were side-effecting calls during the transaction, you might get in trouble.
16:52TimMcYou might also want to draw a distinction between idempotency and side-effects.
16:53sdegutisHey amalloy.
16:55kwladykaTimMc not if you call side-effect after alter :P But yes you have right. I should do additional question in flowchart, but not sure how to do it clear.
16:57WorldsEndlessWhat library is recommended for making API requests (get, post, the others)?
16:57TimMcHTTP calls?
16:57WorldsEndlessYeah
16:57sdegutisWorldsEndless: I use clj.http-lite or whatever it's called
16:57sdegutisWorldsEndless: it's got minimal dependencies and does all the things i need
16:58kwladykaWorldsEndless Clojure or ClojureScript?
16:58TimMchttps://github.com/dakrone/clj-http is pretty nice
16:58WorldsEndlesskwladyka: Just Clojure
16:59sdegutisTimMc: yeah thats the one that links to the one i use
16:59WorldsEndlessTimMc: Looks like the one that http-lite thinks is too heavy
16:59kwladykaWorldsEndless so like TimMc wrote
16:59sdegutishttps://github.com/hiredman/clj-http-lite
16:59WorldsEndlessAny major reasons to go with http instead of http-lite?
16:59sdegutisWorldsEndless: look at "Differences from clj-http" on my link
16:59sdegutisWorldsEndless: if you need any of those then go with http-fat
17:00sdegutisWorldsEndless: i did not need any of those things so i went with http-light
17:00WorldsEndlessGot it. I don't think I need any of those things, either, unless I end up needing the JSON decoding
17:01sdegutisWorldsEndless: it doesnt do *automatic* json decoding, but you can still decode your own json from the :body key
17:01sdegutisWorldsEndless: i use clojure.data.json to decode the :body key into a json thing along with http-skinny
17:01kwladykaWorldsEndless light has last update a year ago
17:01sdegutiskwladyka: when a thing is done, its done.
17:01WorldsEndlesslol
17:01sdegutisif it aint broke, dont fix it
17:02WorldsEndlesssdegutis: Said like an emacs user?
17:02kwladykagenerally i most of cases it means something
17:02sdegutisWorldsEndless: i use 'choose'
17:02kwladykabut in that one of course it can be ok
17:02sdegutishttps://github.com/sdegutis/choose/commits/master
17:02sdegutislast real-world commit was march 2015
17:02sdegutisi mean real-stuff commit
17:02sdegutisand hey it still works 13 months later
17:03kwladykalast time of commit is my personal decisive factor. Software is never done :)
17:04sdegutiskwladyka: i used to think that way too.
17:04sdegutiskwladyka: sometimes inactive software is actually just done though.
17:05kwladykain the readme i can read "No support for insecure HTTPS connection (yet" and last commit is a year ago
17:05kwladykaIt is enough for me to choose http-clj
17:05sdegutislike, 'choose' does one job but does it well. the only time ill ever need to update it is if Apple changes some API and deprecates any of the ones this uses on like OS X 10.15 or whatever
17:05sdegutiskwladyka: then choose http-big
17:06kwladykabut still it is my personal decisive factor form my experience. Find you own way :)
17:07WorldsEndlessYeah, the "supported" factor is a big one, given that this app should have longevity and maintainability
17:09sdegutisWorldsEndless: thats a hard thing to predict
17:10sdegutisWorldsEndless: for example predicting dommy vs domina was hard
17:11sdegutisand if you looked at their commits, they're both relatively inactive about the same amount
17:12kwladykaTimMc I am thinking about flowchart and what you said... but when somebody use not idempotent functions and need synchronise access there is nothing better then refs. Isn't it?
17:54sdegutisTIFU by using some? on a value that had a boolean value returned.
17:55sdegutisI mean some? is great but I need to be more careful about these things.
18:00parenjitsuI'm curious, is there any consensus about the best libraries for spinning up a convention-over-configuration API server with Clojure?
18:01amalloyshell out to rails
18:01parenjitsuPretty much just authentication, and then a thin serialization layer between http and the database
18:01parenjitsuamalloy: I hadn't considered that
18:02amalloywell it's not really good advice, so much as a claim that clojure doesn't really do "convention over configuration"
18:02Glenjamin(inc amalloy) that made me chuckle
18:02amalloyif that's an important feature for you, try rails or python
18:02parenjitsuYeah, that's kind of a community thing
18:03parenjitsucultural thing
18:03parenjitsua clojure version of Rails API would be awesome
18:04parenjitsumaybe a good lost weekend project
18:04Glenjaminwhat would it do that rails api doesnt?
18:04parenjitsuI guess what I would get out of it would be:
18:04Glenjaminthere is compojure-api and liberator, but afaik they don't attempt to deal with either auth or databases
18:05parenjitsu1. I could spin up a database, api-server and clojurescript frontend boilerplate in a couple minutes
18:06parenjitsu2. If the API layer needs to get smarter, I can write it in clojure, instead of ruby
18:08patchworkparenjitsu: You can pretty much do this with luminus, last I checked
18:08parenjitsupatchwork: I'll give it another look, thanks
18:08parenjitsuHadn't seen compojure-api before either. The swagger integration looks great.
18:09parenjitsu(been away from clojure for a few years, trying to get back up to speed)
18:13{blake}Ever-changing-poorly-documented-fragile-convention Over Configuration!
18:14{blake}That said: I'm using straight JDBC for a web app and now I want to allow the user to page through results of a select. Opinions?
18:14GlenjaminLIMIT?
18:14Glenjamin:D
18:15{blake}Brilliant! A series of calls using "Limit 1" should produce just what I need!
18:15Glenjaminwhich bit did you want an opinion on?
18:15{blake}Heh. Paging isn't really a big issue here. The database isn't so big that I =shouldn't= be able to load it all into memory.
18:16Glenjamini'd normally do a count, and then render page links with offset=x&pagesize=y
18:16{blake}It's a one-at-a-time viewer.
18:16parenjitsu{blake}: usually the client would pass in a page parameter and that would transformed into OFFSET and LIMIT to get the appropriate results
18:16Glenjaminoh, then y=1 and it's easier
18:16parenjitsulol
18:16{blake}parenjitsu: Oh, so I really can do "Limit 1" if I combine with "Offset"! Ha!
18:17{blake}I can't believe Codd & Date would approve somehow.
18:18Glenjaminone thing you want to watch out for, is new items getting added during paging
18:20{blake}Or deleted, I presume. Shouldn't be an issue here.
18:20{blake}I'm mostly trying to figure out if it's worth it to switch from straight JDBC.
18:20{blake}To any of the multitude of SQL libs.
18:20Glenjaminunlikely, i don't think they'd help here
18:21{blake}I'm only suspicious because that's the answer I want.
18:22Glenjaminthey mostly help you write SQL, although I do quite like yesql
18:24{blake}They all look okay, but I feel like they all would take time to get up to speed. Maybe not much, but I'm...behind. =P
18:37srrubyloop/recur - Can I use let to define local variables ?
18:38justin_smithsrruby: locals of what scope?
18:38srrubylocal to the "invocation of the loop".
18:38justin_smithsrruby: within one iteration, definitely, if each iteration might modify the binding, it goes in the loop binding vector instead
18:38srrubyThanks.
18:44sdegutisright
18:48tolstoyIf I want to have a little "storage" data structure that I persist to disk on change, would it make sense to have it implement the IAtom protocol or the IPersistentMap protocol rather than come up with something custom?
18:49tolstoySeems like (assoc storage :key "value") implies immutable values, while (swap! storage assoc :key "value") at least suggests it's mutable.
18:49amalloytolstoy: my first step would be to do none of that, but instead research the thousands of other attempts people have made to implement this exact feature
18:49amalloythere is probably one that meets your needs
18:50justin_smithtolstoy: I would attach a single thread to a queue, and put the modifications to that data structure on the queue. This could be expressed as a function that sends an action to an agent, a core.async go block looping on a chan, or a java concurrent queue with a thread polling it
18:50Glenjaminadd-watch -> spit
18:51tolstoyamalloy: Good idea, I'll do that.
18:51tolstoyjustin_smith: That's implementation, I'm talking about the interface.
18:52Glenjamini do like how lots of clojure libs start their README with a picture of something
18:52amalloyyou're going to have a hard time making something that's truly atomic in the face of multiple threads when you involve the disk
18:52amalloyso you'll have to decide what kind of contract you want to support
18:53amalloy*then* you can start looking at things like justin_smith's and Glenjamin's suggestions, which each do some rather surprising things in the case of concurrent modification
18:53tolstoyBut is it just a bad idea to implement those existing Clojure interfaces, all that other taken of?
18:53Glenjamini mostly suggested mine as a contrast to demonstrate the range of possibile answers
18:53amalloyimplementing IAtom might be fine
18:54ben_vulpesdoes anyone know how to get the string that clojure.java.shell/sh tried to evaluate back out of it?
18:54amalloyimplementing IPM would be evil imo
18:54amalloy"tried to evaluate"?
18:54hiredmanimplementing IAtom for something that only wraps a map seems really weird
18:54hiredmanand you would need to do really weird stuff to implement (swap! … assoc k v)
18:54hiredmansince assoc works on maps
18:55ben_vulpes"tried to evaluate" -> "passed to Runtime.exec()
18:55ben_vulpes"
18:55Glenjaminhaving assoc write to disk seems weirder though
18:55asdf12z_what is the symbol ^ mean?
18:55hiredmanimplementing IPM for something that isn't a value is terrible
18:55asdf12z_does*
18:55ben_vulpesamalloy: ^^
18:55Glenjaminasdf12z_: metadata
18:55amalloyben_vulpes: that's the arguments you passed to shell yourself
18:55amalloyjust look at them before you call shell
18:55hiredmanasdf12z_: http://clojure.org/reference/reader#_metadata
18:56amalloyhiredman: does it only wrap a map? i was imagining since he's just going to use pr-str/spit/read-string/slurp, it would work for other non-map things
18:56Glenjaminben_vulpes: you could trace it perhaps
18:57hiredmanamalloy: could be, but if that is the plan, why the heck would tolstoy be talking about implementing IPM?
18:57amalloyover-focus on the current situation, where what he's thinking of persisting happens to be a map
18:59hiredmananyway, either way, do neither
18:59hiredmaneither using a map or a map in an atom
18:59hiredmandon't implement anything
18:59tolstoyHeh. Well, that's the safe route.
19:00ben_vulpesGlenjamin: nah i just thought really hard for a half second
19:00Glenjaminusually a good bed
19:00Glenjaminbet
19:00Glenjamineugh
19:02hiredmanwhatever you do, don't decide the transient interfaces make more sense, then implement them for a mutable store that obviously doesn't have transient semantics then submit it to lobsters so everyone can see how cool it is
19:02Glenjaminyeah, submit to r/clojure instead
19:03ben_vulpesAA
19:03ben_vulpesAAAAAA
19:03ben_vulpesAAAAA
19:03ben_vulpeshiredman: scary.
19:04hiredmanand then sits on the lobsters frontpage for a while, which tells you how much of a grain of salt to apply to that sort of thing
19:05amalloyi hadn't heard of lobsters till now
19:06hiredmanit is a thing
19:06tolstoyIt's somehow ... better ... than hacker news, right?
19:06amalloy"better"
19:08hiredmanslightly less startup stuff, which is nice, trends slightly more technical
19:09tolstoyI don't see a lot of "persist / cache a data structure to disk" things out there. Must not know the right keywords.
19:09tolstoyI'm not worried about implementing it myself. Just was curious about using some Clojure interfaces for a basic key/value thingy.
19:09amalloyhttps://github.com/alandipert/enduro is the first one i found
19:09hiredmantolstoy: atoms that use watchers to read and write to disk are a common thing people do
19:09hiredmanI would recommend using apacha derby
19:10tolstoyDerby seems too heavyweight for two or four keys. (I'd use h2, probs.)
19:10amalloyit has plenty of problems in the face of concurrency
19:11hiredmanlobsters big, I dunno, claim to fame?, is the user tree, to get an account you need an invite, and you can go look at the tree of invites https://lobste.rs/u
19:11amalloytolstoy: if you want more reading, searching for `clojure persistent durable atom` works pretty well
19:11tolstoyOkay. I just found konserve.
19:11amalloyLobsters 'R' U
19:11Glenjamintolstoy: what is your wider context here?
19:11tolstoyApp needs to generate a couple of UUIDs that need to persist across restarts. No persistence other than that.
19:12Glenjaminhow much do you care about data loss?
19:12tolstoyBUT, I might like to make a component out of it. And maybe store some additional stuff when running in simulator mode.
19:13tolstoyGlenjamin Reasonably concerned, but if a sysadmin comes along and kills the file, well, *shrug*.
19:13Glenjamini was thinking more along the lines of synchronous vs asychronous write
19:13tolstoyThis is code running on a device shipped to customers. It does connect to the "cload". IMHO, a better solution is that it calls home with a hostname and gets back an ID. ;)
19:14Glenjamindo said uuids change?
19:14tolstoyOh, well, I wrote my own fatom before and used core.async, I think. Maybe locking.
19:14tolstoyThey shouldn't.
19:14Glenjaminyou could just write text to disk on first start i suspect
19:14tolstoyYes.
19:15tolstoyAnd never change it ever after. That works.
19:16tolstoyAnyway, it sounds like if someone had a good reason to write a file-backed "thing" such that adding or removing stuff from it was reflected on disk, implementing IAtom is sketchy, and IPersistentMap is misleading (at best).
19:18tolstoyThen again, enduro does that.
19:20Glenjaminwhy do I keep reading HN :(
19:44rhg135implementing IPM for a file write, that's wow
19:51tolstoyLay it on me, buddy.
20:05rhg135I'm sure in certain languages that'd be great
20:06rhg135along with 1 = '1'
20:07tolstoyWell, I didn't think it was a good idea, so I won't defend the unmitigated temerity it took to publicly suggest it. ;)
20:14rhg135the sad part is I know there's people who think it's a good idea
20:38VapeNayshhey so using loop/recur. If I want to like start the bound values with defaults would I wrap the (loop ...) form with some kind of (let..) binding
20:39VapeNayshlike first iteration it starts with let bound values but every further iteration will loop rebind them and shadow over the let binding?
20:42VapeNayshis this the right way to do something like that
20:45VapeNayshnvm im stupid
20:45tolstoyIf you do (let [xs (foo x)] (loop [xs xs] .... (recur (rest xs)))) ... (foo x) is only called once. ;) Okay. ;)
20:47VapeNayshyeah i saw that loop has bindings
21:45asdf12z_uh when i run lein repl, it's not installing my dependencies? lein deps :tree looks ok
21:46asdf12z_oh nevermind
21:57bendlasdo ^:unsynchronized-mutable deftype fields still work?
21:59sdegutisGood morning.
22:02sdegutisjustin_smith: I have a race condition, help.
22:42asdf12z_so if i wanted to make a constant, but local to a function, how would i do that? just use let? is there a performance issue over using def ?
22:46machinewarhttps://gist.github.com/AlexWheeler/84503e2fe46c37f2f2dcd31a294e49f8 having trouble with basic reduce function, when I call (even-or-odd [1 2 3 4 5]) I get (5)
22:47machinewarexpecting {:evens [2 4] :odd [1 3 5]}
23:10hiredmanit would be illuminating for you to print the arguments to your reducing function
23:10hiredmanalso maybe print out what the function returns every time it is run
23:12hiredmanor just, sort of step through it in your head, what are the arguments the reducing function will get the first time it is called, what will be returned from it
23:20TEttingerreductions can be handy too.
23:20TEttinger,(reduce + [10 20 30 40])
23:20TEttinger,(reductions + [10 20 30 40])
23:21clojurebot100
23:21clojurebot(10 30 60 100)