#clojure logs

2015-09-20

00:09TEttingerdomokato_: still around?
00:10rritochWhat is a "dev-resources" folder for? I've never really noticed it before but when I setup a new clojure project in eclipse it added a dev-resources to the java build path but didn't actually create the folder.
00:11rritochI also don't recall seeing dev-resources in any project, or ever needing anything comparable.
00:11rhg135resources you don't want to ship
00:14rritochrhg135: Cool thanks. So it's more useful for proprietary projects, like a licence key for developers to bypass restrictions, or for parts of the system that aren't yet ready for release.
00:23rritochrhg135: Is there a comparable folder for source code? Such as a main entry point that isn't needed in a distributable library but is provided for testing other than unit tests?
00:38amalloyrritoch: you can roll your own by adding to :source-paths in your :dev profile
00:39amalloynothing built in that i know of. i think mostly nobody minds including their -main in a library jar
00:41rritochamalloy: Thanks. I'm not entirely sure I'll ever need that, I haven't needed it so far, but at least I can add it to my stockpile of coding trivia :)
01:15rritochIs there a "best practice"/naming convention for a "with" function that returns a promise instead of a value? Such as (with-gui-thread #(do (print "GUI OK") true) . Using with for this seems deceptive since the return value won't yet be fully defined when it returns.
01:17justin_smithwhen you say promise, do you mean function?
01:17justin_smithbecause we have promises, and that isn't one
01:19rritochjustin_smith: I'm writing a function, that with the aid of a macro and some other magic is going to perform a given function and arguments and return a promise. That promise will be fulfilled when the function is executed in that other thread.
01:19justin_smithOK, your code example didn't have any promise in it, so I wasn't sure
01:20rritochsorry, t was just simpled that that function was in some way defined to return a promise instead of a value.
01:20rritocherr
01:20rritochIt was just implied
01:21jeremyliterritoch: "with" usually implies some additional context. in this case, it's your gui thread. so i think that's fine
01:21jeremyliteto return a promise
01:22justin_smithI still have no idea where the implied promise was supposed to be in that example. Does with-gui-thread return it? does the anonymous function return it?
01:22justin_smithI mean the one that never gets called
01:23rritochjustin_smith: Yes, with-gui-thread will create and return a promise
01:24jeremyliterritoch: on second though, maybe "on-gui-thread" or "invoke-gui" or something like that
01:24rritochI was just thinking that with seems deceptive, like maybe it should be future-with or some other name.
01:25justin_smithto my eye, a with-* is a macro that takes your code and puts it in some other context, so it would take a &body instead of a lambda
01:25jeremyliteyeah
01:25justin_smithalso, how is this different from future - just the fact that it runs something on a specific existing thread?
01:25rritochjeremylite: Hmm, I think invoke is a good idea, like "invoke-with"
01:26rritochjustin_smith: Yes, that's the only difference. It is going to run on a specific thread.
01:27justin_smithI'd make that function, and call it call-in-gui, then make a macro that expands to putting the body in an anonymous function supplied to call-in-gui and call that with-gui-thread
01:28justin_smithand yeah, return a promise that the caller can access later
01:35rritochjustin_smith: If I use a macro instead of a function won't that eliminate the possiblity of being able to map over it? Such as (map #'invoke-with-gui-thread job-list)
01:36justin_smithrritoch: I said invoke a function, the macro is just a convenience
01:36justin_smithand it becomes inconvenient if you want to map (but don't do that, because map is not for side effects)
01:37justin_smithrritoch: I only suggested the macro because you suggested with-foo and that's how a with-foo would work, turn a body of code into a function and then put it into the right context for evaluation
01:38rritochjustin_smith: Well, I'm still debating function -vs- macro for this, the function is using a macro internally. I really don't know a way to do this without macros.
01:39justin_smithdef is a macro, let is a macro, everything uses macros internally
01:39jeremyliterritoch: he's talking a function like (defn call-on-gui [f] (call-on-thread *thread* f)) and a macro like (defmacro [&body] `(call-on-gui (fn [] ~@body)))
01:40jeremylitethe functino is more useful, but the macro adds sugar
01:41justin_smithfunctino, heh, I do that typo all the time
01:42jeremylitelol
01:42justin_smithwe should totally make something called functino for making small inline functions or something
01:42jeremylitejustin_smith: i keep typing "litearl" instead of a "literal" and i think of james earl jones being high
01:42justin_smithhaha
01:43jeremyliteyou know, functino, the core.logic operator for functin, duh
01:44justin_smith"duude - hear me out now, what if the death star is just a symbol of our hubris, man, like we have an intergalactic empire but want to be gods, create worlds, destroy them" *puffs*
01:45emdashcommawell
01:45emdashcommayou're not wrong
01:45jeremylitelol
01:46justin_smithI can totally picture Vader getting stoned. Of course he would vape though.
01:48justin_smithalternately, Thulsa Doom, he would roll blunts
01:48emdashcommahe'd try to force choke the wall, and giggle unconrtollably
01:48justin_smithhaha
01:51justin_smithemdashcomma: force lightning to spark the bowl, followed by a force-choke on his piece instead of using a carb
02:11rritochWhat about x-quiet vs x-stfu , I really prefer the stfu but god-forbid clients ever look at the code.
02:11domgetterIs there a way to make a set of maps where the uniqueness of the members is determined by one of the values of a key each of them has?
02:12justin_smithdomgetter: sorted-set-by will only keep 1 of each return value for its sorting function
02:13domgetterawesome Ill look at the docs for that, thank you
02:13justin_smithdomgetter: so if what you want is to keep only one map for a given value of :key, then (sorted-set-by :key ...) would do what you want (as a side effect of the sorting that I am sure you don't need)
02:13rritochmy last question was rhetorical, for entertainment purposes only.
02:13justin_smith,(sorted-set-by :k {:k 1} {:k 2 :v 1} {:k 2 :v 2})
02:13clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Comparator"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Comparator"\n :at [clojure.core$sorted_set_by invokeStatic "core.clj" 412]}]\n :trace\n [[clojure.core$sorted_set_by invokeStatic "core.clj" 412]\n [clojure.core$sorted_set_by doInvoke "core.clj" -1]\n [cloj...
02:14domgetterjustin_smith: well I do want them sorted by their :create_at date, but I want them to be unique by their :id
02:14justin_smitherr...
02:15justin_smith,(sorted-set-by #(apply compare (map :k %&)) {:k 1} {:k 2 :v 1} {:k 2 :v 2})
02:15clojurebot#{{:k 1} {:k 2, :v 1}}
02:16domgetterAnd that will enforce uniqueness and sortedness on the same key, correct?
02:17justin_smithyes
02:17domgetterokay cool, thank you
02:17justin_smiththat is how sorted-set-by works - it always enforced uniqueness by the sorting key
02:44rritochI ended up using a macro for my invoke-with ... it was the cleanest solution.
03:08rritochShort of assigning all defrecord fields as atoms, is there a way to establish two-way bindings between a defrecord and a user interface? I need events triggered each time a field changes so the system can update the GUI.
03:11amalloysince a record (which is just a fancy map) is immutable, you can't really have a specific instance of defrecord be synched with something that can change. you could, of course, have an atom that points to different records over time
03:11justin_smithsounds like react
03:11justin_smiththe api for reagent is pretty close to that
03:22domgetterIs there a reason why this is happening? https://gist.github.com/anonymous/e8e658619f9b92f2bfca
03:22domgetterI thought swap! ran apply, so I wouldn't get a nested vector
03:22rritochThanks,. For this case it sounds like I need two record types, one for values which don't change often so it can reasonably be maintained in a "watched" atom, and another which contains values which change often and need individual fields watched.
03:22justin_smithdomgetter: no, swap! does not run apply
03:22justin_smithdomgetter: just use into, or provide the 3 and 4 as separate args
03:23justin_smith,(def a (atom [1 2]))
03:23domgetterHow do I supply them as separate args
03:23clojurebot#'sandbox/a
03:23justin_smith,(swap! a conj 3 4)
03:23clojurebot[1 2 3 4]
03:23domgetterthat is, if I can't do it literally
03:23justin_smith,(swap! a into [5 6])
03:23clojurebot[1 2 3 4 5 ...]
03:23justin_smithdomgetter: literally works, as above
03:23domgetterah I see
03:23domgetterok thank you
03:24justin_smithor you can use into if you need to provide them as a coll
03:24justin_smithdomgetter: it mentions apply ... args but note that it's arg list has & args
03:25justin_smithso args will be a coll, containing all your args, I hope that makes it more clear
03:25justin_smith(doc atom)
03:25clojurebot"([x] [x & options]); Creates and returns an Atom with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn If metadata-map is supplied, it will become the metadata on the atom. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validate-fn should return false or thro
03:25justin_smith(doc swap!)
03:25clojurebot"([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."
03:25domgetterah okay, that makes sense
03:25justin_smithoh, that's a bad doc string :P
03:26domgetterso I'm not crazy :P
03:26justin_smithif you are going to refer to "args", then bind args in the doc string, hah
03:26justin_smithI mean in the args list
03:26justin_smithbut you get what I mean
03:26domgetterI think into works for what I want
03:29justin_smiththe funny thing is when you combine swap! with update*
03:29justin_smith,(swap! a update 2 * 42)
03:29clojurebot[1 2 126 4 5 ...]
03:29justin_smithlike forth in reverse
03:53sotojuanjustin_smith: do you ever sleep? Every time I log on you are here ;D
04:19roelofHello, Im looking at living clojure for learning clojure. Can I start with the exercises and read the chapters that are involved or can I better read everything first and do the exercises after it
04:21domgetterroelof: Probably better to read a chapter and then try the exercises.
04:22roelofdomgetter: that is what I mean. but the book has two parts. First the explanations and after that a training part.
04:38amalloyjustin_smith: in my 1.6 repl that docstring reads "args", not "..."
04:39roelof domgetter maybe first read everything and look at the examples and then do the training weeks
04:50javahippieroleof: why not 'code along' on your own while reading the theory? This way you could get a better grasp of it and afterwards do the trainings
04:53domgetterroelof: My only advice is to not spend too much time thinking about the best way to do it. Just choose a strategy and do a little each day.
04:54roelofjavahippie: I could do that but then I have to have a idea what to programm
04:54roelofdomgetter: oke, thanks for the tip
04:56domgetterOnce you learn that you can do things, you'll dream up projects, I guarantee it
04:56domgetterAnd the more tools in your toolbelt, the more imaginative and confident you'll be
04:56domgetterAnd Clojure offers some pretty powerful tools :)
04:56roelofdomgetter: I think I know a project for in the future. or a ecommerce site or a accounting site
05:12javahippieroleof: I meant, coding along the examples in the relp. Maybe, read a chapter about sequences, fool around with them in the repl
05:12roelofjavahippie: thanks for the tip
05:14roelofI have a quick read of chapter 1 of the Living book and I think I can do something with it
05:19roelofFirst install clojure on my ubuntu box :)
05:27roelofCan I just do apt-get clojure or can I better make a project and use the newest version as a dependency
05:28javahippieroleof: does your book mention leiningen?
05:29roelofyes, it does
05:29roelofit says first make a project
05:30javahippiethat sounds good. See following link: http://clojure.org/downloads section 'Get Clojure via Leiningen'.
05:31roelofaha, and I see if I do lein repl clojure 1.7.0 is installed :)
05:31javahippieYep, it is part of the initialization routine (if you want to call it that way)
05:45roelofThanks all, Im now working trought chapter 1 of living clojure
05:47javahippieroleof: have fun! maybe give a little feedback from time to time about how you like the book ;)
05:56domgetterIf I'm in the lein repl, how do I load core.async so I can play with channels?
05:57domgetterOr do I have to explicitly set it as a dependency in a project.clj file?
05:59javahippieAs far as i know, dynamically adding dependencies is quite difficult, without additional tools. I remember it being a classloading issue
05:59javahippieI prefer to work with the project.clj
05:59domgetterah okay fair enough
06:00javahippienever tried it, but maybe this is what you are looking for: https://github.com/pallet/alembic
06:13roelofjavahippie: did you write it ?
06:17javahippieOh, no. Far from it :D I am just interested in the quality of different books. I find it incredibly difficult to keep track about it
06:23RaynesWell AWS sure just ain't doing well right this moment.
06:23RaynesDynamoDB is ded and apparently everything depends on it according to newrelic telling me all my shits dying :D
06:24RaynesHow's everyone else's Sunday morning?
06:28roelofjavahippie: I did read the first chapter and did the examples and I like it. Everything is explained very well on a way a beginner understand it
06:31mungojellywhat does ^{} mean
06:36mungojellyok so my problem involves numerous things that are just slight variations on one another, which persistent data structures are awesome for, except i'd also like to persist them as in write them to disk sometimes, how can i remember things and maintain that space sharing, except of course to use datomic
06:41hellofunkmungojelly: ^{} is for adding meta data, not something you will need most of the time
06:41hellofunkRaynes: pretty good, yours? still in l.a.?
06:41RaynesWell pretty terrible since all my shit's dead and all but hey I could be dead.
06:42RaynesStill in LA, yessir.
06:42lodin___mungojelly: IIRC transit does that, i.e. it can refer to a previously serialized entry in the structure.
06:42hellofunkyour shit is dead? isn't shit supposed to be dead? that is why it is flushed.. ?
06:42mungojellyhellofunk: i'm not trying to do it but i'm reading the code for JDBC and it's used a lot there so i wanted to understand what i'm reading :)
06:42RaynesYou're looking for lodin- sir.
06:42RaynesNot hellofunk.
06:42hellofunkmungojelly: for understanding basic logic, you don't really need to pay attention to metadata most of the time
06:43RaynesOh wait, nevermind
06:43RaynesI can't read.
06:43RaynesI should go to bed.
06:43hellofunkRaynes: how are those fires out there, did you start them?
06:43RaynesOr play Heroes of the Storm.
06:43RaynesI mean unless I somehow stepped on a butterfly and caused a hurricane in us-east-1, doubt it was my fault.
06:43mungojellylodin-: this transit-clj thing from cognitect? ok i'll learn about that thanks :)
06:45mungojellyin general it seems sad to me how bad our programs are at communicating so far, i bet sometime soon all the programs will start talking, the silence will end, but we'll think about it just in terms of some particular data exchange format, like how we understood the hypertext transformation to be about "HTML"
06:46lodin-mungojelly: Right. I'm not 100 % sure, so please let me know if I remembered correctly. :-)
06:55mungojellylodin-: transit seems to know how to serialize basic values, compound values and can be extended by teaching it new types, but i don't see anything about preserving structure sharing or references. looks useful in general, certainly better than speaking directly to JSON! :)
06:57ianhedoesitam I stupid or is there a problem with the invite site for the clojurians slack channel?
06:57ianhedoesitclojurians.net gives an error when I try to get an invite. it's saying the token provided has insufficient privileges, basically.
07:06mungojellylodin-: oh ok well i'm not sure i quite understand yet how to do it but this http://swannodette.github.io/2015/02/19/transit-js-caching/ says you can get it to cache references by writing custom handlers that say to do the caching hm
07:24lodin-mungojelly: I have not used transit myself, so I thought that the caching was not only for map keys.
07:39mungojellylodin-: it's for nothing and anything, it'll handle things based on a custom handler, so if your write handler says put my symbol by which i mean backreference, and your read handler reads and reinflates the back references, voila
07:41mungojellyi don't need to drag the data back out often so i'm trying the strategy of just compressing it, i find that's wiser often than trying to be clever :)
08:05visofhi guys
08:05visofwhat is the performance of take and concat?
08:06roelofhello, how can I take care that a character is printed out instead of #<Atom@1322f9d: here is my code so far : http://lpaste.net/141361
08:07domgetterroelof: You need to "dereference" the atom. Every time you want what's inside an atom, put a @ in front of its name
08:07roelofoke, I will try that
08:08mungojelly,(let [a (atom "contents")] (println @a))
08:08domgetterso on line 28, it should be (println @directionX)))))
08:08clojurebotcontents\n
08:09mungojellythat's the first time i ever said @ yay it worked
08:09roelofdomgetter: then there is more wrong. I do not get a output at all
08:09domgetteralso, on lines 22 and 25, you need @thorX
08:10domgettersince it's an atom, and youre trying to compare its value
08:10roelofoke, changed it
08:10roelofI try to do a challenge of codeingame with clojure
08:11domgetterMay I ask what (= thorX > lightX) means?
08:11domgetterare you trying to check if @thorX is equal to lightX? Or are you trying to check if it's larger than lightX? Or something else?
08:12roelofof course it means if the current postion (ThorX) is smaller then the end-position(LightX) then the direction must be W
08:13domgetterI think you might want (< @thorX lightX)
08:13roelofyou are right
08:13domgetterthat says "@thorX is less than lightX"
08:16roelofoke, now this part (if (< @thorX lightX) (swap! directionX "E")) gives this error message : xception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
08:17domgetterroelof: You want to use reset! instead of swap! to set an atom to something in particular
08:17domgetteryou'd use swap! if you want to use a function on the atom, but here, you just want to set it to the string "E" directly
08:17roelofoke, I wil try that
08:18domgetterchange (swap! directionX "E") to (reset! directionX "E")
08:18mungojellythe second argument to swap! is a function that gets applied to the thing to change its value, like (swap! thing inc) is like thing++
08:20roelofyes, first part is working :)
08:21roelofis this good clojure : http://lpaste.net/141362
08:22domgetterlooks alright. The important thing is, do you understand it?
08:47crocketuncle bob said clojure deserved to be the last programming language or the seed of the last programming language in 2011.
08:49crocketThe last programming language to rule it all.
08:50crocketIf only clojure could handle the metal directly.
08:51roelofyes, I wrote every piece of it
08:52roelofthen now the y part and chancing the ThorX and ThorY. I can use the swap for the last one
08:54roelofbut is every time using a def for a variable in a loop is good ? Can I not better do the def before the loop and do also a reset! to make them empty ?
08:55mungojellythere is no metal, modern cpus just pretend to be the old cpu architecture so that's a virtual machine now too
08:58mungojellythey split the asm "instructions" into parts, they smashed even those, and then the actual metal rearranges how those smashed partial instructions are pipelined for efficiency, so it jit compiles everything down into a language that very few humans can begin to understand and that literally no one speaks
09:08xikuukyHey guys.
09:09xikuukyI came from a Hylang/Python background, I use functional coding and what not. Will Clojure be a good language?
09:09mungojellyxikuuky: i just started a few weeks ago but in my opinion clojure is a ridiculously good language. so good.
09:10mungojellywhat's a hylang, never heard of it, sounds like it would be the programming language of hyrule
09:10xikuukymungojelly: Is it static?
09:10xikuukymungojelly: A Pythonic Lisp
09:10mungojellyis what static? are what static?
09:11xikuukymungojelly: Static is where every type is set in stone while dynamic is where every type is defined on a need to know basis.
09:11mungojellyit allows mutable state but strongly encourages a style focused on immutability, by providing and supporting awesome practical immutable structure
09:11mungojellyoh in its typing. it's very dynamic.
09:12crocketIs it possible to have dependent types in clojure?
09:12crocketWould it be wieldable?
09:12mungojellythere's a typed variant called typed clojure that i've just started to find out about, but around here it's mostly untyped.
09:12xikuukymungojelly: Yay!
09:13xikuukyI really don't like static languages. I worked with C#, F#, VB, the whole deal and I didn't think it was so great all the time/
09:17mungojellyin fact the style around here is very terse, there's this clever thing where hashmaps can be used as functions, from key->value, and also hashmap keys can be used as functions, from map->value, which sounds odd for a moment but then reads just splendidly
09:17mungojelly,({:a 1 :b 2} :a)
09:17clojurebot1
09:17mungojelly,(:a {:a 1 :b 2})
09:18clojurebot1
09:19mungojellyso that's used eeeeeeeeeverywhere to just say, i want the :this from the {that}, i've got a map called stuff, i want the thingy from the stuff, so either (:thingy stuff) or (stuff :thingy) gives me what i want
09:22crocketCan clojure go close to the metal?
09:22mungojelly,(let [thingy {:a 2 :b 5}] (* (thingy :a) (thingy :b)))
09:22clojurebot10
09:22mungojellycrocket: there is no metal
09:23crocketYou don't know what I mean by metal.
09:23budaiis it possible to check if a record implements a specific protocol?
09:24gfredericks,(doc satisfies?)
09:24clojurebot"([protocol x]); Returns true if x satisfies the protocol"
09:24budaigfredericks: thanks :)
09:25mungojellycrocket: the ground reality for clojure is the jvm, or for clojurescript javascript, it doesn't help you dig below there. because you really really shouldn't for almost every purpose.
09:26crocket'almost'.
09:26crocketFor writing kernel, you should.
09:26crocketFor writing system libraries, you should.
09:26crocketThat's not 'almost'.
09:26gfrederickswell the answer for clojure will be the same as whatever platform you're on, generally
09:26mungojellywrite just the performance sensitive parts in c and expose them as a library. it's not ideal but that's what everyone does.
09:27gfredericksso by deciding to use clojure on platform X you're agreeing to whatever restrictions platform X has in that category
09:27crocketI'd like to see a natively compiled variant of clojure.
09:27crocketNativeClojure, maybe.
09:27crocketThe platforms are x86 and so on.
09:28crocketIt should have built-in garbage collection.
09:28mungojellyclojure as a language is tied closely to the semantics of the jvm and indeed to the java libraries
09:28crocketSo, I said 'variant'.
09:28crocketOr, a new langauge heavily inspired by clojure.
09:28gfredericksmungojelly: that's not true, cljs and clj-clr are both things
09:29mungojellygfredericks: i've been wondering, how much code actually works across all of them?
09:29wasamasanot much
09:29gfredericksmungojelly: more and more, thanks to cljc
09:29mungojellyit seems like in practice things are mostly for one platform or another, but i don't have a sense for the details
09:29gfredericksexcept for the clj-clr part but only because nobody uses it
09:29wasamasayup
09:30crocketcljs is terrific except tooling.
09:30crocketgfredericks, Is it possible to create a single source folder for both clojure and clojurescript?
09:31gfrederickscrocket: yes, reader conditionals is a new feature in clojure 1.7 for sharing the same files
09:31gfrederickse.g., test.check will soon have a mostly unified codebase that works on the jvm and cljs
09:31crocketgfredericks, Do the build tools facilitate using single source folder for multiple languages?
09:32gfrederickscrocket: yep
09:32crocketI haven't read a tutorial that teaches how to do it yet.
09:32mungojellydo we have any libraries for generating c? oh there's this c-in-clj thing, how's this work
09:32crocketI started learning clojurescript a while ago
09:32gfrederickscrocket: github.com/gfredericks/test.chuck does
09:33crocketCan a web app pull it off, too?
09:33crocketisomorphic source base for server and client.
09:33gfredericksyou can certainly share source when that makes sense
09:33gfrederickse.g., if you want business logic shared on both ends then you can do that easily
09:34crocketWhat kind of build tools support that?
09:34gfredericksleiningen
09:34crocketlein-cljsbuild?
09:34gfredericksyep
09:34gfrederickssee test.chuck linked above
09:34crocketI'm not sure how it's done, yet. I'll get there.
09:34gfredericksanother portable lib: https://github.com/gfredericks/exact
09:35crocketgfredericks, Can you recommend the best clojurescript learning material?
09:35crocketClojurescript: up and running is quite old.
09:35crocketI already know clojure.
09:35gfrederickscrocket: I think the wiki on github is supposed to be decent
09:36dnolenmungojelly: re: code sharing, ClojureScript is easily the most significant .cljc project, some 7000 lines of shared code so the compiler can run on JVM or JS
09:37crocketgfredericks, It refers me to several tutorials.
09:37crocketThey all overlap.
09:37crocketThey all overlap largely
09:41crocketgfredericks, Did you read clojurescript: up and running?
09:45crocketDamn...
09:45crocketIf clojure could be used to write kernels and operating systems, it would rule the world.
09:47gfrederickscrocket: no; I've been using cljs for >3yrs now so have no idea what modern tutorials are like
09:48crocketGod damn you
09:48crocket3 years
09:48crocketYou should be a clojure expert by now.
09:49crocketgfredericks, Do you think dependent types can be introduced to clojure?
09:51gfrederickscrocket: any static type system is a tough fit, as the language just wasn't designed with that in mind
09:52crocketStatic typing and dependent typing might save big projects with many devs.
09:52crocketHaskell comes into mind.
09:52crocketIf google is found today, it'd use haskell instead of C++.
09:52crocketHaskell wasn't mature enough when google was growing.
09:53gfrederickscrocket: I've been seeing a lot of similar benefits from prismatic/schema + test.check
09:53crocketWhat do they do?
09:54hyPiRioncrocket: Google uses mainly Java internally, actually.
09:54crocketOh
09:54crocketThey do the work of static typing.
09:55emautonThat's not at all true, FWIW: the languages used there are mostly C++, Java, Python and Go, in roughly that order.
09:57crocketI'm not sure if clojure should be the langauge for writing AI infrastructures.
09:57crocketJVM
09:57crocketJVM deters me.
09:57crocketIt's hungry of RAM.
09:58emautonRAM is cheap, please try to forget that.
09:58crocketRAM is not cheap
09:58crocketRAM is cheap for big companies
09:58crocketThat kind of thinking only makes hardware manufacturers richer.
09:58hyPiRionemauton: re C++: Really? Has it changed the last 1.5 years, or have I only been in contact with the "higher level" infrastructure?
09:59crocketCompared to OCaml, JVM uses ungodly amounts of RAM.
09:59emautonhyPiRion: I guess the latter. I've been out for 1.5 years myself. :o)
09:59crocketNow, OCaml is quite performant.
10:00crocketemauton, If RAM was so cheap, why don't you run linux on JVM?
10:00emautoncrocket: I'm sorry, I won't be engaging with this anymore.
10:00crocketWrite kernel in java
10:00emautonJ
10:01sotojuano.O
10:02crocketI want to see C killed.
10:02hyPiRionemauton: hah, alright then, I stand corrected. I've only talked to some Chrome devs, and they said that most services was Java, only outliers like Chrome/"low level" infrastructure was C++.
10:04crocketPeople nowadays launch java processes in VMs because dev time is as expensive as or more expensive than hardwares.
10:04crocketThat doesn't mean hardware is cheap.
10:05crocketIf you're desining client applications, you'll realize that ordinary people do not have 64GB of RAM.
10:06noogathat's why you move logic to the "cloud"
10:07noogait's called SaaS ;D
10:07crocketWell, if you are designing native GUI applications and system libraries, you don't have that kind of luxury.
10:07crocketSmartphones have 1-4GB of RAM.
10:09crocketSo, the assumption is that you're a cloud app developer.
10:09crocketThen, RAM is cheap.
10:10crocketHowever, people still miss the experience of native GUI apps.
10:10sotojuanI think most people nowadays are.
10:10crocketweb browsers are slower.
10:10crocketThey are limited
10:10crocketsotojuan, That's because of web bubble.
10:11visofhi
10:12visofi have list and function and want to apply function of list per element but each result of invocation is the input for other?
10:13visof(defn foo [x] (* x x)), (foo x), (foo (foo x)), (foo (foo (foo x)))
10:13visofhow can i do this?
10:14emautonvisof: Sounds like you might want http://clojuredocs.org/clojure.core/iterate
10:18emauton,(take 4 (iterate (fn [x] (* x x)) 2))
10:18clojurebot(2 4 16 256)
10:57jimmy---If anyone's got a moment to critique a macro that's like defn, but produces a curried version of the function, I'd love feedback. Notes, questions, and usage supplied in the link. Many thanks! http://pastebin.com/mBLMtLkX
11:01justin_smith(-> args count (= 0)) => (zero? (count args))
11:07justin_smithactually no => (empty? args)
11:10justin_smithjimmy---: you don't need gensyms, because no symbols created in that let body are emitted - it's just transforming forms and using existing symbols, not emitting any new symbols
11:14justin_smithjimmy---: `(defn ~name ~args ~body) => (list 'defn name args body)
11:15justin_smith(list `~args `~body) => (list args body)
11:16justin_smith(cons 'defn (cons `~name (seq `~all-bodies))) => `(defn ~name ~@all-bodies)
11:19lodin-jimmy---: I don't know if it's good or bad, but I almost always prefer syntax quote over constructing the result manually, even if it's just (list args body).
11:19justin_smithlodin-: to me it just ends up looking like cargo cult macro making. Use syntax quote if it's more concise and clear, if it isn't don't use it.
11:20lodin-justin_smith: I use it precisely because I think it's clearer. :-)
11:20jimmy---justin_smith: re:gensyms: OK. I personally didn't see any way that I could clobber anything, but I've been wrong plenty of times before.
11:20justin_smithlodin-: there's no way (list `~args `~body) is clearer than (list args body)
11:21justin_smithjimmy---: no symbol you create ends up in the output form
11:21lodin-justin_smith: I mean of course `(~args ~body).
11:21justin_smithlodin-: OK, I was talking about the actual code
11:22justin_smithand even compared to `(~args ~body) I find (list args body) much more clear
11:22lodin-justin_smith: Interesting.
11:23jimmy---justin_smith: I haven't thought it through entirely, but isn't it possible to clobber something in the code to be transformed by the macro within something like a let within the macro?
11:24lodin-I use `() as a way to tell the reader (= me) that "this will (probably) end up in macroexpand". I don't use it if I plan to pick it apart and manipulate it further.
11:24justin_smithjimmy---: your macro does not transform any symbol that comes in, and it does not emit any symbol that isn't a: in clojure.core or b: in its input already
11:24justin_smithjimmy---: you can't possibly clobber within those constraints
11:25justin_smithlodin-: `() is valid both inside and outside macros
11:25lodin-justin_smith: Sure.
11:28jimmy---justin_smith: Sorry, I wasn't clear. I just meant in general when writing macros, but I guess the fact that gensyms exist answers my question.
11:30lodin-I also tend to write `([~@args] ~@body), and not care about which sequence type args happens to be. I think this is much clearer than e.g. (conj args body), which might sound weird, but if I were to highlight only the syntax quoted code in a macro (and in code-returning functions used in the macro), I get a pretty good picture of how the resulting code will look.
11:30justin_smithjimmy---: that's true, and for that reason if you use let or defn inside ` it will force you to use gensyms
11:32jimmy---justin_smith: Ahh, OK, I didn't know it was forced within `. Good to know.
11:33lodin-jimmy---: Another point: I think it is customary that body is a seq, e.g. (defmacro foo [stuff & body] ...). If it's not several statements, call it "expr" or something. This is just my experience from having looked at some macros.
11:33justin_smithit's essentially a side effect of ` ns-resolving every symbol, and you can't let-bind ns-qualified names
11:41jimmy---lodin-: OK, I'll move away from the name 'body' in my case then. Thanks.
11:41jimmy---justin_smith: Ahh, right, that makes sense then.
11:42lodin-jimmy---: Why not change to [... & body] and adjust accordingly?
11:56jimmy---lodin-: Hmm... I'm trying to work it out. I just wonder if someone were to then look at it, if they'd expect to be able to send arities themselves, and then there's a whole new problem.
11:56lodin-jimmy---: I don't follow.
11:59jimmy---lodin-: Now one just sends a single argument, expr. If they saw it takes [name args & body], they might try to supply their different arities as such: (defcurried f ([] "no args") ([x] "one arg") ([x y] "etc."))
12:00jimmy---lodin-: And then maybe expect (if there were gaps in the arities) for the currying to "just work."
12:00lodin-jimmy---: Maybe, but I don't find it likely, really.
12:01lodin-[name args & body] is not [name & fn-tails]. The args is outside the seq, but in your example the args are in the seq.
12:01jimmy---lodin-: I agree, the likelihood is extremely small as I expect the number of users who use this to be countable on one thumb. :)
12:01lodin-jimmy---: I wouldn't worry about it.
12:03lodin-It's not necessary to use & body either, since you can always just use (do ...), but I think it is more likely that your users assume that you can add a leading assert or prn without it (and end up being confused by the error message).
12:06lodin-jimmy---: What are you porting, btw?
12:07jimmy---lodin-: OK. Got it afloat with & body now. Good practice if nothing else.
12:08jimmy---lodin-: I was going through the functional parsers section of the Graham Hutton Haskell book.
12:10jimmy---lodin-: I was giving pixie-lang a whirl, saw it could read json, but not output it, and realized I didn't really know much about parsing and looked into that.
12:10jimmy---lodin-: But then I ended up using protocols instead, but am going back to the parsing stuff now because it seems useful.
12:23justin_smithjimmy---: why would you parse anything in order to generate json?
12:23justin_smithjimmy---: usually when generating json you have data structures already in your program that you want to emit
12:24justin_smithand there's no parsing in that, unless you are doing it the hard way, turning the structures into strings, parsing them again, and then making json out of that?
12:27jimmy---justin_smith: For a json-in, json-out program, it's not simply emitting.
12:28justin_smithOK, you already mentioned it had json reading, I guess I misunderstood
12:29justin_smithso, you realized it couldn't write json, so decided to implement both reading and writing?
12:32jimmy---justin_smith: I've only done the writing thus far, which was a breeze, and was all that I actually needed given the reading was provided. But parsers weren't covered in my school's curriculum, so I'm just looking to fill that void at this point.
12:36justin_smithahh, got it
12:36justin_smithhopefully they at least covered FSMs
12:39jimmy---justin_smith: It was gone over pretty quickly when covering regex. So we saw them and the BNF notation, but didn't put it to code unless you count regex.
12:40justin_smithgot it
12:47kavkazI know this isn't #emacs, but do you guys have any idea how to change the color of the menu bar and the scroll bar?
12:48trissso is there any work in the pipeline to make it possible to have :pre and :post conditions emit custom error messages?
12:49trissI'd love to be able to embed Strings that described the problem encountered in the error thrown
12:51hellofunkkavkaz: what menu bar? what scoll bar? :)
12:52kavkazhellofunk: one second, i'll send you a screenshot
12:52hellofunkkavkaz: i am jesting with you
12:52kavkazhaha
12:52hellofunkkavkaz: most emacs users (well many) do not use those features in emacs at all and have the GUI turned off
12:53hellofunktriss: the pre/post map already shows which pre/post expression failed, in its message
12:54justin_smithkavkaz: there's faces defined for the menu and scroll bar and tool bar that you can use to set foreground and background colors
12:55trisscheers hellofunk. I'd love to be able to provide a message like I do would with `assert`
12:55trisscould make my library a lot more friendly
12:56justin_smithyeah, pre / post are very uninformative, I just do asserts instead, much more flexible in representation and in output
12:56justin_smithI mean it's an OK idea just not polished enough to be actually useful for me
12:56justin_smithalso I can throw an assert into the middle of a let block, etc.
13:00kavkazAh thank justin_smith
13:00kavkazthanks hellofunk, but I'll probably try first with my GUI version
13:01justin_smithkavkaz: my favorite idiom (assert (ok? input) (str "input was not ok: " (pr-str (select-keys input [:relevant :keys]))))
13:01justin_smithpr-str so that things containing strings and/or symbols will be readable
13:01kavkazhaha justin_smith did you mean triss
13:02justin_smithahh, oops
13:02justin_smithgot my channels crossed
13:02kavkazYes the assert thing changed the colors of my emacs haha
13:03trisspleased to know it bothers more than just me justin_smith
13:04trissWould it really be so hard to implement? Are there reasons it hasn't been?
13:04kavkaz,(assert (colors-ok? my-colors) (println "keep using emacs") (println "keep working on your .emacs file"))
13:04clojurebot#error {\n :cause "Wrong number of args (3) passed to: core/assert"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (3) passed to: core/assert"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6797]}]\n :trace\n [[clojure.lang.Compiler macroexpand1 "Compiler.java" 6797]\n [clojure.lang.Compiler macroexpand "Compiler.java" 6853]\n [clojure.lang.Compiler ...
13:05kavkazoh true
13:05kavkazhaha didn't do it right
13:05justin_smithkavkaz: also, assert messages don't work like that
13:25justin_smith,(assert false (str "this guy, " 'kavkaz " does not use assert."))
13:25clojurebot#error {\n :cause "Assert failed: this guy, kavkaz does not use assert.\nfalse"\n :via\n [{:type java.lang.AssertionError\n :message "Assert failed: this guy, kavkaz does not use assert.\nfalse"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Comp...
15:06roelofCan I take care that 2 expressions are executed after a if then is true. And if so, how can I do this ?
15:07justin_smithroelof: do
15:07justin_smithroelof: if your if would be only one branch, use when
15:08justin_smith,(if true (do (print 'a) (print 'b)) 'c)
15:08clojurebotab
15:08justin_smith,(when true (print 'a) (print 'b))
15:08clojurebotab
15:09roelofoke, I have this http://lpaste.net/141379 and after the W , I have to update another variable thorX with 1
15:10roelofand after the E I have to decrease the same variable with 1
15:11justin_smithroelof: that looks more like a case for cond
15:11justin_smith,(cond (> 0 1) "W" (< 0 1) "E" :else "")
15:11clojurebot"E"
15:11justin_smithI think that's what you want
15:13roelofjustin_smith: no, what I want is something like this if var1 < var2 then W ; var1 = var1 + 1 else
15:13roelof""
15:13oddcully,(let [thor-x 5 light-x 2] (get {-1 "W" 0 "" 1 "E"} (compare thor-x light-x)))
15:13clojurebot"E"
15:14roelofoddcully: is thor-x there updated ?
15:14justin_smithroelof: what is "+ 1"
15:15roelof+1 means that var1 is increased by 1
15:15justin_smithoh, you aren't using clojure = there, OK
15:15roelofsorry
15:17justin_smith(let [var1 0 var2 1 [result var1] (case (> var1 var2) ["W" (inc var1)] (< var1 var2) ["E" var1] :else ["" var1])] ... (code using var1 and result)) ; something like this?
15:18justin_smithyou can easily make a new binding for var1, actually changing it is a whole other mess
15:19roelofjustin_smith: I think so . I have to try it out
15:26roelofhmm, still errors on this code : Exception in thread "main" java.lang.RuntimeException: Unmatched delimiter: ), compiling:(Player.clj:21:42)
15:27justin_smithOK, so you have too many close parens somewhere?
15:29roelofjustin_smith: I think so, Clojure is more difficult then I thought after reading 4 chapters of Living Clojure
15:31justin_smithroelof: it can help to have an editor which has paren highlighting, or auto indent, or paren-colorizing
15:32roelofjustin_smith: the challenge site has one but still I do not see it. I have deleted all the ) after the [] except the last one and still the same error
15:32justin_smithcan you share the updated code?
15:33roelofjustin_smith: yes, here you have : http://lpaste.net/141381
15:35justin_smithroelof: for starters, on line 10 you should be providing a binding vector for the results of the case on line 10
15:35justin_smithroelof: second problem, there is nothing in your code that will actually propagate the new bindings when the while does its next iteration
15:35justin_smithyou can fix this by changing while to loop, and passing the new bindings to recur
15:37roelofoke, the W must be in the variable directionX or directionY. If I read the code right thor-x and thor-y are already updated
15:37justin_smithroelof: nothing can update in that code
15:37justin_smithit's impossible, there is no mechanism by which this would occur
15:38roelofpff, I think Clojure is not for me. Im struggeling the whole day with this problem
15:38justin_smithyou can shadow bindings with new bindings, but by the time the while does its next loop, the old bindings don't even exist any more
15:39justin_smithroelof: there's one root misunderstanding going on for you here, and once you sort that out everything else comes from understanding the consequences of it
15:39justin_smithroelof: clojure bindings do not change, ever. They can be shadowed, or replaced in a new iteration, but nothing changes them.
15:40justin_smithroelof: so you need mechanisms to propagate new bindings to their context
15:40justin_smiththese include loop/recur, recursive functions, or shadowing within a single let block
15:40roelofyes, I read that So I have to use things like reset! ?
15:40justin_smithno
15:40justin_smithroelof: the syntax problem is that you don't close the let binding vector
15:41justin_smiththe reason it's complaining about an unexpected ")" is because it needs a "]" first
15:42justin_smithin order to rebind thor-x and thor-y, you need to rewrite the case call so that every result returns thor-x, thor-y, and the direction string
15:42justin_smithcurrently you aren't even using the result of the case
15:44roelofoke, back to the books then
15:46justin_smith,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 10) iterations (recur new-x new-y (inc iterations))))
15:46clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:47justin_smith,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 10) iterations (recur new-x new-y (inc iterations)))))
15:47clojurebotExecution Timed Out
15:47justin_smith,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 10) iterations (recur new-x new-y (inc iterations)))))
15:47clojurebotExecution Timed Out
15:47justin_smiththat immediatly returns a number (about 250k) on my box
15:47justin_smith,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 5) iterations (recur new-x new-y (inc iterations)))))
15:47clojurebot17
15:48justin_smithroelof: that's a random walk that stops when x and y are both 5
15:48justin_smithyou should be able to use the same basic structure as above (modified for your own logic of course)
15:48roelofjustin_smith: thanks
15:49justin_smithoh wow, I guess my first try with 10x10 was lucky
15:49justin_smiththe second run locally is taking forever...
15:50roelofoops, not good
15:50justin_smithexecution time of a random walk to a determined point is very unpredictable :P d'oh
15:51roelofI think you are right here
15:52justin_smithI wonder what the minimum coordinate distance from 0 is where integer overflow is more likely than hitting the target
15:52roelofbut im going to bed. it's late here. and thanks for the explantion and patience with me
15:56justin_smithroelof: no problem, thank you for your patience as well, I know it's not always easy
16:01roelofnope, maybe if I look at it with a fresh look there will be a aha moment
16:01roeloftill now I find it all very confusing
16:02roelofmaybe wait for the new brave and true and try to learn from that. I did now use living clojure and the click is not there
16:03justin_smithIn the long run, immutability makes things much less confusing. Clojure isn't a harder way to do things, just a different one. Give it time to sink in, like a new language.
16:11sobelI think immutable data has made my programming life simpler
16:13roeloffor me as beginner at this moment not. Like I said earlier I m the whole day busy with this challenge which seems to be easy
16:16roelofmaybe someone knows a good beginners book with a lot of exercises
16:17justin_smithroelof: this task you picked would be easier for you right now if you didn't know how to program already, the mistakes you are making are basically caused by assumptions about programming languages that clojure doesn't follow
16:19jakesyl#join facebook
16:19roelofjustin_smith: that can also be a reason
16:21roelofand I see that loops and recurr are not explained in the living clojure book
16:22roelofso I think I wait for the new brave and true and hopefully that book will explain that
16:23roelofin this example there is also no recur ;; a var to be used for its side effects (def a (atom 10)) ;; #'user/a (while (pos? @a) (do (println @a) (swap! a dec))) ;; 10 ;; 9 ;; 8 ;; 7 ;; 6 ;; 5 ;; 4 ;; 3 ;; 2 ;; 1 ;;=> nil
16:23amalloyjustin_smith: another way of writing the random walk that i think is interesting:
16:23amalloy,(count (take-while (complement #{[3 3]}) (reductions (partial map +) [0 0] (repeatedly #(repeatedly 2 (fn [] (dec (rand-int 3))))))))
16:23clojurebot47873
16:24roelofbut im now really goto bed. Good night all
16:27justin_smithamalloy: nice, you could do that one with iterate too I think
16:28amalloyyeah, but the lambda you give to iterate is bigger, since it needs the + and the randomness. i like keeping them separate, and this *almost* survives with no lambdas
16:46justin_smithNow I am asking myself why I committed myself to do a live performance using software that wasn't done yet. I had my code all ready to go and see at the last stretch that my raspberry pi (which was going to run this synth code) doesn't boot. Now trying to reinstall and crossing my fingers this is not a hardware problem...
17:45mungojellyhave any of you tried funding your programs chits and then charging them for resources? i'm sick of my programs getting a free ride :p
17:53mungojellyfor disk space i guess i'm going to auction blocks of database inserts or something, that's easy to quantify, i could even charge them by the byte. i'm less sure how to charge for processing, maybe auction off slices of time and warn and terminate!?
17:55justin_smithmungojelly: just like in macroeconomics, the ideal is 100% resource usage because savings is meaningless under inflationary pressure. I want all my CPUs at 100% - and then I optimize so that more work is getting done.
17:56justin_smithintroducing a systemic pressure to prevent resource usage is counterproductive if you have any task you are undertaking.
17:57mungojellyjustin_smith: you always decide manually about specific resources, though, eh? what i'm saying is i want the resources to be maxed out and distributed, but instead of saying who specific resources go to i want just to say which things are important without specifying what resources that translates into
18:00justin_smithmungojelly: if your app is complex enough to have more than one task workflow, you can use a system like onyx which allows task prioritization, but most everything I've made before my current onyx process has client requests, and then a set of unconditional tasks which are needed to fulfil each request
18:02mungojellyjustin_smith: what i'm making is evolving processes, they reproduce when they can so there's always (more than) the maximum of them, so i can't just always say yes to them i have to have some way of dumping/ignoring low priority (potential) tasks
18:15mungojellytoday i managed to get "lein run" to run the same thing i got working in the repl, but it was more complicated than i expected. :/ is there something i should read or watch about leiningen that'll make things clearer?
18:15justin_smithmungojelly: no top level side effects
18:15justin_smithmungojelly: that means don't call def with args that alter state
18:16justin_smithonce you are following that rule, it's easy
18:16justin_smithall stateful initialization should be done explicitly inside -main, or by some function called by -main
18:17mungojellyi learned this -main thing and also i learned to say :main somewhere else pointing at the namespace with -main in it
18:17mungojellybut there's clearly a zillion other things i'm missing, i need leiningen 101
18:17justin_smitheh
18:18justin_smithleiningen is mostly declarative, once you learn what the valid keys are that's usually it
19:54cammellosjoin haskell
20:34hlolli,(defn print-hello [] (prn "hello-atom"))
20:34clojurebot#'sandbox/print-hello
20:34hlolli,(print-hello)
20:34clojurebot"hello-atom"\n
20:35justin_smithhlolli: so I was going to be performing using a csound thing tonight, but my raspberry pi broke at the wrong moment
20:35hlolli,(def atomic-eval (atom {:eval #'print-hello}))
20:35clojurebot#'sandbox/atomic-eval
20:36hlolliok, I tried using csound on the raspberrym it's very unstable. Very slow for sure.
20:36hlolliHaven't tried the new one, is it compleatly broken or just a bug?
20:36justin_smiththe device is refusing to boot
20:36justin_smithI think some hardware is bust
20:37hlolli,(eval (:eval @atomic-eval))
20:37clojurebot#'sandbox/print-hello
20:37hlolliwhy didn't that work?
20:37justin_smithhlolli: you aren't calling the var
20:37justin_smithhlolli: you are just returning it
20:38justin_smith,((:eval @atomic-eval))
20:38clojurebot"hello-atom"\n
20:38justin_smithhlolli: eval isn't for calling functions, it is for compiling them
20:38hlolliwtf, ok, return it then eval. ok I see
20:38justin_smithwhen you give it something that doesn't need any resolution or compilation, it just gives you the thing
20:38justin_smithhlolli: no, no eval
20:38justin_smitheval is for compiling, the thing you have is already compiled
20:39hlolliok, Im getting the grips of this difference of compile time and run time.
20:39justin_smithhlolli: every form you type into the repl is implicitly evaled already, and having to use eval otherwise is usually a sign you are doing something wrong, unless you are writing a compiler
20:40hlolliok ok
20:40justin_smiththe repl is a loop, it reads forms, compiles them, then prints the result, then loops
20:40justin_smithREPL
20:40hlolliI just would not have guessed on double parenthesis
20:40justin_smithhlolli: parenthesis are the syntax for calling things
20:40hlolliok ok
20:41justin_smithif you have a function, and want to call it, you need to wrap it in parens. If something returns a function and you want to call it immediately, you need double parens
20:41justin_smithif you had a function returning a function returning a function, triple parens would be the thing you want
20:42mungojelly,(let [x (fn [] (fn [] (fn [] "hi")))] (((x))))
20:43clojurebot"hi"
20:43hlollihaha ok, funny how thinking about some language feature before knowing that it's a feature, that's how I usually learn best, to see it in practice.
20:43hlollitriple!
20:44rhg135The factories of factories are useful
20:45gfredericks,(let [f (nth (iterate constantly 42) 10)] ((((((((((f)))))))))))
20:45clojurebot42
20:46hlolli10 parenthesis, winner
20:48gfredericksI wonder what the upper limit on that is
20:48domgetterAnd that was the last time we saw gfredericks alive...
20:49hlollijvm nuke
22:30rritochIs there any way to create a new class that extends another class overriding some methods without using a gen class? I've been trying to get away from gen-class dependence but for this issue I can't see a way around it.
22:48domgetterIf I have a clojurescript app and I want to maintain a list of stuff that's updating, like a chatlog, is it better to use an atom or one of the immutable persistent data structures?
22:54namradomgetter: i think a chatlog can become quite large, and immutable means higher memory requirements. using an atom in this case would you save memory, but don't know if it would also be faster, something to test. and because of clojure easy and safe way to actually work with atoms, why not use it.
22:56namracljs not clojure ^^
22:56domgetternamra: That's sensible. I'll try to get to a point where I would understand how to test that.
22:59namraa simple way i can think of is using included time fns near the code that updates i.e. the chatlog
23:01namrathere's even a time macro
23:01namra(doc time)
23:01clojurebot"([expr]); Evaluates expr and prints the time it took. Returns the value of expr."
23:01namra.(doc time)
23:07amalloy"should i use an atom or a persistent data structure" seems like the wrong question to me: almost the only sensible thing to put in an atom *is* a persistent data structure
23:23python476hi there
23:23python476I'm having trouble converting this Path path = FileSystems.getDefault().getPath("logs", "access.log");
23:24python476Started with this (.. FileSystems getDefault), ok, (.. FileSystems getDefault (getPath "/var")) fails
23:25python476(and btw, I'm not trying to be idiomatic, it was about learning java interop)
23:36SaukenHello!
23:36mal_hola
23:37amalloypython476: http://stackoverflow.com/q/5638541/625403
23:37python476Apparently one has to ... (Paths/get "/" (into-array String ["bar" "baz"])) sometimes
23:37python476makes me cry all inside
23:37python476amalloy: heh, was just reading this.
23:37SaukenI've got a question. So I made a random letter generator in C++, and I made it write 10,000 random capital letters from A-Z
23:38SaukenHow do I look for my name inside of those letters?
23:39python476unless you (Paths/get (URI. "file:///var/log")) then interop lands on its feet
23:41python476oh and you were the author of the final answer, how convenient