#clojure logs

2014-02-20

00:00nopromptbob2: of course. that and ml.
00:00s1gs3gvtry to be positive mark[oz] ... it'll feel good.
00:00johnwalkeror rust
00:00sm0keerlang
00:00s1gs3gv1980
00:00bob2noprompt, did you find haskell's type system to be significantly more valuable than scala's?
00:00mark[oz]s1gs3gv: I just feel like the same conversations happen, no matter which language I'm playing with.... "does it scale?" "is it better then language X"
00:01sm0kego
00:01s1gs3gvit is a legit concern
00:01mark[oz]we can make anything scale... geez people scale c++
00:01sm0kelua can be scaled
00:01bob2s1gs3gv, without context, it isn't
00:01nopromptbob2: i never used scala. i took one look at it and literally said "fuck no".
00:01bob2noprompt, hah, fair enough
00:01mark[oz]s1gs3gv: if google can keep 14 copies of the internet in memory, then you'll be fine :)
00:01johnwalkernoprompt: ugh, yeah me too, except it was in the context of the coursera introduction
00:01s1gs3gvok, with remote akka actors i can scale thru configuration
00:02s1gs3gvwithout writing any new code
00:02bob2so does running more app servers count as "scale thru configuration"?
00:02mark[oz]you could always throw a load balancer in front of a few instances right?
00:02mark[oz]varnish, etc.
00:02s1gs3gvyes, if i don't have to change my code, just the config
00:03bob2then any language counts, if you write mostly-stateless apps
00:03johnwalkertwitchplayspokemon seems to scale
00:03nopromptlike i said, i mostly enjoy type safe languages just not syntax.
00:04bob2clojure is type-safe, it's just not statically typed
00:04nopromptcall me a smug lisp weenie. syntax adds an unecissary barrier between you and your program.
00:04nopromptbob2: fair enough.
00:05johnwalkers1gs3gv: look for the technique that you want to use to scale your app, and check how it works in clojure
00:05dsrxmy favorite scala thing is List(1,2,3).toSet() # => Boolean = false
00:07nopromptwut?
00:08inahandizhahttp://VisitsToMoney.com/index.php?refId=386970
00:08dsrxit ends up becoming something like (List(1,2,3).toSet).apply( () )
00:09dsrxand since list is covariant the inferencer makes that list a List[Any], and checks for membership of () in it
00:09dsrxsomething like that
00:10s1gs3gvso, i am considering mark[oz] question regarding the differences between scalability thru configuration using akka remoting and using loadbalancers
00:17s1gs3gvreally that throws the burden of application scalability on the system admistrators rather than the software architects
00:18s1gs3gvit should be possible just to netboot a system and have it join the application service
00:18mark[oz]s1gs3gv: you need to tackle each component of the application to determine where it best sits
00:18mark[oz]and I don't believe there is burden, just various solutions
00:19s1gs3gvmark[oz]: when you require administrative action to scale a system, you introduce a point of failure
00:20bob2" application scalability" is absolutely the software developer and architect's problem
00:20bob2poorly designed and implemented apps will never scale
00:21mark[oz]facebook would disagree
00:21mark[oz]so would reddit and twitter
00:21mark[oz]it's just tougher
00:21bob2heh
00:22mark[oz]I'm on a 16million pi app that's is being scaled across 3 web servers, and still as one db.
00:22s1gs3gvwhich db ?
00:22mark[oz]we have solid caching, memcached, memoization, varnihs, etc.
00:23mark[oz]s1gs3gv:postgres.
00:23mark[oz]s1gs3gv: hidden behind an ORM btw
00:24s1gs3gvwhat kind of hardware is running the db ?
00:24mark[oz]it'll be RDS soon. but it's a beefy dell 2950 (3 years old though)
00:25s1gs3gvand this is a clojure app ?
00:25mark[oz]nope.
00:25mark[oz]python... so prob slower then the jvm :)
00:25s1gs3gvwell ...
00:25mark[oz]but my point stands... it shouldn't matter?
00:25s1gs3gvwhat shouldn't matter ?
00:26johnwalkerclojure is faster than python
00:27s1gs3gveverything is faster than python, except ruby lol
00:27johnwalkeris php faster than python?
00:27s1gs3gvdunno. i don't do php :)
00:27s1gs3gvscala is
00:29s1gs3gvanyways, the takeaway i am getting is that clojure is slower than scala but some think it make up for it by being a better match to the problem spaces and that you can scale clojure apps using load balancers.
00:29s1gs3gvhave i got that right ?
00:29Cr8i..
00:30s1gs3gv?
00:30Cr8it's hard to say that a -language- is slower or faster than another
00:30Cr8especially two jvm languages
00:30Cr8unless one is groovy
00:30s1gs3gvlol
00:31Cr8I'd say Clojure and Scala are pretty similar in terms of closeness to the underlying runtime though
00:32Cr8and there's always https://github.com/ztellman?tab=repositories when you need an escape hatch
00:33s1gs3gvthats kinda interesting. ty.
00:34Cr8(by which i mean ztellman has several different projects that allow you to step around some of the things in clojure when you need to for performance reasons)
00:34Cr8vertigo, proteus, probably more
00:35Cr8That is one of the differences I'd say that exists between Clojure and Scala is that Clojure does a lot less in the way of actual *enforcement* of its sensibilities
00:36s1gs3gvright
00:36Cr8which may be something you like or don't, depending on your situation
00:36s1gs3gvsure
00:37s1gs3gvthere are times when covariance and contravarience hurt the brain
00:38s1gs3gvbut it seems to pay dividends
00:39s1gs3gvcan u summarize the benefits of *not having* a static type system in clojure
00:41Cr8probably not. One though is that it is a bit at odds with its goal of being a language that sits very thinly on-top of some host platform (enabling stuff like ClojureScript very easily)
00:41technomancynot having Java's type system is pretty great
00:41Cr8^^
00:41technomancyit would be really difficult to build something that is both 0) good and 1) allows for decent JVM interop
00:43Cr8and now you have the weird effect of touching the JVM "types" at a lower level than you would from Java even
00:44Cr8since Java has things that don't "exist" at the JVM layer (generics, inner classes)
00:44s1gs3gvso what is great about not having the java type system ?
00:44s1gs3gvperl doesn't have it either ...
00:45s1gs3gvtechnomancy: define good
00:45Cr8if you had a static type system and it was significantly different from Java's it complicates the interop layer
00:46s1gs3gvbut that is hidden in the implementation. as an application programmer i don't need to worry about it.
00:46technomancys1gs3gv: catches common errors without imposing lots of unnecessary mental overhead
00:46Cr8heh
00:47Cr8I've never used FFI of any form without eventually having to study the implementation to deal with something
00:47s1gs3gvFFI ?
00:47Cr8(foreign function interface, though here I use it to mean interop layers in general)
00:48s1gs3gvas an application programmer using a jvm language that interoperates with java classes, why should i care
00:49s1gs3gvin fact, i shouldn't have to care
00:50s1gs3gvi think i'm missing something here that y'all are trying to explain ...
00:51s1gs3gvscala and clojure both target the jvm and interoperate with java classes
00:51s1gs3gvscala has a static type system, clojure doesn't
00:51s1gs3gvthat has benefits and costs
00:51s1gs3gvconvince me that the costs outweigh the benefits if u can
00:52technomancyI don't care; if Scala doesn't drive you crazy then that's fine by me =)
00:53`szxs1gs3gv: why don't you just try it out and decide for yourself?
00:53bob2why? if you like scala, go for it
00:53bob2no one but you (and your coworkers) cares what you use or prefer
00:53s1gs3gvlol. thats what i thought !
00:53s1gs3gvi like both.
00:53s1gs3gvbut clojure is so slow ...
00:54technomancyslow clojure programs are slow
00:54technomancyfast clojure programs are fast
00:54technomancythere's nothing about clojure that makes it impossible to write programs that are as fast as the fastest scala programs
00:55s1gs3gvso why do the benchmark game benchmarks suck ?
00:55technomancybecause benchmarks are stupid
00:55s1gs3gvohhh, excuse me. sorry.
00:56technomancyno one who knows how to write clojure has bothered to spend a bunch of time optimizing against a silly gamed metric
00:56s1gs3gvi don't think any of those programs are optimized.
00:56technomancyright, because no one cares
00:57s1gs3gvits still an apples to apples comparison
00:58technomancybenchmark games are like arguing on the Internet
00:58technomancywhoever has more time to sink into a fruitless cause always wins
00:58s1gs3gvit shouldn't be necessary to optimize an idiomatic clojure program to get good performance.
00:58s1gs3gvthat is a bad tradeoff
00:59technomancywhat good is a fast program that isn't correct?
00:59technomancydo you want a language that makes it easy to write fast code and difficult to make it correct, or vice versa?
00:59s1gs3gvare you suggesting that idiomatic clojure programs are less likely to be correct
00:59technomancyno
01:00alewif you want performance, you should use a language built with speed in mind, like c
01:00s1gs3gvare you suggesting that idiomatic clojure programs are more likely to be correct ?
01:00technomancyyes
01:01s1gs3gvso you are implying there is a tradeoff between idiomatic usage and performance ?
01:01alewthat's true of every single language
01:01s1gs3gvnot really
01:02s1gs3gvi don't have a problem with it if there are ways to deal with scalability
01:02technomancyscala comes out better in the games because it makes it easier to write imperatvie code
01:02s1gs3gvin fact i think idiomatic usage trumps performance
01:02technomancyimperative code is more difficult to write correctly in a concurrent setting
01:02s1gs3gvyes
01:02s1gs3gvi'm not arguing imperative vv functional
01:03technomancyimperative vs functional *is* the same argument as fast vs correct
01:03s1gs3gvphhhwww
01:03technomancyin the context of clojure vs scala
01:03s1gs3gvi've written a lot of correct imperative programs
01:03alewin what language is the idomatic solution also always the fastest?
01:04s1gs3gvi think the primar concern in language choice is how closely the language models the abstraction we use when thinking about the problem space
01:04s1gs3gvbut i want to ensure that my solution scales reliably without adminstrative action
01:05alewwhat about erlang?
01:05s1gs3gv1980
01:05s1gs3gvsorry, thats a reasonable question. but out of scope in a clojure/scala conversation
01:06s1gs3gvi really like clojure, but the benchmarks suck
01:07technomancyif you think you can't write fast code in clojure you should read http://meshy.org/2009/12/13/widefinder-2-with-clojure.html
01:07technomancyif you base your decisions on alioth benchmarks you deserve what you get =)
01:08s1gs3gvi'll read it. thanks for the link.
01:09s1gs3gvtake it easy folks. ttyl. late here ...
01:10ssafejavathanks for the links technomancy, always glad to have you in channel
01:10technomancyalioth used to penalize you for startup time too
01:10technomancynot sure if they still do
01:11technomancybut that made it totally misleading for server software
01:12technomancyread the meshy.org article ... and pray you never have to deal with optimization at that level yourself =)
01:12technomancyssafejava: np; cheers. calling it a night.
01:13ssafejavanight
01:43quizdrI have a map of maps, therefore a lazy sequence that contains other lazy sequences. I just want to print it all out, but it seems I have to get fancy with mapping printlns on top of printlns; is there an easier way? doall only realizes the top-level map
01:44bob2pprint?
01:45Cr8map {:foo "bar"} or map (map foo [bar baz]) ?
01:45Cr8map {:foo "bar"} <-- not lazy
01:46quizdrCr8 yes, map of map, actually three levels deep.
01:46quizdrbob2 that only works on top level
01:46Cr8pprint or pr-str should realize the whole structure
01:47quizdrCr8 ok let me take a closer look.
01:47Cr8er, (prn) rather
01:47Cr8if you want to print it out
01:48Cr8pr-str would return the string that would be printed using pr
01:49Cr8quizdr: (print) is for humans
01:49Cr8(pr) is for printing things such that they are fully represented and can be read back in
01:49quizdrCr8 gotcha
01:49Cr8with (println) and (prn) respectively if you want newlines after
01:51hhenkelHi all, I'm running in an error trying to use at-at as a scheduler library with http-hit communicating over channels. The error is: Exception in thread "main" java.lang.ClassCastException: clojure.core.async.impl.channels.ManyToManyChannel cannot be cast to java.lang.Runnable
01:52hhenkelSo my guess is, that it is not a good idea to use return a channel at that point in the code but rather return the data and put it then in the channel?
01:55amalloyhhenkel: an error message is much, much less useful than an entire stacktrace
01:57hhenkelamalloy: That's not a big deal: https://www.refheap.com/42612
01:59amalloyi know very little about at-at, but it sure looks to me like you are calling schedule-requests with a core.async channel, when it wants a Runnable
01:59amalloy(and since clojure functions implement Runnable, you may in fact just want to be passing it a fn)
02:02Cr8at-at is a pretty thin wrapper around http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
02:02Cr8and it looks like you tried to hand at-at/every a channel where it expected a function (or other Runnable thing)
02:03hhenkelamalloy: Cr8: added the functions to https://www.refheap.com/42612
02:04Cr8hhenkel: every expects an interval
02:04hhenkelCr8: Yes, that's what I thought might be the problem. So it's better to return the result of the http request then?
02:04Cr8ahah waity
02:04Cr8*wait
02:04Cr8you want to run that http-post every timed-request ms
02:05Cr8right
02:05Cr8just toss a # at the front of line 15 =P
02:05hhenkelCr8: Yes, exactly.
02:05Cr8you're actually passing it the result of *calling* http-post
02:05Cr8you want to pass a function that *will* call http-post
02:06Cr8(every <interval> <function> <pool>) ; (every 1000 (fn [] (println "I get printed every 1000ms")) my-pool)
02:06Cr8(every 1000 (println "I return nil") my-pool) <-- throws nullpointerexception because it tries to call nil as a function
02:07hhenkelCr8: okay, okay...I think I see the issue...I'll give it a try.
02:07hhenkel;)
02:08Cr8I've done this same thing using at-at myself.
02:12webushi! i'm locking for remote job on clojure
02:12hhenkelCr8: Looks much better now...totally strange that it works once it is done right.
02:12Cr8funny that
02:12hhenkel(inc Cr8)
02:13hhenkellazybot is gone?
02:13ddellacosta,(inc Cr8)
02:13clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: Cr8 in this context, compiling:(NO_SOURCE_PATH:0:0)>
02:13Cr8huh it was here earlier
02:13ddellacosta&(inc Cr8)
02:13Cr8guess it got borked
02:13ddellacostahmm
02:13Cr8ddellacosta: it's actually not in the channel :)
02:14ddellacostaCr8: ah
02:14ddellacostaclojurebot: where is lazybot?
02:14Cr8is it its brother's keeper
02:14ddellacostajeez, the bots are really slacking off today
02:14ddellacostalazy bots
02:21juliankrauseHello, I am following this doc http://clojure-doc.org/articles/tutorials/vim_fireplace.html on how to get my repl set up correctly. However, when I try and run the tests I get: ClassNotFoundException clojure.tests java.net.URLClassLoader$1.run (URLClassLoader.java:366)
02:21juliankrauseI am using OpenJDK 7 on debian. Is this a problem? Is there a way to get more details?
02:23juliankrauseOoops, I realized what it is, running (clojure.tests/run-tests) fails with that.
02:23juliankrauseThanks
02:57TravisDDo refs provide validation because you may not control the transactions that update the ref?
03:03arrdemddellacosta: you don't do inc with code eval. it's its own system.
03:03arrdem(inc ddellacosta)
03:04arrdemwhich apparently is offline..
03:04arrdemTravisD: care to elaborate?
03:05TravisDarrdem: Ah, I watched a talk by Rich Hickey about simplicity tonight. It seems like you should be able to have validation and mutation as orthogonal concepts. I was trying to figure out why they are coupled together
03:06TravisDarrdem: The talk was relevant because he started using the word "complect", which is why i was thinking about it in the first place
03:08arrdemTravisD: AFAIK ref transactions provide no validation. You can achieve validation by using ref update hooks, but it's not something I've done.
03:09TravisDAh, maybe it's just for convenience then. What I was thinking of is this: (def some-ref (ref 0 :validator #(> % 0))
03:09arrdemlemme look around a bit, I may be entirely offbase here.
03:10arrdemI appologize. there is official support for ref validation.
03:10arrdemhttp://clojure.org/refs#Refs%20and%20Transactions
03:10amalloyTravisD: #(> % 0) is just pos?, isn't it?
03:10arrdemhttp://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-validator!
03:10TravisDamalloy: sounds like it :)
03:10TravisDI just made something up on the spot. not too familiar with the available predicates yet
03:13mskou72I have something like this: (def x [{:a 1 :d #{}} {:a 2 :d #{}}]) , but how do i put items in the set and get a new x?
03:14ddellacostaarrdem: ah, didn't realize...thanks
03:18ddellacostamskou72: if you want to do the same thing to all :d sets, you could do something like (map (fn [v] (update-in v [:d] #(conj % :foo))) x)
03:18mskou72well only fx for maps where (= :a 2)
03:20ddellacostamskou72: in that case just add a predicate I suppose: (map (fn [v] (if (= 2 (:a v)) (update-in v [:d] #(conj % :bar)) v)) x)
03:21mskou72thanks, will try!
03:21bob2are you sure you want a randomly mutable global?
03:22ddellacostamskou72: more generally, if you are still figuring out how to structure your data, consider what you will want to access/update and how, and think about the ways that clojure gives you to make it easier. Sometimes that pays off.
03:22ddellacostabob2: what do you mean?
03:22ddellacostabob2: I don't see anything mutable anywhere in mskou72's question or my answer
03:26mskou72bob: the (def x part was just to present the problem in a runable manner...
03:47lizzinis there a way to destructure a map in a def? say (def [x y] (group-by #(< % 5) (shuffle (range 10))))?
03:48ddellacostalizzin: you mean defn? You don't pass args into a def like that.
03:49ddellacostalizzin: and if you are asking about defn, then the answer is yes, you certainly can. This is a great article on destructuring: http://blog.jayfields.com/2010/07/clojure-destructuring.html
03:50lizzini am familiar with defn. just wondering if was also possible to create two vars w/ a single def while destructing that map
03:51ddellacostalizzin: no, the first arg to def is a symbol, not bindings/params.
03:53lizzinddellacosta: seems a bit odd that this is not allowed. but binding via let etc should work just fine
03:53hhenkelHi all, is it possible to pass multiple values to a function using the "arrow" notation?
03:54ddellacostalizzin: why is it odd? Honestly I can't really think of a use case that would need you to do this kind of thing
03:54bob2mskou72, ah, sorry, I misunderstood
03:55ddellacostalizzin: simply set the var to be the value of the group-by, then it's very easy to refer to things using built-in mechanisms that Clojure provides.
03:55bob2hhenkel, you can pass a container and destructure it in the function, but -> and ->> only pass in one arg themselves
03:56lizzinddellacosta: true. it just something i've found useful in scala
03:56hhenkelbob2: okay, thanks.
03:57lizzinddellacosta: i just started learning clojure. so i'm sure my views on this are sure to change
03:58ddellacostalizzin: another thing is that function args/let bindings are setting local scope; you would be setting indefinite (global) scope with this proposed mechanism.
03:58ddellacostalizzin: I'm not sure there is much of an arg there other than semantic consistency, though.
03:58ddellacostalizzin: yeah, in general it's good to get a feel for the tools Clojure gives you for getting ahold of your data--it is very powerful but takes a bit of time to "think in Clojure" so to speak.
04:04lizzinddellacosta: i have much to learn. thanks for the help
04:05ddellacostalizzin: as do we all. :-) Sure, any time, hope I was helpful!
04:05TravisDSince random number generators are not pure (unless you include the seed as an argument, which seems uncommon), should you be careful about their use in otherwise pure code?
04:07dsrxpassing RNG state around inside a closure or contained within an object or with a state monad or something isn't really that uncommon
04:07TravisDyeah, I wrote some simulation stuff in Haskell that used a state monad to thread the seed through the program
04:08TravisDbut that felt kind of tedious in the end
04:09quizdrI'm finding it a bit odd that partition returns a sequence, which you'd understand to be ordered, yet conj prepends to the front, unlike other ordered sequences like vector. Is this confusing or expected?
04:10lizzinddellacosta: you definitely were!
04:18dsrxthe 'place' that conj happens depends on the collection; lists are one example where it's prepended (because they're singly linked lists)
04:46nathan7quizdr: conj just does the most efficient 'add this to the sequence' it can do
04:46nathan7for a single-linked list, that's at the front, for a vector, that's at the back
04:47nathan7conj is guaranteed to be constant-time
05:04hhenkelWhat are the best options/prefered types when I'm facing such an exception: nth not supported on this type: PersistentArrayMap
05:10clgvhhenkel: what do you want to extract from the map?
05:11hhenkelclgv: I don't want to extract anything... ;) I'm providing a datastructure to http-kit to be used within a post request.
05:12hhenkelclgv: https://www.refheap.com/42670
05:13clgvhhenkel: oh then you provide the wrong data structure or the wrong layout
05:14clgvhhenkel: http-kit is clearly assuming a sequential data structure there - maybe even a vector
05:14clgvcheck the docs about what data you need to provide
05:15hhenkelclgv: yes, thought so...updated the refheap with my code...gues I have to rethink line 8 then.
05:16hhenkelclgv: looks like I need a vector for that.
05:17clgvwhat's that: (keyword "form-params") ? why not :form-params?
05:17clgv hhenkel: maybe you need a vector of requests? just check what the docs say ;)
05:25hhenkelclgv: How do I create a vector then? I'm limited with my knowledge regarding options to process the data.
05:26hhenkelclgv: As far as I understand I need a different operation then the doall / map because this gives me a lazyseq
05:26clgvhhenkel: you need some introductory text to clojure if you ask that
05:27hhenkelclgv: I'm trying to understand the oreilly book at the moment...
05:28clgvhhenkel: If I were you I'd read the http-kit docs to find out what the used call needs to get as data
05:28clgvand then go from there
05:39sm0keconj is not constant time
05:40sm0keit took over 3 days i guess
05:40sm0ke:D
05:46rurumateIs there a way to enable auto-reload of modified source files with liberator?
05:49bob2rurumate, 'lein ring server'does that already
05:57rurumatebob2: ok, that's what I used to do before liberator, and it worked
05:57sm0kewhats is liberator?
05:58rurumatenow I cloned the liberator project and run lein examples, and have to restart after a change
05:58rurumatesm0ke: it's a project on github
05:58sm0kerurumate: whats it good for?
05:59rurumatesm0ke: not sure yet, but it seems to require less setup work for a new project
05:59rurumatethan raw compojure
05:59rurumateI'm lazy you know
05:59sm0kehmm how can compojure be more work!! the req response is a map!
06:00sm0kethanks to ring
06:00rurumatesm0ke: for example, many useful ring handlers are already there
06:00sm0keit seems to have some fancy graph based thingy
06:01sm0kerurumate: ring handlers and middlewares are completely different things
06:01Anderkentwell that's the thing, it doesn't really do anything for you; sometimes it's nice to work on a higher level of abstraction than just request-response
06:01rurumateoops sorry, I meant middlewares
06:01sm0keand can be resused in any app based on ring
06:01sm0keneed to read about it
06:08rurumatehmm, no liberator users here?
06:08rurumateit has almost 500 stars, I wasnt't expecting this
06:15sm0kerurumate: did you try what bob2 suggested?
06:15sm0kerurumate: if its based on ring, lein ring server should be good enough
06:16sm0kerurumate: https://github.com/weavejester/lein-ring
06:22clgvrurumate: I can ping one of the maintainers if he is around ;)
06:28clgvno luck yet..
06:31rurumateclgv: yes please, thanks
06:32rurumategoogle didn't help me much, I think this should go into liberator's README.markdown
06:32rurumateor the wiki start page
06:41clgvrurumate: maybe you need to start the server from the REPL. then updating code would be pretty easy without additional magic
06:51sm0kehey is it necessary for deftype to implement an interface? ##(deftype ValarMorghulis [s] (getName [_] x))
06:51sm0kethe doc here has a spec* http://clojuredocs.org/clojure_core/clojure.core/deftype
06:52sm0kewhat happened to lazybot?
06:52sm0ke,(deftype ValarMorghulis [s] (getName [_] x))
06:52clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol>
06:52sm0ke,(deftype ValarMorghulis [s] (getName [_] s))
06:52clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol>
06:53clgvsm0ke: to implement a method in a deftype you need an interface
06:53clgvor a protocol
06:54sm0kehmm than the statement that gen-class and deftype are similar is just plain wrong
06:56clgvsm0ke: similarity does not mean they are identical, they just share some common properties
06:57rurumateclgv: thanks, I'll try the repl way
06:57rurumatecheers
06:59sm0keugh, i am lost when it comes to defining types
06:59Anderkentsm0ke: functions on deftype must fulfill a protocol / interface
06:59Anderkentthat's by design
06:59sm0kedefprotocol, definterface, then defrecord, extend-type, deftype, then proxy, reify, gen-class.. blah blah bleh
07:00Anderkentright, they're all different tools for different purposes; (with perhaps exception of gen-class, which is the low-level mechanism)
07:01Anderkent.. I think there was a cool graph of 'what datatype to use' somewhere, but cant find it now
07:01sverihi, did someone here integrate friend into a luminus/http-kit project and has some example code or any other resources for this?
07:01sm0kehttp://chasemerick.files.wordpress.com/2011/07/choosingtypeforms2.png
07:02sm0kethere is no extend-record, extend-type on that
07:02Anderkentyeah, that's it :P
07:02Anderkentbecause they're not datatypes, they're ways fo bending an existing datatype to support new interfaces
07:03Anderkenti.e. you're defining a protocol and want to provide implementations for types you don't control
07:11sm0ke,(defprotocol IncStr (inc [s]))
07:11clojurebotWarning: protocol #'sandbox/IncStr is overwriting function inc\n#<SecurityException java.lang.SecurityException: denied>
07:11sm0ke:P
07:11clgvdon't annoy clojurebot! otherwise he may join lazybot in the tavern ;)
07:12sm0kethe sandboxing is bullet proof
07:23sm0kehow wise it would be to have something like...(ns org.abc) (deftype....) (ns back.to.original). in a source code?
07:23sm0kethe point being deftype could be given a custom package strucutre?
07:27clgvsm0ke: very stupid, since clojure cannot require that namespace since class loading is done via a namespace-file-location correspondence
07:28sm0keclgv: is that true? why is it permitted on a repl then?
07:28clgvbut if you want a different namespace for the deftype just create the appropriate file for that namespace
07:29clgvsm0ke: yeah that is true. on the repl when you define a namespaces it is created in memory. when you define the namespace in a file and require it from a different file there is the mentioned convention so that the namespace can be found and loaded into memory
07:30sm0ke,(doc ns)
07:30clojurebot"([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class .....
07:31clgvjust remember ech namespace needs his own file. but one namespaces can be implemented in different files for better organization of large namespaces see clojure.core
07:31clgvsm0ke: the docstring just explains how ns is used^^
07:32sm0keclgv: what do you mean by one namespace can be implemented in different files?
07:32clgvsm0ke: you can simply try your scenario. write a second file (ns my.example (:require org.abc)) where (ns back.to.original) ... (ns org.abc) ... (ns back.to.original)
07:33clgvand see if failing ;)
07:33clgvsm0ke: see clojure.core
07:33sm0keclgv: hey that would obvisouly fail
07:34sm0kewait..
07:34sm0kehmm i am interested to know what would happen if i put (ns xyz) in middle of a source code
07:34clgvany setup with two ns-forms within a single file will fail
07:34sm0keah
07:35clgvyou can't properly require xyz if the file where it is contained was not loaded in advance
07:37sm0keso do you propose i either use gen-class or create folder like org.stupid.java.packaging.howlong.cani.dothis ?
07:39clgvsm0ke: if you really need that long package yeah
07:39sm0ke:P
07:41sm0keanyways, getting off now
07:41sm0kelater!
07:41TimMcclgv: But if one were to require the "containing" namespace, the other would become available, yeah?
07:42clgvTImMc: yeah
07:42TimMcnot that I'm encouraging such shenanigans
07:42clgvjust like the (ns) form executed in the repl
07:43clgvTimMc: it is just the classloader logic that cannot find the file where the "contained" namespace is in
07:44clgvwe should switch from files to database as storage for programming. no more file oriented organization ;)
07:45clgva petty that the lighttable feature for composing the workspace view out of different functions did not survive...
07:49TimMcIt didn't? :-(
07:49clgvlast time I tried I could not find it.
07:49clgvabout 3-4 weeks ago
07:57clgvTimMc: https://groups.google.com/forum/#!topic/light-table-discussion/0DAuy2Trfjw
08:00mercwithamouthwould any of you clojure afficionadas be willing/interested in starting a video tutorial site like railscasts? Not 'with' me but 'for' those like me =P
08:00mercwithamouthpaid service of course...
08:04clgvmercwithamouth: some did write books to help you ;)
08:08mercwithamouthclgv: lol very true..and i've bought all of them =P
08:17clgvmercwithamouth: and read all of them yet? ;)
08:33winkmercwithamouth: well there is videos.lispcast.com, but not many
10:23stainhi, is it possible to use (extend-type) or similar to make beans of a Java interface also implement ISeq or ITransientMap or similar? (without modifying the Java source)
10:24stainor would I have to do my own new multimethods?
10:25stainif I try (extend-type com.example.MyJavaThing clojure.lang.ITransientMap (..)) I get: IllegalArgumentException interface clojure.lang.ITransientMap is not a protocol
10:26Anderken1you can't add interfaces to java classes, but you can proxy them and add the interfaces to your proxy
10:27gfrederickssometimes
10:27Anderken1sometimes.
10:27gfredericks,(proxy [clojure.lang.Keyword] [])
10:27clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching ctor found for class sandbox.proxy$clojure.lang.Keyword$0, compiling:(NO_SOURCE_PATH:0:0)>
10:27gfredericks,(proxy [clojure.lang.Keyword] ["foo"])
10:27clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching ctor found for class sandbox.proxy$clojure.lang.Keyword$0, compiling:(NO_SOURCE_PATH:0:0)>
10:27gfredericks,(proxy [clojure.lang.Keyword] ["foo" "bar"])
10:27clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching ctor found for class sandbox.proxy$clojure.lang.Keyword$0, compiling:(NO_SOURCE_PATH:0:0)>
10:27stainok.. but then I would have to proxy it everwhere I retrieve the Java objects?
10:27stainthen I could rather just create brand new Clojure object at each of those points
10:28Anderken1that's usually the right thing to do, yes
10:30stainbut I can create multimethods around my Java classes, right? Say a (convert-to-clojure) method with different implementations for each of my Java classes
10:32Anderken1yes in theory, though I'm struggling to imagine a use case for that; usually when interacting with java you know straight away what class you'll be getting and can do whatever you want with it without the indirecton of a multimethod
10:35clgvstain: yes you can. I did it for an R interface
10:38_bartLet's say I have (def beats {0 [kick] 1 [kick snare]}) and (def arps {0 [a] 1 [b]}), how do I merge the two so that I get a (def c {0 [kick a] 1 [kick snare b]})?
10:39Anderken1,(doc merge-with)
10:39clojurebot"([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."
10:39_bart(the hashes hold a 'bar' for the sequencer, and I have multiple bars for multiple instruments)
10:39Anderken1so (merge-with conj beats arps)
10:40Anderken1uhm, I ment concat
10:40Anderken1,(merge-with concat {1 [1 2 3]} {1 [4]})
10:40clojurebot{1 (1 2 3 4)}
10:40clgvbetter use into
10:41Anderken1yeah, that's better
10:41_bartah that looks great, why would I use into?
10:41Anderken1you'll get the same type
10:41clgvconcat may bite you when you use that code too often
10:41`cbpinto is also faster
10:41Anderken1,(merge-with into {:a #{:b :c}} {:a #{:b :d}})
10:41clgvstacking up lazy sequences with concat too often results in a stackoverflow
10:41clojurebot{:a #{:c :b :d}}
10:41Anderken1,(merge-with concat {:a #{:b :c}} {:a #{:b :d}})
10:41clojurebot{:a (:c :b :b :d)}
10:42_bartah okay, thanks
10:42sdegutis_I always avoid conj.
10:42_bart,(doc into)
10:42clojurebot"([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."
10:42sdegutis_I never seem to want to add onto a sequence in an undefined order.
10:43sdegutis_Anyone else with me on this?
10:43_bartcan I also merge 3 maps ith this code?
10:43sdegutis_Or am I crazy?
10:43Anderken1sdegutis_: so you don't use into either?
10:43_bartwith*
10:43clgvsdegutis_: I almost only use vectors for sequential data. except from macro implementations
10:43`cbpyou're crazy
10:43sdegutis_I use into only for (into {} ...)
10:44sdegutis_clgv: But once you run it through map or filter, it's not a vector anymore.
10:44sdegutis_Anderken1: I only use (into {} [[k v] [k v] ...])
10:44Anderken1well, for maps and sets the order doesnt matter anyway; vec and list are the only places you'd care I suppose, and there I usually avoid conj
10:44llasramHuh
10:44sdegutis_llasram: Huh.
10:44clgvsdegutis_: well I guess I do not often have the need to add to such a sequence after filter again.
10:45clgvfor map there is mapv ;)
10:45clgv,(apropos "filter")
10:45clojurebot(filterv filter)
10:45clgvoh right, filterv as well^^
10:45llasramI see knowing if a value is a seq vs a vector as pretty much the same as knowing if it's a string vs a database connection
10:45sdegutis_clgv: When you get a sequence from another of your functions, it may have been mapped or filtered or not.
10:45`cbpso what do you use instead of conj? :-D
10:45sdegutis_clgv: So I always have this hesitation of not being sure at all of what type my sequences are.
10:46sdegutis_`cbp: Usually just concat.
10:46Anderkentllasram: huh. For me it's more like map or sorted-map
10:46`cbpThat is horrifying!
10:46Anderkentin most cases you don't care
10:46clgvsdegutis_: as I said. adding single elements to such a sequence didnt pop up that much in my projects
10:46sdegutis_`cbp: Yep.
10:47Anderkent(i.e. just `seq` it and forget about the problem :D)
10:47llasramAnderkent: Right, but when you do care, then you just know, or document, or check, or coerce, or whatever else is appropriate to the problem
10:47sdegutis_I've had to do it a few times, for example adding a header row to a CSV table.
10:47Anderkentllasram: sure.
10:47sdegutis_It just happens that I always care about where it's being added to the sequence at.
10:47clgvsdegutis_: you can use (list* header data) to be sure what you get ;)
10:48Anderkentunless you think you know it's a set so you don't bother checking and then nil comes in
10:48clgvworks for vectors as well
10:48sdegutis_That just sounds so idempotent though.
10:49pcnnewbie quetion here: is there a typical way to take a config file, e.g. .ini file, and read it with a module, and turn values that contain commas into lists?
10:50pcnI'm struggling with getting the mapping back from clojure-ini, then checking a subset of keys for values with commas
10:50`cbpsdegutis_: I feel like (into [header] table) would be preferable as it's faster and you dont turn it into a seq. Unless the table is a lazy seq then a conj would do the trick
10:50pcnthen returning the new mapping with lists in their place
10:51sdegutis_Could be so.
10:51sdegutis_May be so.
10:52pjstadig,(clojure.string/split "foo,bar" #",")
10:52clojurebot["foo" "bar"]
10:52pjstadigpcn: ^
10:52pjstadigif you know a key in a map you want to do that to, then you can use update-in
10:53pjstadig,(update-in {:foo "bar,baz"} [:foo] clojure.string/split #",")
10:53clojurebot{:foo ["bar" "baz"]}
10:53`cbppcn: maybe you can try instaparse for parsing config files
10:54pcncould be. I think my needs are better served by clojure-ini for now, but when I'm more comfortable in the language, maybe
10:55`cbpOh i didn't realize that library existed
10:58hhenkelIs there a way to set the body of a post request with http-kit?
11:07`cbphhenkel: I believe you add a :body key to the options map in http/post
11:08`cbphhenkel: Also :form-params are part of the body
11:08`cbp(and override it)
11:11AeroNotixso, I was thinking that (clojure.data.json/read .... :bigdec boolean) shouldn't just be for decimal numbers, but for all numbers. Right?
11:11AeroNotixAt the moment if the number is decimal... i.e. N.N then it converts
11:13hhenkel`cbp: yes, I had that...was missing a slash at the end of the url resulting in a strange behavior.
11:16ellisd23Howdy. I'm a pythoner at the moment and I'm looking to fully dive into Clojure after some sporadic dabbling in FP in the past. Does anyone have any good ideas or links to places with good ideas on small side projects I could hack on that would immerse me in Clojure and show me what it's good at?
11:18winkellisd23: I can present you a wildly random assortment of 113 clojure bookmarks, otherwise not so sure I can help https://pinboard.in/u:winks/t:clojure/
11:19ellisd23wjlroe, thanks, I'll take a look :-)
11:19`cbpellisd23: clojure is good at concurrency. Maybe you can try making a webapp with a chat using websockets, which is pretty easy in clojure and pretty hard in python
11:20ellisd23`cbp, ooh, interesting
11:20wink`cbp: I don't think it's that hard with tornado, but then again I never tried
11:21`cbpwink: I tried with flask + uwsgi + gevent and man was that hard
11:21wink`cbp: hehe ok :)
11:21winkI probably would've tried mongrel2 + brubeck first
11:23ellisd23`cbp, I guess I don't understand the concurrency aspect. If I had written such a thing in Django, obviously parallel requests can be handled for receiving the chat messages
11:25pcnellisd23: my experience is that twisted (not tornado, however) has a lot of sharp edges, and gets single-cpu limited.
11:25`cbpellisd23: yeah with django you'll have to handle those requests in parallel which means one instance per request which is very limiting.
11:25pcnThe workarounds suggested are overwhelmingly complex for the beneft derived.
11:25`cbpellisd23: in clojure you just handle them asynchronously with one thread per request or even with callbacks
11:26pbostromellisd23: perhaps a better example is if the chat app send messages that mutate some shared application state on the server, like user A logs out at the same instant user B sends a message to user A
11:31`cbpellisd23: basically the django implementation wouldn't scale at all
11:33ontoillogicalHow do I properly time a pmap?
11:33ontoillogical(time (pmap #(+ % % ) (range 10000))) doesn't do what I want it to do
11:35hyPiRionwrap it in a doall
11:35hyPiRion(time (doall (pmap ...)))
11:35`cbpor a dorun if you wanna be able to look at the time result :-p
11:36ontoillogicaloh of course
11:36ontoillogicalthanks!
11:48benmossdnolen_: have you seen http://facebook.github.io/react/blog/2014/01/02/react-chrome-developer-tools.html ?
11:48benmossworks decently well with om it seems
11:50jonathanj`cbp: should be easy with Twisted ;)
11:54technoma`nothing's easy in twisted =(
11:57jonathanjit's an OT conversation for this channel, but i would really love for people who say that (and there do seem to be quite a number) to explain to me where they were tripped up
11:57dnolen_benmoss: yes, we should submit a patch so that we can get names in
11:57technoma`I had the misfortune of taking over maintenance of a twisted app
11:58technoma`the API for reading public keys as part of the SSH server implementation was pretty much undocumented and didn't make a lot of sense
11:58dnolen_benmoss: that said, I think we still want instrumentation that's browser agnostic, I'm pondering how to do this properly for Om.
11:58technoma`luckily I didn't have to make many modifications to that codebase, but every single one I made was painful
11:59dnolen_benmoss: basically the idea is that any call to om/build could be intercepted
11:59dnolen_and you can wrap in an instrumentation component
12:00sm0ke_llasram: one quick question, can i do this any better (->> (avro/binary-encoded schema record) (avro/decode schema) type str)
12:01sm0ke_llasram: so basically i want to know the type of the record, the above is obviosly inefficent
12:06jonathanjtechnoma`: ah, yes, unfortunately people who don't "get" Twisted tend to write a lot of unmaintainable code and then run away
12:06technoma`well then when I joined the #twisted channel it was full of people trying their best to convince themselves that async is the only reasonable way to write network servers, and yes, all this pain is totally worth it in the end
12:06mikerodStrange, I have a - Caused by: java.lang.ClassFormatError: Invalid method Code length 297606 in class file file/path/name - that *only* occurs with AOT-compilation
12:06mikerodwell, technically only when I write class files
12:07llasramsm0ke_: Oh, -- you want to know the schema in a union that abracad will select to encode a particular object?
12:07sm0ke_llasram: right
12:07mikerodI can make this happen in the REPL by doing `(binding [*compile-files* true] (macro-generating-too-much-code))`
12:07llasramsm0ke_: I honestly can't think of a clean way to do that off the top of my head... OOC, what's your use-case for it?
12:08Anderkentmikerod: but having the macro in a file and then doing (require 'my.ns) doesn't trigger it?
12:08mikerodHowever, when I do not have *compile-files* set, I see no issue with the method size
12:08Anderkentweird.
12:08mikerodAnderkent: no,
12:08sm0ke_llasram: i want to vertically partition the data file location by creating sub folders named by type
12:09sm0ke_llasram: so given a union of schema i cant read a partiular type by reading files from that subfolder
12:11sdegutistechnoma`: so it wasn't just me then, they really were doing that
12:11sm0ke_llasram: do you think it would be possible to attach type metadata to the encoded record?
12:11mikerodAnderkent: I do not get the exception even when calling clojure.core/load
12:12sm0ke_llasram: so basically i can encode a record to bytes. take the meta,, then append the bytes
12:12sm0ke_i dont know if it makes any sense
12:12llasramsm0ke_: So I think it'd be better to do this outside of the Avro layer. Having a union schema implies that each given record in the set (e.g. in the file) could be anything in the union
12:12llasramIf you want to partition by type into separate files, then it seems like you should first partition by type, then write each file w/ the schema for that type
12:14sm0ke_llasram: yes that too makes sense, but ideally the used should have independence of having a complex schema union
12:14sm0ke_user*
12:14mikerodWell, never mind. load does fail with the same exception, it just doesn't print it out. :)
12:17llasramsm0ke_: Well. Hmm. Maybe. Unfortunately I don't have any good ideas right now though :-)
12:17lpetitclgv: hello
12:17clgvlpetit: hi
12:18lpetitclgv: do you use CCW these days?
12:18`szxfunctional thinking question: i'd like to iterate over all pairs in a sequence (using e.g. math.combinatorics) and update the results of the computation on *both* items
12:18clgvlpetit: yeah. never stopped to
12:18sm0ke_llasram: thats ok, the use case is peculiar i see
12:19clgvlpetit: 8-10 hours a day 5 days a week ;)
12:19lpetitclgv: so I have a question for you. Would you have objections to have Ctrl-Alt-S always start in debug mode instead of run mode ?
12:19lpetitclgv: wow :-)
12:19clgvlpetit: well I can rebind the keys, right?
12:20sm0ke_anyways i think the extra ser/de step is little cost to pay for partitioned data
12:20clgvlpetit: debug mode. you mean eclipse's debug launcher?
12:20lpetitclgv: yes, the question is about that, not about the exact key binding
12:22clgvlpetit: what would be the implications? eclipse asking me at least once to switch perspective and working breakpoints as default
12:22lpetitclgv: currently, when you're in a file, and you type ctrl-alt-c (or whatever you've rebound it to), you get (if no repl is active) : 1/ start in background, in "run launcher mode", of a java process for the project ; 2/ open a REPL View ; 3/ send the editor's code to the REPL ; 4/ switch the REPL's current ns to the editor's ns ; 5/ give focus to the REPL View. Right ?
12:23clgvyeah.
12:23lpetitclgv: hmmm, I think it depends on the exact settings. In my current configuration (but maybe not the default, maybe I've tweaked it, don't remember), it only tries to switch if code with breakpoints is hit.
12:24lpetityeah, working breakpoints as a default, that would be
12:24lpetitso that the easiest think to do is also the more powerful one
12:24clgvwell, if there are no disturbing effects I have no objections.
12:25clgvbut I hardly use breakpoints. when I started with clojure I used them pretty often but that decreased
12:25lpetitclgv: I've managed to get this exact workflow work for leiningen projects, with the difference that it's leiningen which manages the start of the project VM.
12:25clgvlpetit: great.
12:26clgvlpetit: so all the leiningen magic will work?
12:26lpetitclgv: you may be annoyed by old breakpoints you had set going to life, with the new settings.
12:26clgvlpetit: well that'll happen only once
12:26sdegutislazybot died
12:27lpetitclgv: yes, all leiningen magic. So for instance :injections taken into account
12:27clgvlpetit: then I could finally fix the missing `doc` and `source` by leiningen configuration ;)
12:27lpetitclgv: indeed
12:28lpetitI guess so, what would you do for that in leiningen, exactly?
12:30clgvlpetit: I guess I'd try vinyasa to map them into clojure.core (https://github.com/zcaudate/vinyasa)
12:31clgvlpetit: the simple answer is to just require clojure.repl after a namespace is loaded
12:32lvhhi
12:33lvhI'm looking desperately for a github project I found recently that used clojure and clojurescript; it composed three major projects. The last was definitely om (the react wrapper), I think the first was compojure, and the other one was datomic
12:33clgvlpetit: the simple solution is probably :injections as I checked
12:33bbloomlvh: was it dnolen's om-sync ?
12:34lvhdacom!
12:34lvhbbloom: nope: https://github.com/bellkev/dacom
12:34bbloomlvh: ah ok, b/c i thought david had an *example* in the om or om-sync wiki with all 3 of those
12:34lvhI thought it was codam but google kept thinking I wanted "condom"...
12:34lvhoh, awesome
12:34lpetitclgv: :injections will just send some code for evaluation when the repl server starts
12:36clgvlpetit: huh? as I read in the past it is prepended to every evaluation
12:36lpetitI wouldn't bet on it, but I may be wrong
12:36clgvlpetit: https://github.com/technomancy/leiningen/blob/stable/sample.project.clj#L209
12:37technomancyyes, it's for every eval-in-project call
12:37clgvoh. so only once per repl?
12:37technomancytypically that's when the JVM starts, but for eval-in :nrepl it will happen for processes that have been running for a while
12:38technomancyno, it can happen repeatedly
12:38technomancydepending on how eval-in-project is called
12:38sandbagsanyone aware of a library equivalent to the Ruby RVG library ("RVG (Ruby Vector Graphics) is a facade for RMagick's Draw class that supplies a drawing API based on the Scalable Vector Graphics W3C recommendation.")?
12:39sandbagsgoogle isn't turning anything useful up
12:39lpetitclgv: well, I'm not sure :injections works with lein repl :headless at all (either on command line or via ccw)
12:39sandbagsah found something tikkba
12:40sandbagssorry for the noise
12:40clgvlpetit: I had no chance to try it in CCW so far ;)
12:40`cbpsandbags: it's not noise
12:41`cbpsandbags: there's also analemma
12:41lpetitclgv: i guess if :injections does not work with repl :headless, we should try to fix it at the heart, in leiningen itself. Probably by doing some kind of middleware which would always prepend code received via nrepl connections for evaluation ...
12:42sandbags`cbp: yeah i was just looking at that one too
12:42sandbags`cbp: i'm looking to dynamically generate an image from a logo and some text obtained via a REST API call
12:42lpetitThat way, this would work the same either via "lein repl" (and the embedded repl client) and "lein repl :headless"
12:43clgvlpetit: well repl-y fixes the clojure.repl issue at the frontend
12:44lpetitat *one* front-end, the command-line one. And only for Linux/OS X I guess.
12:44TEttingersandbags, there's even AWT for that if you wanted to do it with no dependencies
12:45sandbagsTEttinger: i'm looking to output as a PNG
12:45TEttingerright, I use AWT for that
12:45sandbagsit's been ~14 years since i used AWT
12:45TEttingerheh
12:45sandbagsoh, right
12:45sandbagsthings change :)
12:45sandbagsdoes AWT work headless?
12:45clgvlpetit: yeah ok. that's true it is only that frontend...
12:46sandbagsi'll be doing this on an EC2 instance running probably debian
12:46TEttingerI actually have no idea, I have it running as a console app, but it might need some kind of graphics capability
12:49TEttingerI wrote this a long time ago and have been tweaking it continually for different fonts I need rendered https://dl.dropboxusercontent.com/u/11914692/mess.clj
12:50sandbagsthanks TEttinger
12:52TEttingersandbags, I uh wouldn't try running it as-is, but the general method should be clear enough of how to interact with AWT from clojure. if you do want to run it, it expects https://dl.dropboxusercontent.com/u/11914692/unicode.txt in the same dir... and a bunch of undocumented command line args
12:53sandbagsheh, yeah i was just looking at it as source material :)
12:57sdegutisJim Weirich's last commit, plus comments: https://github.com/jimweirich/wyriki/commit/d28fac7f18aeacb00d8ad3460a0a5a901617c2d4 -- I'm surprised nobody's commented "He's dead, Jim."
12:57sdegutisA little longer and he would have gotten into Clojure probably. All the Rubyists are doing it.
12:57technomancyhe gave a talk on clojure at strange loop
12:57sandbagsi believe he said he was dabbling
12:57technomancyit was awesome
12:58technomancywell, a talk on the Y combinator, given in Clojure and Emacs
12:58sdegutisAlthough I guess it would be disrespectful to say "He's dead, Jim."
12:59pcnyou think?
12:59sdegutisI'm starting to think so.
12:59pcnYeah. I kind of hope no-one does that
12:59llasramsdegutis: And how are you enjoying your visit to our planet? ;-)
13:00sdegutisIt's okay so far. Missing the context free grammar back home.
13:01sdegutisI like your "soda pop" though.
13:01`cbpfirst concat instead of conj now this
13:01`cbpyou done gone insane
13:01sdegutisOh sorry, is it just "pop"? I thought that was slang for "punch".
13:05sdegutisIt's possible Jim isn't really dead.
13:06sdegutisHe hasn't tweeted or committed recently, but the only news that he's passed is that someone said RIP on his github commit.
13:06sdegutisHope this isn't a prank.
13:07kitallisreally?
13:07sdegutisMore likely I'm probably just in denial.
13:07sdegutisFirst stage of grieving and all that.
13:10sdegutisAlso I avoid dynamic vars like the plague. Is this healthy?
13:10technomancyyes
13:10sdegutisI'm tempted to use one right now, to toggle whether you're an admin previewing the site, or just a normal user.
13:10technomancythat's what they said about the black death too
13:11technomancy"it's just a few rats; what's the worst that could happen?"
13:11sdegutisThe alternative is changing API functions to take another argument (:preview?), or possibly duplicating page code to render under a new URL or something.
13:11technomancyps. don't listen to me
13:11sdegutisWhy not?
13:11technomancybecause I lie a lot
13:12sdegutisWait... is that.. is that a lie?
13:13technomancyseriously though, I think it's a matter of dividing code into the functional core and imperative shell. things that would be terrible in library code might be acceptable when used at the "outside" of the codebase
13:13sdegutis(trptcolin: was Jim Weirich the one who showed up at our 8LU in LVille a few years ago? Or was that someone else?)
13:13technomancybecause as long as the core is functional, and the shell is small enough, you can fit everything you need to know into your head at once.
13:13sdegutistechnomancy: hmm, now that you mention it, that sounds like a familiar paradigm
13:14sdegutisLike, as long as the dynamic var never strays into the core, then it's okay.
13:14technomancydynamic vars add complexity overhead. as long as they don't blow your complexity budget, they can be a reasonable trade-off if you know their scope won't be too broad
13:14sdegutisExcept in this case, that's exactly what it'd be doing. Which makes me noivous.
13:14technomancypretty much, yeah
13:14trptcolinsdegutis: i don't remember seeing him here, but met him at a few confs around here. such a nice person.
13:14sdegutisHmm. Now I wonder who that guy was. I think he was a Jim. He wrote a book, and I think he gave us a mug.
13:15technomancyyeah, Jim was one of the friendliest and most welcoming programmers I knew
13:15technomancythe Emacs Starter Kit was actually his idea that I ran with
13:15sdegutisSo it was *you*!!
13:15trptcolinsdegutis: oh, you're thinking of james grenning i believe
13:15sdegutisAh yes.
13:16sdegutisToo many Jims.
13:16sdegutisEr, I mean, Jim names. Not too many people.
13:17zerowidthsdegutis: evan phoenix said he had confirmation from several sources before tweeting about it
13:17sdegutis:/
13:19`cbpDynamic vars are bad! They make me afraid of putting things on other threads
13:19sdegutisHmm, that's an interesting consideration.
13:20sdegutisYou'd have to be sure to read it first and pass it to the other thread if anything.
13:20technomancyin your core you need to write code that works in any threading context. in your shell, you can usually know what threading context a given defn will be used in.
13:21sdegutisSo let's say you have a webapp (in this context, is it "let's
13:21sdegutis" or "lets"?)
13:22technomancylet us
13:22sdegutisIn this case, we can only assume each request runs in its own thread (might not be true, but safest assumption).
13:23sdegutisSo the only time you'd want to do other threading is when you're explicitly doing background work. At which case you're ideally spinning up the thread at the high-level of the request, not low-down into whatever the request handler is doing.
13:23sdegutisHmm, in that case, dynamic vars seem perfect! Because you'd statically know which core functions are on what thread.
13:34technomancyoh, plus you have laziness to consider
13:34technomancybut typically at the outside you have all you need to make an informed choice
13:35sdegutisThanks all.
13:38sandbagsdefinitely liking gorilla repl
13:41sdegutisMostly for graphs/charts, right?
13:46sandbagswell as a playtime repl it's also pretty nice
13:46technomancydammit
13:46sandbagsbut the USP's are the Markdown/Latex note support
13:46technomancyI was gonna do portable rich-content repls as my clojure/west talk
13:46sandbagssave/load session
13:47sandbagsi'm hoping adding MathML isn't too hard as it's been ~20 years since i did any Latex
13:47technomancynow people are going to keep going off and implementing this stuff in editor-specific ways, aren't they
13:47sandbagsnot sure what that talk doesn't still fly
13:48llasramtechnomancy: Until you stop them / show them how its done!
13:48technomancyllasram: but I'm not even using clojure any more =P
13:48technomancyI don't want to write a bunch of code just to stop people from doing something I think is wrong-headed
13:48technomancybut if people keep pulling this stuff I might have to
13:49bbloomtechnomancy: surely if your yak shaving powers are insufficient, we must call cemerick
13:49bbloomtechnomancy: or abandon all hope
13:49technomancybbloom: already in the middle of a massive yak shave, sorry
13:49bbloommmmm yak fur
13:49technomancyhttps://secure.flickr.com/photos/technomancy/12642312163/
13:50michaniskinthat's the best time to get involved with more yak shaves though!
13:50bbloomtechnomancy: are you seriously going to make your own keyboard?
13:50michaniskinthe Inception Shave is how it's done, didn't you know?
13:50bbloomtechnomancy: that's pretty hardcore.
13:50technomancybbloom: just waiting for the microcontroller to arrive in the mail
13:50sdegutistechnomancy: not using clojure anymore, hmm? do you still maintain lein?
13:51technomancysdegutis: here and there
13:51bbloomtechnomancy: i bow at the feet of your yak blade
13:51TimMcI don't understand Flickr anymore.
13:51bbloomtechnomancy: i'm clicking through more photos. is this a mini keyboard for you kid?
13:51technomancybbloom: no, he's just modelling it
13:52bbloomtechnomancy: ah ok
13:52bbloomi like the big green buttons :-P
13:52technomancyI wouldn't go otaku for my kids =)
13:52technomancy(no labels, I mean)
13:52technomancynot till they're at least ten anyway
13:52bbloomhaha
13:52bbloomthat coffee shop looks familiar...
13:52bbloomok i'm done :-P
13:54TravisDtechnomancy: Is there some underlying idea behind those cool looking keyboards?
13:54TravisDLike, a reason you made them, instead of using what's available
13:55technomancyTravisD: a few main things
13:55technomancy0) mechanical switches have a really crisp feel to them that make me happy
13:56technomancy1) most keyboards are staggered by row, which comes from trying to avoid typewriter jams. I like mine staggered by column, because I'm a human with fingers of different lengths.
13:56technomancy2) having an on-board microcontroller with firmware you can reprogram on the fly is awesome
13:56TravisDhehe, cool :) How many have you made?
13:56TravisDSeems like something that would take some practice
13:56turbofaili prefer to enforce a uniform finger length
13:56technomancyTravisD: I've assembled one from a kit, which I posted about here: http://technomancy.us/172
13:57bbloomi use a kenesis contoured for reasons #0 and #1, but RE: #2 it has a microcontroller for programming which i haven't used since the day i got it and remapped caps lock to control
13:57technomancyTravisD: and I'm in the middle of building one from scratch: https://github.com/technomancy/atreus
13:57technomancybbloom: does it support unshifted parens? that's one of my favourite tricks
13:57TimMcturbofail: I know someone who doesn't trim his pinky nails because that gives him better reach...
13:58TravisDtechnomancy: cool, thanks :)
13:58bbloomtechnomancy: i assume i could make it do that somehow, but my brain already has a hard enough time going back to my laptop keyboard & i don't wanna have to drag around a keyboard to coffee shops like *cough* some folks
13:58amalloythat's why you'll never be cool, bbloom
13:58technomancybbloom: yeah, that's actually why I don't have a kinesis
13:59technomancyeven the ergodox is a bit of a beast to drag to coffee shops, that's why I started working on my own
13:59turbofailTimMc: ha. i was envisioning something a little more violent.
13:59bbloomtechnomancy: when you're finished with that yak, you should totally shave a whole flock (herd? what do you call multiple yaks?)
14:00bbloomtechnomancy: by that, i mean, you should totally make a tri-component laptop where the display separates from the two halves of the keyboard
14:00bbloomhow hard could it be really?
14:00bbloomif you don't do it, amalloy won't think you're cool
14:01technomancybbloom: I'm definitely going to be keeping copious notes in case anyone else wants to build one
14:01technomancythe ergodox runs $240 if you get in on a group-buy with volume discounts; mine can be made for about $100 plus shipping
14:01technomancyI mean, assuming I get it working
14:01bbloomheh
14:02benkayany Listora folks in the room?
14:06dnolen_Om 0.5.0 going out, support React 0.9.0
14:06dnolen_supports
14:09TEttingerbbloom, oh man.
14:10fredyrdnolen_: oh, does support means require 0.9.0?
14:10bbloomTEttinger: ?
14:10dnolen_fredyr: yes
14:10fredyrdnolen_: that might explain what im seeing right now then
14:10fredyrdnolen_: :)
14:11dnolen_fredyr: I've updated all the docs / tutorials etc. Feel free to fix up anything I may have missed.
14:11dnolen_fredyr: or if it's actually in the Om repo, point it out.
14:11fredyrdnolen_: sure, but this was on my part
14:12fredyrdnolen_: did update cljs version and om, but missed the new react version
14:12fredyrdnolen_: will def let you know if i find anything
14:12dnolen_fredyr: cool thx
14:12TEttingerbbloom, the old dell axims came with external keyboards that unfolded kinda like that http://i.ebayimg.com/00/s/MTIwMFgxNjAw/z/60oAAMXQyfFSA7Bp/$(KGrHqN,!k8FH6eRO)GKBS!7Bont0Q~~60_1.JPG?set_id=8800005007
14:13bbloomTEttinger: ha! i remember playing with something like that once, crazy
14:13TEttingerit had a good motion too
14:14TEttingerit would unfold into a shape like http://g-ecx.images-amazon.com/images/G/01/ciu/1f/88/ade9c060ada0c18b51a20210.L.jpg
14:28sdegutisI can't help but think that macros complicate things too much for too little gain.
14:29AimHereWriting macros is complicated and painful. Once they're properly wrote, they make your life easier
14:30sdegutisStill.
14:33AimHereBesides, the solution if you're having that very problem is don't use macros
14:33fredyrdnolen_: i'm getting a mysterious error with build-all when trying to upgrade to 0.5.0
14:34fredyrdnolen_: my component function never gets called, but i get a couple of numbers in the dom
14:34amalloyAimHere: if you find writing macros complicated and painful, you're either writing macros that are too complex, or you don't have enough practice writing them
14:34dnolen_fredyr: did you make the necessary changes outlined in 0.5.0-rc1?
14:36muhootechnomancy: did you abandon the keyboard pants?
14:36technomancymuhoo: basically they were too much work to get in and out of when I needed to use the loo
14:37`cbpthe keyboard pants?
14:37`cbpim dying
14:37sdegutis:'(
14:37sdegutisoops typo i meant :)
14:38amalloy`cbp: http://www.flickr.com/photos/technomancy/4397554484/
14:39`cbphah
14:39technomancymuhoo: I do plan on creating a mount for my keyboard that hangs below the surface of my desk and lets me type in a more neutral position
14:39amalloythis was back around the time of the first conj, i think?
14:39fredyrdnolen_: where do i find those?
14:39technomancykind of a compromise between keyboard pants and the conventional position
14:39dnolen_fredyr: CHANGES.md
14:39amalloytechnomancy: +100 to that idea, by the way - i've done that at my last two jobs
14:40dnolen_fredyr: also the React blog
14:40technomancyamalloy: cool
14:40technomancyI'm hoping to build something with tenting
14:40amalloyeh?
14:40muhoo.... tenting?.... o_O
14:41technomancyamalloy: so my hands don't have to lay out flat
14:41technomancykinda like this http://www.thehumansolution.com/kinesis-ascent-multi-tent-accessory-kit.html
14:41technomancybut hanging below the surface of the desk
14:42amalloyninjudd had one of those
14:42fredyrdnolen_: right, i saw that, but i don't see them breaking anything w/ build-all, right?
14:42amalloybefore he discovered the kinesis, i guess
14:42dnolen_fredyr: hard to say, I haven't encountered any issues with build-all
14:42dnolen_fredyr: I have examples that use it and I test against Om TodoMVC
14:43dnolen_which also uses it
14:43fredyrdnolen_: yeah, its probably something ive done
14:44fredyrdnolen_: it works if i swap it for build f (first entries)
14:50fredyrdnolen_: it seems to have something to do with mapping over the cursor
14:51fredyrdnolen_: i got it to work with a manual (mapv (fn [x] (om/build entry-component x)) entries)
14:51fredyrdnolen_: but using map gave the same error
14:53amalloy~map
14:53clojurebotmap is hard
14:53dnolen_fredyr: you should be able to find your problem with source maps.
14:53amalloywell, i was going for "map is LAZY", but close enough
14:53dnolen_fredyr: I see no reason for mapv to work over map
14:54fredyrdnolen_: hmm ok, thanks i'll try to dig into it
14:56TravisDFor a datatype T, are T. and ->T identical functions?
14:57amalloyTravisD: no, because T. isn't a function
14:57TravisDah
14:59TravisDamalloy: I'm just looking at the documentation. Is it a reader macro for (new T ...), which is a special form?
14:59TravisDmaybe not a reader-macro.
15:00llasramTravisD: I don't think there's an official name. I call them "pseudo-macros"
15:01llasramThey're expanded by the compiler during macro-expansion
15:02bbloomllasram: it's a reader macro. clojure offers several types of (non-extensible!) reader macros
15:03llasrambbloom: No, I don't think so
15:03llasram,`(Example.)
15:03clojurebot(Example.)
15:03llasram,`(.example again)
15:03clojurebot(.example sandbox/again)
15:03llasramCompiler, not reader
15:03bbloomllasram: good point
15:03bbloomllasram: ok then, it's a compiler-macro :-)
15:04TravisDI don't know much about macros, but can one macro create new macros? Then it might make sense that defrecord introduces the DataType. macro
15:04llasramBut at least does happen as part of macro-expansion
15:04llasram,(macroexpand `(Example.))
15:04clojurebot(new Example)
15:04llasram,(macroexpand `(.example here))
15:04clojurebot(. sandbox/here example)
15:04TravisDoh weird, so it actually works even for things that aren't datatypes
15:04TravisDlike, arbitrary symbols
15:05bbloomllasram: ok then, it's a compiler-macro :-)
15:05llasramTravisD: Yeah `Symbol.` and `.symbol` are magic "compiler-macro" syntax
15:05llasram(as we will now call them)
15:05TravisDthat's a bit sad :(
15:06llasramIt is an odd complication, but the result is convenient
15:06TravisDyeah, true
15:07TravisDI guess it's not really any different from special forms
15:08TravisDlike, the compiler already has a few special cases. It's not /so/ strange to add a whole family of special cases, if they're convenient
15:12bbloomsyntax is inherently special cases
15:12bbloomthat's what syntax is
15:12bbloomclojure decided that syntax should be minimal, but the correct amount is slightly more than scheme
15:12bbloomseems reasonable to me :-P
15:13pjstadig"slightly more"?
15:14bbloompjstadig: scheme has strings with escape sequences and the cons dot notation, and numbers, ratios, etc
15:14bbloompjstadig: what did clojure add? a few extra sets of matching braces, repurposed dot, and the deref @ operator?
15:14bbloompjstadig: yeah, slightly more :-P
15:14pjstadigdo you consider destructuring as syntax?
15:15bbloomyes, but now you're getting in to the question of where does syntax live
15:15bbloomi consider any function that takes position arguments to be syntax :-P
15:16pjstadigwell i mean i'm not necessarily disagreeing with you
15:16pjstadigi wouldn't say there's "buttloads more" syntax in clojure
15:16pjstadigbut i might go a smidge higher than slightly more
15:17bbloom*shrug* pick a word
15:17pjstadighaha
15:17pjstadigi define my word to be semantically not whatever your word is :-p
15:18dnolen_pjstadig: well, modern Scheme has a lot a syntax now I would say, it's been ~16 years since you could say Scheme was truly minimal syntax wise.
15:26maglopHi; I'm looking to preprocess a file line by line with lazy-seq before I pass it on to enlive. I don't see a way to get a Reader or InputStream interface to a seq, though. Am I approaching this badly?
15:30Wild_Catmaglop: line-seq, maybe?
15:32maglopThat gets me the first part, but then I need to somehow get back to exposing that as bytes as a Reader
15:33rhg135any thoughts https://bitbucket.org/rhg135/gutter
15:33Wild_Catmaglop: so you need something that takes a Reader and transforms it to another Reader that returns a lazy seq of the first Reader's lines?
15:34rhg135it isn't too bad?
15:34Wild_Catmaglop: isn't that the definition of the BufferedReader interface?
15:35maglopWild_Cat: maybe? I will be changing the data on the way, though
15:35benmossrhg135: you know about enliven?
15:35benmossenlive rather
15:35rhg135yup
15:35rhg135i've used it too
15:36rhg135had some crazy idea jsou was faster
15:36maglopTakes a Reader, modifies the data on a line by line basis, and then exposes the modified data as a Reader
15:38sdegutis_Clojure has 0% syntax.
15:38sdegutis_Absolutely none.
15:38rhg135nah
15:38rhg135more like %3
15:39rhg135well it depends
15:39rhg135it isn't necessary to lear but its nice
15:50sdegutis_Okay, let's compromise and say it's about 80% syntax.
15:51sdegutis_But that the 20% that's semantics happens to be really super consistent.
15:53amalloyexcept nth
15:53amalloythat is super inconsistent
15:54rhg135how is nth inconsistent?
15:54amalloyit's the only sequence function that takes the collection as its first arg
15:55amalloy(nth coll n), (take n coll), (map f coll)
15:56dkinzeryeah, but it's consistent with it's origin in scheme. http://hyperpolyglot.org/lisp
15:56amalloyit's also one of very few functions that will be either O(1) or O(n) depending on what you pass it
15:56amalloydkinzer: yes, i'm aware of why we have this function; that doesn't make it consistent with clojure
15:56dkinzerhistorical consistency sometimes trumps other stuff.
15:56amalloydkinzer: well, send a pull request replacing first/rest with car/cdr
15:56dkinzeramalloy: true.
15:57dkinzer:)
16:00dkinzerthough racket uses both (car, first) and (cdr, rest).. but maybe racket is not really scheme.
16:03technomancybutlast having no hyphen =\
16:03joegallough, yes
16:03technomancyyou know: real, hard-hitting issues
16:06amalloyi dunno, i'm okay with butlast's name. but-last isn't really better, because there's no...verb? that sounds silly, but mashing an adjective together with a modifier feels better to me than doing it with a verb
16:08sveri1hi, i am trying to login with the friends library and i use this code: http://pastebin.com/ajnhffa4 However, everytime i submit my form i get a 404 error back saying the resource was not found, any ideas what I am missing here?
16:08amalloythe fact that butlast isn't lazy and drop-last is...*that* bothers me
16:08technomancyyeah, know that I think about it the "you use a hyphen for identifiers containing two words" comes from CL, not clojure
16:08technomancy*now
16:08sdegutis_amalloy: it returns a single element though, not a whole coll
16:08amalloysdegutis_: not true at all
16:08sdegutis_oh
16:08sdegutis_amalloy: please disconfuse me
16:09sdegutis_,(nth [1 2 3] 1)
16:09clojurebot2
16:09amalloy&(butlast [1 2 3 4])
16:09amalloyoh, you're talking about forever ago
16:09sdegutis_yep, im always behind the times
16:09amalloywait what? 2?
16:09sdegutis_0-based
16:09amalloyoh, that was clojurebot. lazybot is ignoring me
16:09sdegutis_lazybot is dead
16:09dkinzernot so weird also when you consider that most of the core operators don't have hyphens.
16:09amalloyi thought 2 was the answer to (butlast [1 2 3 4]) and i was going to change careers
16:10sdegutis_i mean, missing
16:10sdegutis_amalloy: wow, what kind of trauma have you been going through that such a small discontinuity is the straw that killed the camel with two stones?
16:11amalloylazybot, i summon thee!
16:11dkinzer ,(butlast [1 2 3 4])
16:11clojurebot(1 2 3)
16:11sdegutis_WHOA.
16:11sdegutis_that was cool
16:11amalloy*chuckle*
16:11TravisDamalloy: Convenient timing? Or does it somehow monitor the channel through the other bots?
16:12amalloyi just restarted him
16:12amalloy&1
16:12lazybot⇒ 1
16:12technomancyhow about this: assoc works on vectors, but not dissoc
16:14sdegutis_I followed the mailing list thread about that. That's about the time I started realizing maybe Clojure isn't going in the best direction.
16:14sdegutis_&()
16:14lazybot⇒ ()
16:14sdegutis_That too.
16:15sdegutis_Every time you see an unquoted set of parentheses, it's a function call. Except when they're empty, then it's a literal list.
16:15sdegutis_,(= () '())
16:15clojurebottrue
16:15sdegutis_Oh man. That's totally a nerdy robot emoticon!
16:17devnsdegutis_: I have Leah Hanson's ear on Romeo. I think she's going to stop by sometime this week and give me some guidance.
16:17devnShe's working on the type checker.
16:17mklappstuhl_whats an idiomatic way to check if a "stringA" starts with "str" ?
16:17technomancysdegutis_: also in letfn, proxy, and reify, paren sets don't indicate function calls but definitions
16:18sdegutis_devn: sweet
16:18devnmklappstuhl_: you could use java
16:18devn,(.startsWith "abc" "a")
16:18clojurebottrue
16:18technomancy(and maybe a few other hosty macros)
16:18amalloyalso deftype and defrecord, which technomancy prefers to believe don't exist
16:18sdegutis_technomancy: I totally agree: out of all languages, Clojure is probably the most consistent.
16:18devn,(re-find #"^a" "abc")
16:18clojurebot"a"
16:18llasrammklappstuhl_: ##(.startsWith "stringA" "str")
16:18lazybot⇒ true
16:18bbloom+1 for the re- approach
16:18technomancyamalloy: la la la can't hear you
16:18amalloyand sometimes in fn/defn: (fn ([x] x) ([x y] (+ x y)))
16:19llasramHuh, I thought that went to lazybot
16:19devn,I like using re-* personaly
16:19clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: I in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:19llasram,(.startsWith "stringA" "str")
16:19clojurebottrue
16:19devnpersonally
16:19llasramWhoa, I was lagged
16:19devnllasram: no worries :)
16:19technomancysdegutis_: "all languages" being "th eset of languages you can get paid to work in"?
16:19devnheh
16:19sdegutis_technomancy denies deftype? But.. how else do you define functions in Clojure programs?
16:20sdegutis_technomancy: No, all languages.
16:20sdegutis_I've never seen or heard of a more consistent language than Clojure.
16:20dkinzerThe empty parentheses one is totally weird.
16:20sdegutis_Prove me wrong please. I really want to be wrong.
16:20technomancysdegutis_: have you learned forth?
16:21sdegutis_dkinzer: I'm very grateful to find someone who agrees with me on this; last time I brought it up, I got a lot of "nah that's totally consistent and expected and good and normal"
16:21sdegutis_technomancy: That toy language?
16:21devndoes anyone here have any opinions on postgres-friendly sql abstractions in clojure beyond jdbc, something that's a bit more "i don't know SQL but have used ActiveRecord" friendly? How about one that /isn't/ korma?
16:21sdegutis_technomancy: Can you write *actual programs* in it?
16:21sdegutis_That do, like, useful things?
16:21sdegutis_I thought it was an esolang.
16:21technomancyactually kind of tempted to write my keyboard firmware in forth
16:21sdegutis_!
16:22devnmy god technomancy, you are a bad ass.
16:22dkinzersdegutis_: nah, I agree with you; it doesn't make any sense. It's supposed to be an empty set so why not just return the something with the set syntax?
16:22technomancydevn: well I haven't *done* it
16:22devnyou will have forth-powered, laptop pants
16:22devnerr keyboard pants
16:22technomancyI wimped out and ordered an AVR microcontroller instead so it could run one of the existing firmwares
16:22sdegutis_technomancy: no, he's right actually; I've never met anyone who talked about writing firmware; that's pretty hard core
16:23technomancybut I specifically bought this ARM-based one because I wanted to run a forth or scheme on it
16:23technomancysdegutis_: you should hang out in #geekhack
16:23devntechnomancy: omg they have a freenode channel?!
16:23sdegutis_Nope. I don't want to *always* feel like I'm writing in QBasic while everyone around me is inventing anti-gravity force fields.
16:23devngeekhack is a fantastic community
16:24sdegutis_Just once in a while :)
16:24technomancydevn: except for the caveat of "uses php-based forum software non-ironically" I agree =)
16:24devn:) It gets the job done. *shrug*
16:24sdegutisoh man, i wrote a phpbb competitor once in.. php
16:25devnSo, one more attempt: Do you guys have a suggestion on a SQL abstraction lib that isn't Korma and provides a semi-friendly interface to postgres?
16:25sdegutisIs Datomic an option?
16:25devnI've used jdbc, but I'm going to be leveling someone up and want to ease him in.
16:26devnsdegutis: unfortunately no.
16:26sdegutisSorry.
16:29xuserdevn: java.jdbc has a minimal DSL I think
16:29mklappstuhl_I'm surprised how how hard some simple things in clojure can be sometimes. I want to filter a list of strings based on an input string. It's fairly trivial using .startsWith but using re-find it becomes quite a bit more complex
16:31sdegutismklappstuhl_: the Clojure philosophy is to use the platform when it's more convenient I think
16:32sdegutismklappstuhl_: I've used #(.startsWith %) with filter I think
16:32technomancymklappstuhl_: oh man, that reminds me of another of my gripes
16:32technomancyif regexes were ifn this would be easy
16:32technomancyyou probably just want partial re-find though
16:32BobSchackdevn https://github.com/krisajenkins/yesql if you're not looking an ORM.
16:32ToBeReplacedhow do i type-hint ProcessBuilder to avoid reflection?
16:32sdegutistechnomancy: isn't %() preferred over partial btw?
16:34mklappstuhl_sdegutis, issue with platform is, that it varies from platform to platform :D
16:34technomancysdegutis: not by me =P
16:35dkinzer,[(identical? '() ()) (identical? '() []) (= '() []) (= '() #{})]
16:35clojurebot[true false true false]
16:35sdegutismklappstuhl_: there's only one platform, Java. don't let anyone tell you otherwise!
16:37mklappstuhl_sdegutis, I'm actually using cljs right now ;D
16:37amalloy&(identical? () (list))
16:37lazybot⇒ true
16:37sdegutismklappstuhl_: nice
16:37amalloy*chuckle* if CL did that, the entire macro system would collapse
16:40whodidthisany tips on doing multiple channels over a single channel?=(
16:41ToBeReplacedwhodidthis: mix and mult for n-to-1 and 1-to-n
16:41sdegutisSo, I heard some people talking about Common Lisp recently. Seems like a good production read Lisp. What do you all think?
16:41sdegutis*ready
16:42technomancy"production" is a funny word
16:42technomancywhat are you producing?
16:42technomancyHTTP responses, I guess?
16:42technomancyit makes me think of factory assembly lines
16:43ToBeReplacedI'm looking for a way to invoke (ProcessBuilder. (into-array ["echo" "hi"])) without causing reflection -- any recommendations? afaik i can't type-hint the complex type
16:43sdegutisYou know, Production.
16:43sdegutisLike, where the code goes when I deploy to the nodes.
16:44amalloyToBeReplaced: ^"[Ljava.lang.String"
16:44sdegutisThe thing that executes "ENV=production sudo rake server:start".
16:44technomancyToBeReplaced: I don't think it's possible for reflection to be a bottleneck when launching processes FWIW
16:44amalloyerrrr, might need to be ^"[Ljava.lang.String;"
16:44amalloy&(class (into-array ["x"]))
16:44lazybot⇒ [Ljava.lang.String;
16:45amalloywell, that's true too. but maybe you want to be able to `lein check` and not get any warnings
16:45ToBeReplacedamalloy: correct, thanks, didn't know i could put quotes around it
16:45ToBeReplacedtechnomancy: you're right, it's not a bottleneck -- it was ugly with lein check and it's an easy standard to hold people to
16:46technomancyah, sure
17:06akurilinAnybody here using Migratus? I'm wondering if multiple statements in a migration all get wrapped into one single transaction. I'm looking at the source and it seems to be the case, but I just wanted a sanity check: https://github.com/pjstadig/migratus/blob/master/src/migratus/database.clj#L43
17:16bitemyapptechnomancy: :env/blah keywords in Leiningen defproject, how do I "or"?
17:18technomancybitemyapp: hrm... I think you might need unquote or read-eval for that
17:18bitemyappyou know what, n/m, it's only for GPG stuff I guess.
17:18bitemyappwe're not using it for that, we just wanted a fallback for something nicer than ~
17:18bitemyappbut we'll stick with ~ for now then
17:18bitemyapptechnomancy: thanks, reading the source answered my question, sorry to bother you :(
17:19bitemyapptechnomancy: cheers
17:19technomancyno worries
17:23`szxis there a nicer way to do a commutative memoize than combining all the arguments into e.g. one set?
17:24`szxe.g. https://www.refheap.com/43097
17:24ordnungswidrigtechnomancy: are there known issues with with-profile, clojure-version-deps and test?
17:25amalloywell, a set won't work at all
17:25technomancyordnungswidrig: what's clojure-version-deps?
17:25amalloysince (add 1 1 1 1)
17:25amalloyyou almost need like a frequency map, if you really don't care at all about parameter order
17:26`szxyeah, bad example - they are unique in my case
17:26ordnungswidrigtechnomancy: i try to vary the dependency on the clojure version in profiles for testing
17:27`szxamalloy: i guess = would be a better example than + in this case
17:27ordnungswidrigtechnomancy: like in http://technomancy.us/158
17:29technomancyordnungswidrig: I don't know of any issues around that
17:30ordnungswidrigtechnomancy: I end up with this: https://www.refheap.com/43098
17:46technomancyordnungswidrig: I don't think that has anything to do with Leiningen
17:48ordnungswidrigtechnomancy: lein test works, lein with-profile dev,1.5 test fails with the above error.
17:49technomancysure
17:49technomancybecause your code calls contains? on a lazy seq
17:49technomancyolder versions of clojure fail silently on that
17:50technomancyFSVO "your"
17:58ordnungswidrig1technomancy: oh dear, you're right. the default I defined is 1.4, not 1.5. thanks a lot!
17:59technomancyno problem
18:10tjdis there a builtin function f such that (f g x) == (g x)?
18:11joegallolike, (invoke inc 1) == (inc 1) ;; (not that invoke exists, just asking if that's what you're getting at
18:11hyPiRiontjd: Could you give an use case? Generally you can just remove f
18:11amalloytjd: no, there isn't
18:11seancorfieldseems like the closest thing for be apply: (apply g [x]) == (g x)
18:12amalloyhyPiRion: well, that function is useful in cases where you're not writing it as a literal
18:12tjdapply is close but not quite
18:12joegallo,((fn [f & args] (apply f args)) inc 1)
18:12tjdsince it destructures the arg
18:12clojurebot2
18:12Bronsawell. ##(deliver inc 1)
18:12lazybot⇒ 2
18:12amalloy(condp invoke x, even? :even, odd? :odd), for example
18:12amalloyor (map invoke list-of-thunks)
18:14hyPiRionWhere's FUNCALL when you need it
18:15technomancyhyPiRion: it's hiding in clojure.core/deliver
18:15technomancy(for arity 1 anyway)
18:16tjd(deliver inc 1) oh... oh my.
18:17hyPiRionWell, it's a neat hack, I'll give you that
18:17technomancylike many things, I learned it from amalloy
18:26dsrxha
18:30TimMcor trampoline, if you know the return value isn't a function :-P
18:30TimMc$findfn + 2 3 5
18:30lazybot[]
18:30TimMcOh come on, lazybot/
18:30TimMcThat's pretty lazy, even for you.
18:36technomancyheh
18:49seancorfieldBronsa: just looking at that (deliver inc 1) ... that's weird :) but the source of deliver shows why that happens... TIL: you can deliver a promise by calling it with a value!
18:50technomancyWelcome to Clojure, where everything[1] is a function!
18:50technomancy[1] - except regexes; those are dumb.
18:50hyPiRionit's not like picolisp though
18:51hyPiRionIn Picolisp, (1 2 3) is like saying (defn 1 [& args] (apply list 1 args)), except more efficient
18:55technomancyI'm not entirely sure I *want* to understand that
18:57hyPiRionOh, that came out wrongly. All numbers are functions, so (1 2 3) is the same as (list 1 2 3)
18:57hyPiRionthey are sort-of like autoquoted
18:57technomancywow
18:58bob2is there some way to put part of my ~/.lein/profiles.clj in another file? I have it checked it into vc, but would like to be able to put some non-vc'd stuff in there too
18:58Raynes&(trampoline + 1 2 3)
18:58lazybot⇒ 6
18:58technomancybob2: there is!
18:58technomancyhang on, I know this one...
18:58RaynesTimMc: Not sure why he didn't get that. Maybe his sandbox is getting stuck on trampoline for some ridiculous reason.
18:59hyPiRionhttp://software-lab.de/doc/ref.html#ev
18:59technomancybob2: I think you can do ~/.lein/profiles.d/myprofile.clj
18:59bob2technomancy, oh, score
18:59hyPiRionyup
19:07bob2technomancy, hm, that appears to not be loaded
19:08bob2ah, sorry
19:08bob2that creates a new profile
19:11technomancyyeah
19:12technomancyyou can't split up one profile
19:12technomancywell
19:12bob2I'm not gonna make user.clj :)
19:12technomancyyou might be able to define :user as a composite of :user/private and :user/public
19:13technomancyso crazy it just might work
19:13technomancyoh, heh
19:13technomancysure, name it something else
19:13hyPiRionit's exactly one in a million chance
19:17bob2cool, with-profile works
19:17bob2thanks!
19:18technomancywith-profile?
19:20bob2just gave up, put the creds in ~/.lein/profiles.d/mything.clj and run it with 'lein with-profile mything ring server-headless'
19:23technomancyoh, sure
19:23technomancyI thought you wanted stuff to be picked up implictly, which is harder
19:25bob2I did, but it's not super important for now
19:25technomancyI'm curious if it works though =)
19:28bob2for documenting an (ns), is it preferable to use a ^:doc annotation, or a string in the ns form?
19:36technomancystring, definitely
19:36noonianwhy is a string prefered?
19:37technomancyless punctuation
19:39weavejesterQuick question: is it a common issue for the cljs compiler to run out of heap space?
19:39amalloyweavejester: i've heard about that happening fairly often with source maps; i don't know if it's still an issue
19:40weavejesteramalloy: Hm, I'm not using a source map.
19:40weavejesterI just wiped my target directory, and suddenly it throws a heap space error.
19:41weavejesterhttps://gist.github.com/weavejester/6af8522f4bc22fc58e06
19:41weavejesterIn case anyone's interested.
19:42weavejesterI'm guessing that failing to compile cljs.core is not a common issue, or else it would have been noticed :)
19:42nooniani'd try lein cljsbuild clean if you wiped target manually and your js is being outputed somewhere else
19:43weavejesterShouldn't make a difference, but trying it now
19:44weavejesterHm, nope: https://gist.github.com/weavejester/e35240240e49c4c54b91
19:45weavejesterMaybe the clojurescript compiler just needs a lot of memory
19:53amalloyweavejester: default maximum heap size is 1GB or 1/4 of all ram, whichever is less (for oracle's jvm)
19:54weavejesteramalloy: Free RAM or total RAM?
19:54amalloytotal
19:55amalloyfree would be quite poor, because of mmapped files and disk buffers/caches
19:55weavejesteramalloy: Hm, I'm not sure that's true, then. I have 4GB of RAM, so in theory "lein cljsbuild" should have up to 1GB to play with.
19:56weavejesteramalloy: But it dies with less than 200M
19:56weavejesteramalloy: Same thing with a project that used, datomic, incidentally.
19:56weavejesteramalloy: I need to manually specify -Xmx1g
19:57amalloywell, all i have is http://docs.oracle.com/javase/7/docs/technotes/guides/vm/gc-ergonomics.html and http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html
19:59weavejesteramalloy: Well, whatever the docs say, the version of Java 1.7 on my Macbook doesn't default to 1G! :)
19:59hiredmanit also depends on which jvm (server/client)
19:59weavejesteramalloy: Maybe Apple's version is changed slightly.
20:00amalloyhiredman: yeah, but basically no modern machines count as client for oracle's jvm
20:00amalloy(as noted in my secnod link)
20:00hiredmanamalloy: on my mac I get different versions when I pass -server or not
20:00amalloyand is that oracle's jvm?
20:00hiredmanoh, fuh, never mind, I mist read the string
20:00weavejesterI believe so...
20:01weavejesterThough I'm not sure a dual-core counts as "two CPUs"
20:01hiredmansomehow a whole word just didn't register
20:01weavejesterWhich is needed for Java to guess that it's -server
20:01AmnesiousFunesHeavy users of tools.namespace: what parts/functions do you use/need the most?
20:01hiredmanweavejester: another thing to keep in mind is if you are using lein to run stuff, lein will pass arguments to the jvm
20:02weavejesterhiredman: Ohh, point.
20:02technomancy-client doesn't exist any more
20:02hiredmanlike -client
20:02technomancyunless you're on a 32-bit sytem
20:02hiredmantechnomancy: well, the version of lein I have installed still passes -client
20:03hiredmanit seems to still get a server jvm, but it still passes -client
20:03technomancyhiredman: sorry, I mean it doesn't exist in the JVM
20:03technomancyit's silently ignored
20:03weavejesterLein seems to default to mx512M
20:04hiredmanweavejester: you may have JVM_OPTS set in your environment
20:06weavejesterhiredman: Nope, that environment var is empty... although, it could also be a system property?
20:06weavejesterYeah, curiously if I set :jvm-opts ["-server"] that doesn't work - it runs out of memory
20:07weavejesterBut :jvm-opts ["-Xmx1g"] does work
20:07weavejesterThe docs would suggest the two are synonymous for a machine with 4GB of RAM.
20:07hiredmanweavejester: jvm-opts in project.clj don't override leins, unless you do ^:replace
20:08weavejesterhiredman: So why does :jvm-opts ["-Xmx1g"] work?
20:08hiredmanweavejester: because -Xmx1g doesn't have to be the first argument
20:08weavejesterhiredman: Ahh
20:11hyPiRionhiredman: they've been overriding lein's default for some time, actually
20:11hyPiRionsee technomancy/leiningen#1230
20:11hyPiRionlazybot, can you please live for like more than one hour? :(
20:12hyPiRionhttps://github.com/technomancy/leiningen/pull/1230
20:13hiredmanhyPiRion: that assumes you are running whatever the latest lein release is
20:14hyPiRionyeah. 2.3.0 or later
20:14hiredmanhyPiRion: since I use lein to pin version dependencies to avoid the treadmill of constantly chasing upgrades, you can imagine my attitude towards chasing lein upgrades
20:15weavejesteramalloy, hiredman: thanks for the suggestions, btw
20:37taw23Newbie to clojure here. Can someone explain why (list a b c) gives an error about symbol resolution but '(a b c) doesn't?
20:38dacctaw23: the first element is evaluated as a function call unless you quote it
20:38ambrosebstaw23: an unquoted symbol tried to resolve itself
20:38daccer, yeah that's more to the point
20:39dacc,(list 'a 'b 'c)
20:39clojurebot(a b c)
20:40amalloy&(let [a 1, b 2, c 3] [(list a b c) '(a b c)])
20:40amalloy,(let [a 1, b 2, c 3] [(list a b c) '(a b c)])
20:40clojurebot[(1 2 3) (a b c)]
20:42taw23Not sure who I was just talking to, but that explanation doesn't make a lot of sense to me
20:42taw23I'm used to a variable needing to be declared or assigned to be used at all
20:43dacctaw23: they aren't variables but symbols. naked ones attempt to resolve to a definition, while quoted ones can be used as regular values
20:44TravisDIs it cider that gives me all these nice quotes in the status bar of emacs?
20:44hyPiRionTravisD: yep
20:44TravisDcool, is there a list of them somewhere?
20:44dacctaw23: not sure using them as values comes up much except when passing to e.g. defn, which is a macro and so doesn't required the quoting
20:45taw23dacc, eh, still thoroughly confused :-S
20:45nooniansymbols in clojure are first class values unlike in something like java
20:45taw23but what is a symbol if not a assigned to a value?
20:45bob2tldr you can just not do (list a b c) or '(a b c) until you understand symbols better
20:45dacctaw23: heh, maybe get a good intro book. i'm working through the o'reilly one and it explains this stuff pretty well
20:46taw23yeah maybe i will
20:46noonianso foo and bar are symbols, and the evaluation rules for symbols in clojure is to try to resolve to something they are bound to
20:46taw23and quoting doesn't attempt to resolve it?
20:46bob2yes
20:46noonianafter (def a 10), a will resolve to 10
20:47noonianbut without defining it first, evaluating the symbol a will throw an error because it couldn't be resolved
20:47taw23yeah, that much makes sense, I guess it's just that single quote notation that I find bizzare
20:47noonianif you quote a symbol it will evaluate to a value of type Symbol
20:47noonian,(type (quote foo))
20:47clojurebotclojure.lang.Symbol
20:47bob2the single quote thing is an almost-universal lisp-ism
20:48hyPiRionbob2: it's still very strange for people unfamiliar with lisps
20:48taw23if a b and c were all properly defined as numbers, '(a b c) and (list a b c) would actually have different contents? The first being the symbols themselves and the latter being their values?
20:48hyPiRiontaw23: yes
20:48noonianyeah, most non-lisp languages don't have an analogous concept
20:49taw23hyPiRion, ah, that makes a bit more sense then
20:49noonianquote quotes an entire form
20:49bob2hyPiRion, right
20:50noonian,(let [c 17] (quote (a b (unquote c) d)))
20:50clojurebot(a b (unquote c) d)
20:50noonian,(let [c 17] (quote (a b ~c d)))
20:50clojurebot(a b (clojure.core/unquote c) d)
20:50noonianhmm, unquote only works in syntax quote?
20:51turbofail`yep
20:52turbofail`which is why you're able to hijack unquote for your own purposes in your own macros
20:53right1i just had the weirdest lighttable bug where it was writing out "(" to a tab that wasnt in focus and everything else on my current tab...
20:53right1i thought my keyboard was broken
20:55turbofail`,((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x)))))
20:55clojurebot((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x)))))
20:56turbofail`an oldie but goodie
20:56AimHereThat's just Lisp's way of saying "Yields the source code when preceded by it's quotation"
20:57taw23right1, I once almost formatted my entire computer because I for the life of me couldn't figure out where a particular bug was coming from. Turns out I had placed a book on the spacebar of an extra keyboard I had plugged in under my desk
20:58AmnesiousFunesright1: Any more info on that? Can you replicate the issue?
20:58right1sorry, i couldn't figure out how to replicate it
20:59AmnesiousFunesIf it happens again, feel free to ping me in #lighttable
20:59right1okay
20:59TimMcRaynes: I figure lazybot timed out.
21:15gfredericks,'~~~~~~~~~~~!
21:15clojurebot(clojure.core/unquote (clojure.core/unquote (clojure.core/unquote (clojure.core/unquote (clojure.core/unquote (clojure.core/unquote (clojure.core/unquote (clojure.core/unquote (clojure.core/unquote (clojure.core/unquote #))))))))))
21:16gfredericks,'~:-D
21:16clojurebot(clojure.core/unquote :-D)
21:19TravisDIs there anything particularly wrong with this definition of .. (which I'll call chain): (defmacro chain [& xs] (reduce (partial list '.) xs)) ?
21:20TravisDIt's not exactly the same as .., since it allows for a single argument
21:21amalloyTravisD: that doesn't look very useful to me - it's not close to .., is it?
21:21noonianwell, it wouldn't work with forms that take arguments right?
21:21amalloy&(reduce (partial list '.) '(a b c d))
21:21amalloy,(reduce (partial list '.) '(a b c d))
21:21clojurebot(. (. (. a b) c) d)
21:21amalloyso i guess that's what noonian is saying
21:22noonian,(reduce (partial list '.) '(a b (c c2 c3) d))
21:22clojurebot(. (. (. a b) (c c2 c3)) d)
21:22TravisDAh
21:22amalloyoh, funny. i guess that works, doesn't it
21:23amalloynoonian: that's correct syntax: (. x (c c2 c3)) is the "explicit" form of (. x c c2 c3)
21:24TravisDif it works, it's by accident. I thought .. was just used to access deeply nested methods
21:24noonianamalloy: huh, i've never seen that syntax
21:24noonianthanks
21:24TravisDparameterless methods
21:24jarjar_p_hello ;-)
21:24quizdrif I have a map and I want to alter its values, or its keys, or both, but still have a map in the end, I'm finding I'm often using mapcat over the map, then hash-map it back together. Is this an acceptable idiom?
21:24jarjar_p_Anyone have any idea why this wouldn't print anything...
21:24jarjar_p_println (clojure.string/join "-" (hash-set (repeatedly 3 #(random-string 3))))
21:25amalloygross, quizdr
21:25nooniani think you want update-in
21:25amalloyinto/for is better than hashmap/mapcat
21:25noonian,(doc update-in)
21:25clojurebot"([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."
21:25amalloynoonian: no, he wants to modify each key or each value
21:26noonianah, yeah then for or reduce
21:26amalloy,(let [m {:x 1, :y 2}] (into {} (for [[k v] m] [k (inc v)])))
21:26clojurebot{:y 3, :x 2}
21:26quizdrthanks guys, i'll try to rearrange my habit.
21:26quizdri like that amalloy
21:28amalloyjarjar_p_: you didn't call println, you just evaluated it for side effects
21:28noonian,(let [m {:x 1, :y 2}] (reduce (fn [res [k v]] (assoc res k (inc v))) {} m))
21:28clojurebot{:x 2, :y 3}
21:28noonianyeah, into is nicer
21:28jarjar_p_amalloy: lol i'm quite a n00b
21:31quizdrhere's the ridiculous way i was doing it:
21:31quizdr,(apply hash-map (mapcat #(vector (first %) (-> % second inc)) {:a 1 :b 2}))
21:31clojurebot{:a 2, :b 3}
21:32quizdrworth noting that it is not actually much more characters long, but obviously not as easy
21:39sandbagsI'm slightly baffled by an error I am getting "IllegalArgumentException No matching ctor found for class mces.core$__GT_pred$fn__4734 clojure.lang.Reflector.invokeConstructor (Reflector.java:163)" all the Google hits refer to Java interop, which I am not doing here.
21:40bob2refheap your code
21:40sandbagsi'm posting it, but i'm interested in what the error is actually saying
21:41sandbagshttps://gist.githubusercontent.com/mmower/d20bdf176a993476109d/raw/2eee256fceefb6a83379b4973e7e12afdec17361/gistfile1.txt
21:42sandbagsi can post more if needed
21:43quizdrsandbags what is pos.x ?
21:43sandbagsquizdr: a symbol
21:44quizdrdo you get the error regardless of the symbol or value you pass there?
21:44quizdri.e. if you just pass true or false
21:44noto2try ~criteria ?
21:45TEttingerin the call to ->pred
21:45TEttingererr map ->pred
21:45sandbagsthe functions being built by ->pred work if called indepdently
21:45quizdrnoto2 the criteria in the macro is not in syntax quotes
21:45sandbagsquizdr: yes, because i am processing that in the macro into a different form
21:46sandbagsTEttinger: not sure what you're asking/suggesting
21:46sandbagsTEttinger: oh, sorry, missed your nick change
21:46TEttingernvm, I really know very little about macros
21:46quizdrsandbags i know i was just pointing that out to noto2
21:46sandbagsquizdr: ah, sry, misread you
21:47sandbags->pred appears to build a valid function that works, hang on a sec
21:49quizdrsandbags if you just enter (search world true) or false do you still get the error?
21:49sandbagsi updated the gist
21:49sandbagsquizdr: i'll try
21:50sandbagsi get a different error
21:50sandbagsthat's probably because you can't map true
21:51quizdrwhat happens if you just enter pos.x at the repl, what value do you get?
21:51sandbagsthat's not going to work
21:51sandbagsthere is no symbol pos.x
21:52TEttingersandbags, uhhhh link again? I think the old link is to a specific revision
21:52quizdroh i gotcha. well that's a tree i won't bark up
21:52sandbagsit's a synthetic syntax to refer to something like {:pos {<ent-id {:x }}
21:52sandbagsTEttinger: https://gist.github.com/mmower/d20bdf176a993476109d
21:53sandbagsit's nearly 3am so possibly i am not at my best, sorry :)
21:54quizdrthe buddha says "He who is wise, drinks green tea. Also, he does not code for a stretch exceeding 17 consecutive hours."
21:54sandbagsi'm still not grokking what the exception is actually saying, possibly because I'm not au fait with how clojure turns functions into classes
21:55sandbagsi started at about 00:30 if that helps :)
21:55quizdrso that's nearly 27 hours then!
21:55sandbagswell if you add it all up over the years it's probably a lot more than that
21:56TEttingersandbags, hm. I wonder if it could be AOT compilation-related
21:58sandbagsi think you just veered above my pay-grade
21:59TEttingerheh. then it probably isn't, if you had any gen-class stuff in your file it could be related to ahead-of-time compiled code not being up-to-date
22:00sandbagsno, there's no Java interop at all in this stuff
22:00TEttingerbut if you aren't doing anything with gen-class then it's a very strange error indeed
22:00TEttingeroh!
22:00TEttingerjust realized something
22:00sandbagsi'm a little puzzled by the change in NS reflected in the prompt
22:00sandbagsnot sure if that's a red-herring
22:01sandbagsdo tell
22:01nooniansandbags: don't you just want to call ->pred and not map it?
22:01TEttingermces.core$__GT_pred$fn__4734 refers to the anonymous fn inside ->pred
22:01sandbagsyes
22:01sandbags->pred is, essentially, a function builder
22:01sandbagsreturning it wrapped in a {:component <fn>}
22:01noonian"c1# (->pred criteria)" instead of "c1# (map ->pred criteria)"
22:02noonianoh nvm
22:02sandbagsnoonian: no, there may be multiple criteria
22:02noonianyeah, i didn't parse the varargs
22:03sandbagsthe syntax i am replacing is (find-entities world [{:pos #(= (:x %) 1} ...])
22:03sandbagsso i'm translating (search world (= pos.x 1) ...) into that
22:04TEttingerhmmm... but your example uses '= instead of =
22:05TEttingeri mean I have no idea how to use macros at this point, so my advice is probably not very helpful, but have you tried evaluating this from a file with a non-"user" ns? like the one it keeps switching to, a file in the mces ns
22:06sandbagsyes
22:06noonianwell for one i'd remove the #'s because you're not sticking any symbols in the generated code
22:08sandbagsnoonian: fair point
22:11sandbagsTEttinger: if you change the example to = it still works
22:12sandbagsTEttinger: ((:pos (->pred '[= pos.x 2])) {:x 2}) => true
22:12TEttingerah ok
22:13dsrx ,'('= =)
22:13clojurebot((quote =) =)
22:13Davidoin clojurescript
22:13Davidwhoops, sorry about that
22:14sandbagsto rule out the downstream code i replaced find-entities with println and i still get the same error
22:14sandbagsbut i'm going to recycle my repl jus tin case
22:15ambrosebs,(doc ==)
22:15clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"
22:16sandbagsyep
22:16dsrx(== 4.0 4)
22:16ambrosebsreturns non-nil implies you can check success with (not (nil? %))..
22:16dsrx,(== 4.0 4)
22:16clojurebottrue
22:17ambrosebsmy brain
22:17sm0ke,(== 4.000000000000000000000000000000000000001 4)
22:17clojurebottrue
22:18ambrosebs,(not (nil? (== 1 2))
22:18clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
22:18ambrosebs,(not (nil? (== 1 2)))
22:18clojurebottrue
22:18ambrosebsbad doc
22:18ambrosebsthat is all
22:22sandbagsi've added a couple more more comments to the gist https://gist.github.com/mmower/d20bdf176a993476109d one showing the find-entities call, the other a disassembly of the anon-func
22:22sandbagsnot sure if anyone can see anything funky in the disassembled code, it's a little beyond me
22:30TEttingerI'm wondering why you're using flatten, actually...
22:30TEttinger~flatten
22:30clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
22:31sandbagsTEttinger: actually i don't need to any more, that's a hold-over from something i was doing before
22:31sandbagsin fact what i want is vec
22:31TEttingerthat's a relief
22:31TEttingeralso, mapv may be what you want
22:31TEttinger,(doc mapv)
22:31clojurebot"([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a vector consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."
22:33sandbagsreplacing flatten with vec gives me an identical call to what i expect, modulo the issue with the anon-function
22:35sandbagshttps://gist.github.com/mmower/a7e5f6d78f1f2537a4d1 <- updated code & example runs
22:36sandbagsi still have no idea what the IllegalAccessError: No matching ctor found for class <blah> is really saying
22:37TEttingerctor is a constructor, but I have no idea why it couldn't make one for an anon fn
22:37sandbagssorry, yes, i understand the concept, but I've no idea what ctor it's looking for or why it wouldn't find one
22:37sandbagsit's been an age since i looked at Java or Java byte-code
22:37amalloyyou're calling eval on a closure
22:38amalloy(let [x 1, f (fn [] x)] (eval f))
22:38amalloyyou really shouldn't eval functions at all ever, but if they aren't closures it happens to work
22:39sandbagssorry where i am calling eval on a closure? I call (eval op) because op will be the symbol '=
22:39sandbagsand i need the function =
22:40amalloysandbags: (mces.core/find-entities world [{:pos #<core$__GT_pred$fn__10298 mces.core$__GT_pred$fn__10298@61dc7878>}]) is clearly not what you want to macroexpand to, because you couldn't possibly write that code yourself: it has a function object in it
22:41sandbagsamalloy: when you say a "function object" are you talking about something other than a function?
22:42amalloysandbags: #(% x) is the notation you would use, in source code, to describe a function. when the compiler *evaluates* that, it gets a function
22:42sandbagsyes
22:42amalloyyou can't embed a function directly into your source code, right? you need to use the notation for it
22:42sandbagsah, damn
22:42sandbagsyes i see it now
22:43sandbagsi mean i see what you're saying
22:43amalloyi can't figure out what you're trying to do in search and in ->pred, but the end result is evaluating something too many times
22:43TEttinger{(keyword component) #(op ((keyword slot) %1) value)})) ; like this?
22:43sandbagsTEttinger: essentially yes, except op won't work
22:44sandbagsif you look at the find-entities call you can see it's translating into
22:45sandbagsokay so i probably want to quote the function in ->pred
22:45amalloyyeah, i think that's probably it
22:45sandbagsalthough that leaves some trailling work to do because it's now qualifying e.g. op
22:46sandbagsbut it's 3:46am and I suspect I am not compos mentis enough to handle this ;-)
22:46sandbagsthanks amalloy
22:46sandbagsand TEttinger
22:46amalloy`#(~(eval op) (~(keyword slot) %1) ~value) probably
22:47TEttingerglad it's working a bit better
22:47sandbagsamalloy: you little beauty
22:47sandbagsyes indeed
22:47sandbags(search world (= pos.x 29) => #{#uuid "5306c8b0-c93d-4284-aa36-2826b62a65ec"}
22:47TEttingerwoo!
22:48sandbagsso a stupid idea i had about 5 hours ago becomes working code :)
22:49sandbagsof course the next step is to rewrite the macro to handle boolean logic, that ought to be fun ... but i think i'll leave that for a clearer head
22:49sandbagsthanks again guys
22:50TEttinger(inc amalloy)
22:50TEttingeroh is lazybot not here?
22:52sandbagsright... to sleep, g'night
22:53amalloyTEttinger: he's been disconnecting a lot recently
22:53amalloyi'll bring him back
22:54TEttinger(inc amalloy)
22:54lazybot⇒ 85
22:54amalloy$mail Raynes if lazybot keeps crashing i'll ask lance to fire you
22:54lazybotMessage saved.
22:54amalloygotta get those priorities straight
22:56Raynesamalloy: lol
22:56Raynes$mail
22:59Raynesamalloy: Lance will get right on the firing me stuff
22:59Raynesamalloy: Thanks for starting him, didn't notice he was down.
22:59amalloytwice today, mate
22:59vladimustis lazybot written in clojure? where's the repo, so I can read the code?
22:59amalloyearlier it was more dramatic: i shouted "lazybot, i summon thee!" right before he /joined
23:00amalloy$google clojure lazybot github
23:00lazybot[Raynes/lazybot · GitHub] https://github.com/Raynes/lazybot
23:01vladimustthanks, I've been looking for some good clojure code to read
23:11vladimustCan you guys recommend me any good clojure repos to read?
23:14amalloyhaha, decided against lazybot already?
23:16vladimustah no, I don't have internet at home
23:16vladimustso I download a whole bunch of clojure repos and resources for the week
23:16vladimustand read them/code at home
23:17vladimustall clojure and no internet makes vladimust a very slow learner
23:18seancorfieldat least you have a REPL and the docs handy locally vladimust :)
23:19vladimustYup, it's great. :)
23:58chareunmute me please