#clojure log - May 07 2013

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:10 bbs_: hi folks. i've been looking through the clojure.java.jdbc docs and i'm hoping someone can help me out with what the binding argument is for "db-transaction". i've only been able to find usage examples with the deprecated "with-connection" and "transaction" functions

0:32 muhoo: is it considered evil to do things in project.clj like slurp passwords out of a different file?

0:33 or is there a more elegant way to deal with stuff like migratus that wants passwords to be in the project.clj?

0:33 cause, like, i'm not committing my passwords to git

0:34 adu: what?

0:34 clojurebot: what is 2d6

0:34 adu: clojurebot: are you a bot?

0:34 clojurebot: Thanks! Can I have chocolate next time

0:34 adu: clojurebot: you're a bot

0:34 clojurebot: thanks; that was delicious. (nom nom nom)

0:35 adu: muhoo: I don't see why not

0:35 muhoo: you can always use .gitignore

0:36 just do something like my-secret-password-file.txt, then echo my-secret-password-file.txt >> .gitignore

0:36 muhoo: uh, i don't think i've explained this well enough. migratus wants its config in project.clj. i do want to commit project.clj into git. i do NOT want to commit my passwords to git. but they need to be in project.clj. so, i'm asking, how can i get that data into the project.clj without actually putting it in the file?

0:37 so the question isn't so much how to keep password *files* out of git, it's how to get secret data into the lein project map without having it in project.clj

0:37 and running slurp inside project.clj seems evil to me.

0:39 jxx: muhoo: a lesser evil. The Right Thing to Do(tm) is to fix Migratus so that it no longer requires such shenanigans.

0:40 muhoo: hmm, thanks. maybe i'll do that. i like environ and could integrate it, but i'm not sure he'd want a dependency on it. i'll ask though. thanks.

0:41 jxx: :)

0:50 Sarudak: omg people!

0:51 Does anyone here use windows? :)

0:55 SegFaultAX: I use windows for gaming, does that count?

1:03 robear: how do you get the index of an element in a vector in clojurescript?

1:57 jxx: robear: how did you get the element in the first place?

2:13 robear: i just created a vector with […]. i tried .indexOf like in clojure but got a no method error.

2:13 i assume that is because .indexOf is based on java?

2:34 andyfingerhut: Has anyone successfully run "lein run" on the same project in parallel on Linux or Mac OS X, e.g. with multiple invocations of "lein run &" in parallel? I tried it, but all of the processes soon enter the Stopped state. That may be perfectly normal and expected, but was curious if there was a way to do it.

4:54 naeg: for those who haven't seen it: http://lispinsummerprojects.org/

5:55 yedi: i need more clojure reading material and planet.clojure.in isn't cutting it =/

5:59 Foxboron: yedi, buy books :)?

5:59 or read source code?

6:00 naeg: hehe, Foxboron the guy being funny about parentheses on reddit ;)

6:00 Foxboron: hahaha

6:01 naeg: not but really, i was sure people would get the joke

6:01 naeg: what a coincidence

6:01 Foxboron: I even said project file!

6:01 naeg: well, it was in r/python, so I wasn't sure at all

6:01 Foxboron: Should give any sane person a hint that u have atleast touched lein

6:02 naeg: even if one touched lein, it doesn't mean he thinks clojure/lisp is good

6:02 Foxboron: I enjoy Clojure

6:02 naeg: don't you hear what you said as a joke quite often seriously from people?

6:03 Foxboron: it is often related too "i dont understand anything"

6:03 then they give up.

6:03 My first reaction also, after my strong hate for curly bracers.

6:04 But why i thought it was funny, is because of the overall lack of curly bracers in Python.

6:04 and i have kinda always had the belig that many python programmers dislike curly bracers, might just be me.

6:04 naeg: I often hear people hating about lisp's syntax (or lack of syntax) but they are using C#/Java or something similar

6:05 Foxboron: that is true.

6:05 naeg: even though I agree readability is important in a programming language (since honestly, while you're programming you read a lot of code and not only your own)

6:05 i think readability is subjective

6:06 that's why I do think Python is a great language and very suitable for beginners. but once you're a bit a better programmer, you can also cope with seemingly "more complex" syntax

6:09 Foxboron: i agree

6:09 the only real problem with LISP is the whole "functional" and "declarative" thing

6:09 jjl`: you don't think significant whitespace confuses the hell out of newbies?

6:09 Foxboron: they don't actaully

6:09 not from my experience

6:10 and i am currently mentoring a study group with beginners

6:10 using python

6:10 naeg: jjl`: well, you should be doing this with c#, java, ... etc. too for readability

6:10 and once they understood spaces are important, it doesn't seem like a problem to me

6:10 jjl`: oh sure. but have you actually read the logic for python indentation?

6:11 i suppose if you tell them 'always indent with 4 spaces' it simplifies things

6:11 but the indent rules are utterly batshit. some kid is going to get a mix of tabs and spaces by accident and get confused

6:11 naeg: that could easily be fixed with a good ide/editor

6:12 also, you don't have to use 4 spaces exactly - all you have to do is be consistent

6:12 Foxboron: jjl`: ummm

6:12 confusing spaces and tabs is a editor failure

6:12 jjl`: oh sure, we're going to teach all the newbies to use emacs

6:12 Foxboron: if you setup the editor, and only touch tab, no problem

6:12 Sublime Text

6:12 Notepad

6:12 all have the feature

6:12 naeg: ever decent IDE has this feature

6:13 + vim :P

6:13 Foxboron: tbh

6:13 any decent editor has the feature

6:13 jjl`: to be fair, i did teach someone to program in emacs. just i handled the bits where keychords were required. and it used my config

6:14 Foxboron: but again

6:14 whitespaces, no problem for beginners

6:14 the beginners i have encountered have problems with different conceps as objects and functions

6:14 not whitespaces and identions

6:14 jjl`: komodo edit might be a good thing. it can be set to show indent lines. that would help newbies

6:14 naeg: Foxboron: about the functional and declarative: I also think that imperative programming is easier to learn for most people - yet another reason i think python is great for beginners

6:15 and later they can decide whether they want to try out other stuff

6:15 clojurebot: Titim gan éirí ort.

6:15 jjl`: naeg: yes, but MIT teaches scheme in one lesson. that's pretty impressive. can't teach much python in one lesson

6:16 naeg: I like komodo edit too, using it for C-like stuff and python, but lately prefering lighttable wherever possible

6:17 jjl`: hmmm...I'm not sure what is easier to learn for a complete newbie - are there any studies out there? would be interesting. but the majority starts with an imperative langauge I guess

6:18 jjl`: naeg: and you wonder why lisp is less popular than many feel it ought to be

6:19 naeg: jjl`: as I said, I'm not sure what's easier for complete beginners. but many people who start out with imperative programming get used to this line of thinking and don't bother trying out other things - which is bad for them and e.g. lisp, but one can't do more than educate those people and show them stuff

6:20 Foxboron: naeg: while imperative is easier to learn

6:20 people argue functinal is better

6:20 * Foxboron points at Raynes

6:21 naeg: I can't really judge here, because I have never teached complete beginners nor read a study/comparison on this

6:23 Foxboron: i know a 15 year old currently learning haskell as his first "real" language

6:23 and he himself claims functional is the best way to go for beginners

6:23 naeg: one person is not enough to see a trend

6:24 Foxboron: Well, Raynes also said that :)

6:24 He actually started Haskell himself.

6:24 So we got 2 people!

6:24 Double the people, double the proof (no, not really)

6:24 naeg: I can see the trend right there :P

6:24 lucian: motivation is what drives learning and at least traditionally imperative languages tend to show pretty results faster

6:24 but i would agree pure functions are much, much easier to understand

6:25 Foxboron: and that, lucian, is a awsome point

6:25 which is why python is recommended for beginners

6:25 naeg: lucian: depends on what results you're after. while a mathematician/physician wants to numbers as his result, e.g. software engineers want to see a gui fast

6:26 wants to see*

6:27 lucian: naeg: that's what i mean, the path of least resistance to results that motivate learning is almost always taken

6:28 naeg: agree. even though we both would agree that the path os least resistance is not the best path in form of productivity/simplicity/... (I guess?)

6:38 djcoin: Do you think it would be possible to mark some clojure code as being "pure" and then run/benefits from some optimization on some part of the code ? Is there any such project ?

6:53 mmitchell: technomancy: I have a leiningen plugin that uses the "hooks" feature, along with robert.hooke/add-hook. My functions is executed, but not in the scope of the project. Is this possible to do? eval-in-project doesn't seem to be working in this context.

6:53 jjl`: djcoin: even haskell doesn't do terribly much in that way. the benefit of pure code is that you can cache results, but haskell still relies on manually using memoize

6:54 djcoin: jjl`: you could do streamfusion or stuff like this

6:54 (i'm not really aware of what might be benefits - but i may have some!=

6:54 )

6:55 jjl`: well it's a hard problem to know when to cache results

6:55 perhaps best solved by a programmer than a language implementer

6:56 especially considering the memory usage of the JVM already

6:56 djcoin: stream fusion is not about caching results, its about eliminating intermediate datastructure creation etc.

6:56 s/its/it's

6:57 jjl`: sounds like a fairly hard problem

6:57 especially with richer datatypes

6:58 djcoin: you could check for it

6:58 anyway, I'm just being curious :)

7:35 clgv: does clojure always convert the result of an addition of a double and a BigDecimal to double?

7:37 seems like it: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L555

7:48 andyfingerhut: I believe it does, from the implementation. Probably for speed reasons.

7:48 If you want BigDecimal, make sure all operands are BigDecimal, or at least not float or double.

8:17 clgv: andyfingerhut: yes, just found `bigdec` ;)

9:14 gdev: ,(reverse "racecar")

9:14 clojurebot: (\r \a \c \e \c ...)

9:14 gdev: ,(seq "racecar")

9:14 clojurebot: (\r \a \c \e \c ...)

9:19 noidi: gdev, wtf

9:20 :D

9:20 * noidi is an idiot

9:21 noidi: I can't believe it took me a while to see how that's possible :D

9:23 tomoj: there's a big case statement in reverse with a bunch of palindromes

9:23 Ember-: lol

9:23 I too looked for a while like what's happening until I got it :)

9:30 gdev: ,(doc reverse)

9:30 clojurebot: "([coll]); Returns a seq of the items in coll in reverse order. Not lazy."

9:31 gdev: www.4clojure.com/problem/27

9:37 ,(tree-seq {:a [1] :b [2 3] :c [4 5 6]})

9:37 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$tree-seq>

9:37 gdev: ,(#(tree-seq % seq %2) {:a [1] :b [2 3] :c [4 5 6]})

9:37 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval103$fn>

9:38 gdev: ,(#(tree-seq % seq %2) ["a" ["b"] "c"])

9:38 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval141$fn>

9:39 gdev: okay, gonna try to fix light table instead of using irc as a repl

9:40 libudev.so.0 Y U no found?

9:40 Bronsa: gdev: quick fix: libudev.so.0 -> /usr/lib/libudev.so

9:41 pyr: hi

9:41 anybody using core.match in anger ?

9:41 I have a weird condition of jar compilation failing but lein run working

9:42 TimMc: Last I used it there were some non-deterministic bugs, but that was liek a year ago.

9:42 pyr: (even after a lein clean)

9:42 Exception in thread "main" java.lang.IllegalArgumentException: No method in multimethod 'to-source' for dispatch value: class clojure.core.match.WildcardPattern

9:43 that namespace is aot'ed since it contains a -main

9:43 pjstadig: pyr: AOT is not supported

9:43 pyr: that settles it then

9:44 so I just need to hide that function in a namespace that's not aot'd and call it from the main namespace then ?

9:44 pjstadig: you might be able to set a whitelist or something so that core.match isn't getting AOT'ed, but your namespace is

9:44 otherwise...you've been CLJ-322'ed

9:44 pyr: good to know it's known :) sorry about not figuring it out by myself

9:49 tomoj: is (conde [g1 g2]) semantically equivalent but operationally inequivalent to (conde [g2 g1]) ?

9:51 gdev: Bronsa:) thanks, but it looks like I don't have /usr/lib/libudev.so either

9:51 Bronsa: oh

9:51 gdev: ubuntu 13 for the win

9:52 Bronsa: well, apt-get install libudev-dev then

9:52 IamDrowsy: gdev: /lib/x86_64-linux-gnu/libudev.so.1

9:52 Bronsa: or that

9:55 ppppaul: ,(doc match)

9:55 clojurebot: It's greek to me.

9:55 ppppaul: what is core.match pyr?

9:56 Bronsa: https://github.com/clojure/core.match

9:56 jjttjj`: what do people usually do these days to avoid launching to jvm insances for a ring server and a repl? I'm using emacs/clojure-mode/nrepl

9:56 *two

9:56 nDuff: jjttjj`: AFAIK, most people don't try to avoid that.

9:57 gdev: Bronsa:) that worked when I linked it to /usr/lib/libudev.so.0 thanks

9:57 ppppaul: jjttjj`, i get more memory

9:57 i also use drip

9:57 gdev: (inc Bronsa)

9:57 lazybot: ⇒ 4

9:57 jjttjj`: nDuff: ok cool. I feel like I've seen it before in a project but forget where, wasn't sure if I was missing out on something cool.

9:57 weavejester: jjttjj`: The latest lein-ring allows you to run nrepl alongside it.

9:58 ppppaul: flatland drip

9:58 weavejester: jjttjj`: :ring {:nrepl {:start? true}}

9:58 ppppaul: neat

9:58 jjttjj`: weavejester: awesome

9:59 ppppaul: is there a reason for using core.match over multimethods?

10:00 though, that is probably the smallest fizzbuzz i've seen

10:01 weavejester: ppppaul: core.match allows for more complex matching off the bat, and is more intelligent about optimising IIRC

10:02 Multimethods just apply a function and dispatch off it

10:02 core.match does some interesting things around figuring out the most efficient way to match a bunch of destructured matches

10:03 However, AFAIK core.match is all precompiled - you can't add stuff on the fly.

10:08 pyr: pppaul: a pattern matcher to avoid lots of cond and ifs to make things short

10:08 pppaul: ok

10:08 i'm actually interested init

10:08 what issues are you having with it?

10:08 pyr: pppaul: the advantage of match vs a calling a multimethod with (juxt field1 field2) on a map is that it can handle wildcards

10:09 pppaul: hmmm

10:09 pyr: pppaul: my issue is with aot namespaces and core.match

10:09 pppaul: what does core.match need AOT?

10:10 why*

10:10 pyr: nope, it breaks on AOT'd namespaces apparently so my stuff works fine with lein run / lein repl, but does not compile to a jar

10:10 plumbing details, i'm sure it'll figure itself out

10:11 pppaul: hmmmmm'

10:11 so it breaks when you want to turn your NS into a class?

10:12 i'm not experiences with AOT

10:13 i'm also apparently not experienced with english

10:15 pyr: pppaul: it breaks if it's require'd from your main namespace

10:15 pppaul: main

10:15 like .core?

10:15 so, that sounds extremely easy to get around

10:15 my main ns's are usualy pretty empty

10:28 pjstadig: not just if it is required, but if it is transitively required

10:28 which usually boils down to: if you use your code at all in your main ns, then you're boned

10:28 more or less

10:30 pppaul: oh

10:30 tomoj: the problem is that AOT on core.match produces broken class files?

10:30 or what

10:31 pppaul: main as defined in project.clj?

10:35 pyr: tomoj: the problem is that if core.match is a dependency on an AOT'd namespace, jars cannot be produced

10:35 tomoj: at least if leiningen is used to compile, haven't tried anything else

10:36 pjstadig: yeah, i had to play dirty tricks to require the namespace from a constructed symbol

10:36 tomoj: huh, because core.match throws an exception during AOT?

10:36 pyr: tomoj: yes

10:36 tomoj: ah :(

10:37 pjstadig: pyr: right, you would have to require your core.match dependent code at runtime

10:37 tomoj: maybe one of the next few clojure versions will have a better story for AOT..

10:37 pyr: which is what i'm doing now

10:47 pppaul: so, if you make a war file are you srewed?

10:47 screwed?

10:49 pyr: pppaul: unless you start playing tricks with constructing the symbol to require, yes.

11:07 gdev: there are so many people in the datomic channel yet it is so quiet. so maybe someone in here can help me out. I'm trying to explain the difference between a programmable query language and sql strings

11:09 since my audience doesn't know what datalog is I'm trying to use the analogy of a bank robbery vs a ransom note

11:10 tomoj: hmm

11:11 imagine if inheritance in java was based on some string templating mechanism

11:11 where you're working with the code of the other classes

11:12 gdev: tomoj:) I like it, that's a way better analogy

11:12 tomoj: then there's another level where working with java classes that represent queries seems nuts when you can just use data structures

11:13 though, hmm

11:14 gdev: now I'm trying to think of a query that would get an inherited method from a base class

11:14 tomoj: I haven't done a whole lot of work with sql, do people successfully get through whole projects without dealing with string query parts?

11:16 gdev: tomoj:) I've yet to see anyone do any database interaction without tweaking strings

11:17 we have people who spend all their time writing mountains of sql strings for other developers to use

11:17 tomoj: hmm

11:17 how do you compose them?

11:19 I guess the other devs will just copy fragments and use string concatenation to compose stuff?

11:19 gdev: no, if you need something different you put in another request for a different sql string

11:20 tomoj: and every sql string is self-contained? or the sql people are defining helper functions in the background?

11:21 gdev: to query the database: step 1) email raj with what you need step 2) paste reply into your sql.properties file step 3) ??? step 4) profit

11:21 since some of the relationships are messy, it's hard to tell what will happen if you tried to compose queries based on what you have

11:22 and testing your own queries? f'getabout it

11:25 not all departments are like that, but this is the enterprise, people have job security when they're the only ones that can understand the database...makes the "over there" problem even bigger

11:27 tomoj: I'm guessing your problems are more political than practical? :(

11:33 gdev: I'd say it's equally both; it's impractical to have your database tied to politics

11:36 tomoj: yeah..

11:42 gdev: even on the ones that aren't like that, the average time for composing an sql statement is pretty large

12:18 silasdavis: will enumerating over (concat a [b c d]) be faster or slower than over (conj a b c d)?

12:18 where I am including the time taken to perform the concatenation in each case

12:18 i.e. I'm joining two lists

12:19 bbloom: silasdavis: ##(doc time)

12:19 lazybot: ⇒ "Macro ([expr]); Evaluates expr and prints the time it took. Returns the value of expr."

12:19 silasdavis: would the answer change if I was using different collection types

12:19 bbloom: give it a try

12:19 besure to dotimes while you're at it

12:20 technomancy: jjttjj: FWIW I highly recommend using a single JVM for ring and nrepl

12:21 if you write a -main defn that uses ring-jetty-adapter you can treat your ring server as just another function instead of some magic task you have to invoke from the CLI

12:22 weavejester: technomancy: Just because you invoke a function from a command line doesn't make it inherently magical.

12:22 jjttjj: technomancy: cool that's sort of what I was thinking originally, that that might be useful, I'll play around with it in a bit

12:23 technomancy: weavejester: what I mean is you can't use M-. to see the source

12:23 it's not nearly as transparent

12:24 weavejester: technomancy: You can run lein-ring with nrepl attached, which amounts to the same thing without tying your web application to a particular adapter.

12:25 technomancy: I've never seen an actual case where tying to a specific adapter is a bad thing

12:25 except netty, which doesn't work with ring anyway

12:26 weavejester: There's a couple of ring-netty-adapter projects around

12:26 technomancy: right; I mean the use cases that make netty interesting don't work with ring

12:26 (not saying that's a bad thing)

12:27 weavejester: I dislike the idea in principle of typing an abstract web application to a particular web server when it's not necessary

12:27 technomancy: I know. =)

12:27 I just have never seen a practical downside.

12:27 it's only a 5-line function anyway

12:27 weavejester: I mean, you have a nice abstraction, and then spoil it by tying it to a specific server

12:28 Well, if you're deploying as a war file or something else like that, you don't necessarily want a -main method

12:28 I guess you could argue that even though it's debug code in production, it does no harm...

12:28 But it feels wrong.

12:29 technomancy: it's five extra lines; I'll trade "feels wrong" for the extra transparency

12:29 * technomancy has come to value obviousness over nearly everything else

12:31 gtrak: you could always just pull out the server bit into a separate project later, that's the benefit of working to an abstraction.

12:32 silasdavis: bbloom, that's a rather sensible suggestion

12:32 tomoj: :profiles {:dev {:main com.example.dev-server}} ?

12:32 silasdavis: (defn test-join [m] (time (dotimes [n 10000] (let [a (rand-list 1000 '[]) b (rand-list 100 '[])] (m a b)))))

12:32 technomancy: gtrak: it's hard to argue that five lines makes that more difficult

12:32 silasdavis: (test-join into): 4037 msecs

12:32 (test-join concat): 4032

12:33 gtrak: technomancy: yea, I actually agree with you :-), lein-ring is harder to reason about than loading up jetty myself

12:33 silasdavis: about the same it would seem

12:33 gtrak: lots of costs involved, would I rather fork the project to do something special or change some lines?

12:33 weavejester: It amounts to the same thing as using the CLI.

12:33 technomancy: oh, gotcha

12:34 noncom: hi i have a vector of namespaces. all of them are supposedto have a function, say "update". how do I properly map through them to execute that one function, while I am in another namespace?

12:34 weavejester: And although it doesn't save too many lines of code, it preserves the abstraction.

12:35 hyPiRion: It's not about saving lines in the short term.

12:35 weavejester: Though granted I don't know of a practical downside to tying the adapter to the handler :)

12:35 gtrak: I sacrifice some control over my classpaths to use lein-ring, that gets to be a big deal when it's not a one-off self-contained thing

12:35 technomancy: the abstraction is still there if you have a -main

12:35 weavejester: noncom: What do you mean by "map through them"?

12:36 technomancy: (def app ...) is still a separate var from (defn -main ...)

12:36 gtrak: I think preserving the abstraction is a nice thing, but it doesn't have a ton of force.

12:36 noncom: weavejester: like (doall (map #(%/update) @namespaces)), where namespaces is an atom vector

12:37 weavejester: technomancy: Yeah, but you're still tying a particular web server to your project.

12:37 noncom: but%/update doesnotwork

12:37 binding [*ns* %] either

12:37 weavejester: technomancy: I guess I only have an idiological argument.

12:37 gtrak: you're never 'tying' it.. you're only slightly raising the cost of decoupling it later.

12:37 bbloom: silasdavis: i'm a sensible guy

12:38 hiredman: weavejester: technomancy's is ideological as well, don't let him make you think otherwise

12:38 hyPiRion: hiredman: oh no, you're wrong

12:38 weavejester: noncom: Hmmm… iterating through namespaces like that doesn't seem like a great idea… but you can use ns-resolve I think to resolve a var from a symbol.

12:38 hyPiRion: he's quixotic

12:39 technomancy: defn the ultimate

12:39 ^ my ideology =)

12:42 silasdavis: can I write multiple bodies for a function so that some of the bodies get called when one of the argument takes a specific value?

12:42 noidi: silasdavis, what you want is pattern matching: https://github.com/clojure/core.match

12:42 silasdavis: [n l s] (body...) [:first l s] (other body...)

12:43 noidi, ah yes it is... is there a way to do it with destructuring?

12:44 noidi: no, destructuring just takes things apart

12:44 noncom: weavejester: i tried that, not calling a function seems to compile, however,I cannot add my namespaces to a vector... aren't namespaces just variables in clojure? are them special?

12:45 robear: is there an equivalent to .indexOf for vectors in clojurescript?

12:45 noncom: weavejester: sry, i meant "now calling a function"

12:45 weavejester: noncom: No, they're namesspaces, not vars. However, you can construct a var from a symbol.

12:45 hyPiRion: namespaces are data

12:45 noncom: weavejester: with quote?

12:46 hyPiRion: ,(var +)

12:46 clojurebot: #'clojure.core/+

12:46 noncom: hyPiRion: I see...

12:47 weavejester: ,(var-get (find-var (symbol "clojure.core" "inc")))

12:47 clojurebot: #<core$inc clojure.core$inc@4082d>

12:47 noncom: oh..

12:47 weavejester: But using namespaces in the way you're using them might indicate you're approaching a problem in the wrong way.

12:48 technomancy: weavejester: when did :nrepl get added to lein-ring? that's a cool feature.

12:48 weavejester: technomancy: One of my colleagues suggested it and submitted a patch. I think I merged it in a week or two ago.

12:48 noncom: weavejester: possibly. maybe you could give me some insight on how to do it more right, if I tell you what I am after? here is my story...

12:49 weavejester: noncom: Go ahead

12:50 noncom: I want to have a multiuser environment where everyone can connect to the running program with a REPL and do their stuff in their own personal namespace. So each user has a namespace. And when a user is registered in the system and is active, his namespace is linked to the main executioner thread

12:51 and say, namespace name is build of user login...

12:51 the main point is to have personal parts of the program which can be easily linked oк unlinked from the main execution

12:52 and each such namespace must have "Start" "update" and "stop" functions

12:52 and thats the only contract for them

12:52 .

12:53 weavejester: Hm...

12:53 namespaces won't sandbox users, so presumably everyone on the system is trustworthy?

12:54 noncom: Also, why do all the users need to be in the same process?

12:56 noncom: weavejester: yes, everyone is trustworthy. in the worst case i can make them connect with a special terminal which will ensure security by disallowing references to anywhere but the allowed functions. And them must be in the same process because they must have the ability to do something in the common "world" which is running in that mainprocess. metaphorically, they can create, say, animals and their animals play together

12:57 and that needs to be fast.

12:58 weavejester: noncom: Ah, okay, so why not allow each user to register a function themselves? i.e. instead of creating a function that has to be called update, they have some code like (add-to-world my-update-function)

12:59 gtrak: sounds like you need a map of user-id to implementing object, not necessarily a namespace. it's probably fast enough to look up this way for your needs.

13:00 implementing object can be another map, a record, a reify instance, etc..

13:01 noncom: weavejester: hmmm! looks like a fair and simple solution! how did not I think... I could just force them to execute a couple of "registration" fns at the beginning of their activity... oh.. still trying to get my mind decomplexified of OOP stuff! :D I will try that solution today and see how it wox!

13:01 gtrak: yeah, seems to be I was over-complexifying things :)

13:02 weavejester: noncom: Good luck :)

13:02 hyPiRion: IRC, saving souls since 1988.

13:02 gtrak: key-values are convenient ways to think about associations :-)

13:02 noncom: :D

13:08 robear: is there a way to get the index of an element in a vector in clojurescript?

13:11 gtrak: keep-indexed?

13:12 simply supply a pred that returns the index if it matches, nil otherwise, call 'first' on the result.

13:13 SegFaultAX: robear: You just want the index of a single element?

13:13 robear: Probably just use indexOf

13:14 robear: .indexOf it gives me a no method error. tried it on himera as well and same thing. seems to work on a string but not a vector.

13:14 silasdavis: is there a built in function that does (fn [f] (fn [&xs] (apply f (reverse xs))))?

13:18 wink: silasdavis: I don't fully understand what you want to do :P

13:18 SegFaultAX: robear: Weird, Arrays in js definitely have an indexOf method. Unfortunately I'm not really familiar with cljs.

13:18 emanon_: hello there

13:18 wink: silasdavis: like.. why xs without x :)

13:18 hyPiRion: SegFaultAX: vector != array

13:18 SegFaultAX: wink: They want to apply the arguments right to left.

13:18 hyPiRion: oh, like flip

13:18 SegFaultAX: hyPiRion: I made the assumption that the underlying datatype is still an array.

13:19 emanon_: I have a kinda a weird question, by I'm curious

13:19 silasdavis: wink, get a version of function that takes it's argument in the reverse order

13:19 SegFaultAX: hyPiRion: Yes.

13:19 hyPiRion: silasdavis: no, there isn't afaik

13:20 emanon_: I am ruby developer and I've just started to learn clojure, but I have no Idea how to get started to write code, means I didn't find any best practices, code conventions etc

13:21 SegFaultAX: emanon_: I strongly suggest picking up a book on Clojure. Clojure Programming and Joy of Clojure are my personal recommendations.

13:21 tomoj: ((flipper [x y] [y x]) f)

13:21 (flip [x y] [y x] f) ?

13:22 er, (flip f [x y] [y x])

13:22 SegFaultAX: emanon_: As for code conventions, the easiest way to learn is to read a lot of idiomatic code and emulate their style.

13:22 emanon_: SegFaultAX: Thanks!

13:22 Foxboron: emanon_: i recommend 4clojure and clojure programming. you should wait with Joy of Clojure until the new version is out

13:22 emanon_: Is there any good open source projects for newcomers?

13:22 SegFaultAX: emanon_: Lots.

13:22 emanon_: To dive in best practices

13:23 SegFaultAX: emanon_: I suggest looking at stuff written by weavejester, cemerick, Raynes, amalloy, etc.

13:23 wink: silasdavis: SegFaultAX: yeah was unsure about repeated apply vs apply f to reveresed args.

13:23 emanon_: thanks!

13:24 tomoj: (= [2 4] (reduce-kv (flip conj [ret v] [ret k v]) [] {1 2 3 4})) ?

13:24 wink: silasdavis: that said, I find yours pretty basic. would be a little weird to have a lang construct

13:25 slagyr: In ClojureScrupt, how do I extend IDeref without getting a warninig?

13:25 cljs.user=> (deftype Foo [] cljs.core.IDeref (-deref [this] "foo"))

13:25 WARNING: Symbol cljs.core.IDeref is not a protocol at line 1

13:27 dnolen: slagyr: cljs.core/IDeref is what you want

13:28 SegFaultAX: wink: What do you mean by a lang construct? Flip is a simple function. flip :: (a -> b -> c) -> b -> a -> c

13:28 wink: (Or in other words, a function that takes a function of two arguments and returns a function expecting those arguments in reverse order)

13:29 Except in Clojure we can handle any arity we like. :)

13:29 silasdavis: wink, I think it's quite natural if you're dealing with 2 argument functions or functions that take a homogenous list of arguments like concat

13:30 I wanted to write (update-in foo [:some :stuff] (flip into) bar)

13:30 rather than (update-in foo [:some :stuff] (fn [a b] (into b a)) bar)

13:30 wink: SegFaultAX: I meant: it's composition and you can argue if reversed or normal is the default.

13:31 silasdavis: feels cleaner

13:31 wink: I see

13:32 I think I'm jsut more in the "if I can write it in 80 chars it should not be in the language" camp

13:32 slagyr: dnolan: Thanks! That did it

13:32 wink: even if it means reinventing wheels

13:32 SegFaultAX: wink: What wheel is being reinvented?

13:33 wink: SegFaultAX: said reverese composition function.

13:33 SegFaultAX: wink: It isn't really reverse composition.

13:33 We aren't composing functions here, we're applying them.

13:33 wink: f(g(x)) is composition to me

13:34 emanon_: Maybe it sounds weird, sorry for my object-oriented brain damage, but is there design patterns in functional languages?

13:34 hiredman: f·g would be composition

13:35 wink: hiredman: yes of course, but isn't it this in this case. it's not partial

13:35 SegFaultAX: emanon_: There are patterns in every language. Many of the patterns you know from OOP are probably not as common, don't exist at all, or simply fade into the background.

13:35 wink: s,case,case?,

13:35 my chicken korma doesn

13:35 ww

13:35 technomancy: emanon_: middleware is a common FP "pattern" in clojure

13:36 emanon_: technomancy: thanks, will try google it

13:36 xeqi: which is basically the decorator pattern applied to functions

13:36 hiredman: partial application isn't composing two functions together

13:36 SegFaultAX: xeqi: Isn't the decorator pattern usually about functions?

13:37 emanon_: Strategy could be implemented in FP I guess

13:37 xeqi: SegFaultAX: Isn't it about using composition to add new behavior to an object?

13:38 SegFaultAX: emanon_: If you're interested in such things, you should check out Clojure's multimethod support.

13:38 hiredman: .win 15

13:38 SegFaultAX: xeqi: What the decorator pattern?

13:38 xeqi: yes

13:38 ooh, looks like that the first line in wikipedia

13:38 SegFaultAX: xeqi: Uh, no?

13:39 xeqi: Maybe you're confused with the mixin pattern or something.

13:39 wink: hiredman: maybe I'm thinking too mathematically. but even the wikipedia page tells me g .f := g(f(x))

13:39 SegFaultAX: You don't usually decorate classes, though.

13:39 wink: hiredman: and of course it

13:39 SegFaultAX: wink: Yes, your notion of compositon is correct. flip is not that.

13:39 wink: hiredman: and of course it's not partial at the moment of application

13:39 xeqi: I haven't mentioned classes, just objects

13:39 hiredman: wink: it isn't, obviously, the left hand side has no x

13:40 wink: SegFaultAX: aaah, sorry, I misread

13:40 SegFaultAX: xeqi: Objects then.

13:40 wink: Flip is simply reverse application. It has nothing to do with composing functions.

13:40 hiredman: (f·g)(x) := g(f(x))

13:41 wink: hiredman: g . f: A -> C, x -> (g . f)(x) := g(f(x)), yea

13:41 SegFaultAX: hiredman: I think you got that backwards.

13:41 hiredman: (f . g)(x) := f(g(x))

13:41 silasdavis: yeah this is nothing to do with composition

13:42 SegFaultAX, both convention do actually get used

13:42 confusingly enough

13:42 wink: SegFaultAX: what I meant, i misread your 2nd or 3rd line, with reverse on args. I had indeed read it as g . f => f . g origfinally

13:42 SegFaultAX: silasdavis: Look closer.

13:42 hiredman: SegFaultAX: sure

13:42 SegFaultAX: silasdavis: He flipped the right and left side.

13:42 I've never seen a notation where the right function was applied last.

13:43 hiredman: yeah, I just reused my previous composition for the left side, which happened to use the same letters but in the wrong order

13:44 SegFaultAX: wink: There is absolutely no requirement that f and g be commutative under compositon.

13:44 And in fact it is often the case that they aren't.

13:44 wink: SegFaultAX: yes of course, I was just not paying attention properly, sorry :P

13:44 40min bike ride, delivery guy inbetween

13:44 * wink shuts up

13:45 hiredman: anyway, my point is f(g(x)) is function application to an argument, not composition

13:46 SegFaultAX: hiredman: Yes, but so is (f . g)(x)

13:46 Note the (x) part.

13:46 hiredman: SegFaultAX: exactly

13:47 SegFaultAX: hiredman: Oh, I didn't know that's what you were trying to say. We agree, than!

13:47 Then, even.

13:49 mads-: I'm new to Clojure. I want to make a HTTP connection, but all my google searches are projects on github or something. Isn't there HTTP connections in the language or its standard libraries?

13:50 SegFaultAX: mads-: There is clj-http

13:50 gtrak: mads-: java's got it built in, the next step up in abstraction apache commons httpclient, a clojure interface for that is clj-http

13:51 mads-: Thanks

13:51 SegFaultAX: mads-: There is nothing in the clojure std lib if that's what you're asking. You could of course just use the java libraries.

13:51 technomancy: mads-: clojure is a very small language

13:51 you can do (slurp (java.net.URI. "http://example.com")) for trivial things though

13:51 SegFaultAX: ,(count (keys (ns-publics 'clojure.core)))

13:51 clojurebot: 593

13:51 SegFaultAX: *cough* small *cough*

13:52 hyPiRion: SegFaultAX: what do you compare with? Java, Haskell or Assembly?

13:52 SegFaultAX: hyPiRion: I was mostly kidding. :)

13:52 Also, CL.

13:53 technomancy: "bigger than scheme; smaller than CL"

13:53 hyPiRion: ah

13:53 technomancy: ^ every language

13:53 SegFaultAX: technomancy: Exactly, haha.

13:53 hyPiRion: CL is such a nice thing

13:53 silasdavis: Raynes, if you happen to be around, I was going to suggest that these functions be added to laser: https://www.refheap.com/paste/14258

13:54 SegFaultAX: silasdavis: PR!

13:54 silasdavis: pr?

13:54 brainproxy: dnolen: is it important that in a browser the cljs part of { cljs: ..., mori: ... } is globally accessible, i.e. as window.cljs?

13:54 clojurebot: forget forget primetime is <lowlycoder> i'm not convined clojure is ready for

13:54 SegFaultAX: silasdavis: If you want to contribute, open a pull request.

13:54 brainproxy: dnolen: or is it fine if only mori ends up in the global scope?

13:54 silasdavis: ah I was just about to ask if I should do that

13:54 will do

13:55 can you get leiningen to use a git repo as a dependency?

13:55 emanon_: Found out SICP in Clojure but it looks dropped

13:55 technomancy: silasdavis: no

13:56 dnolen: brainproxy: fine if only mori ends up in the global scope.

13:57 hyPiRion: the most amazing part of CL is least-negative-normalized-double-float

13:57 bbloom: dnolen: surely _ is an available identifier ;-)

13:57 hyPiRion: Along with other long names.

13:57 dnolen: bbloom: heh, I imagine people can do that if they like, I don't really want to follow the noConflict pattern that entails

13:58 bbloom: dnolen: i was kidding. please don't do that :-P

13:58 SegFaultAX: You could just keep adding _ until you find an unbound name.

13:58 brainproxy: dnolen: cool, thanks; almost done with the combo-environments wrapper for mori

13:58 SegFaultAX: It'll be fun! Depending on load order you could be _ or __ or ___

13:58 dnolen: brainproxy: nice!

13:59 bbloom: SegFaultAX: you laugh, but i've seen a piece of hackathon code that depended on two different versions of underscore & totally just made __

13:59 SegFaultAX: bbloom: Haha, oh man I'm crylaughing.

14:00 bbloom: SegFaultAX: i walked out of the room :-P

14:00 SegFaultAX: That's amazing.

14:00 TimMc: I actually like noConflict.

14:01 SegFaultAX: Doesn't it just unbind jQuery from its shortname?

14:02 I wish Javascript was more flexible with its identifiers. I would totally start writing libraries that use common Haskell operators in confusing ways. <=< >=> >>= etc.

14:05 tomoj: why does this counto relation diverge? (the last example at the bottom) https://www.refheap.com/paste/db3f8d59bc1791b03164ea0a5

14:11 ro_st: Raynes: sooo. switching from noir to lib-noir + compojure. buh-bye defpage and server/add-middleware, right?

14:12 Raynes: defpage and add-middleware were horrible, horrible creations.

14:12 Especially add-middleware.

14:12 lynaghk: Raynes: the more Clojure I write, the more I hate anything that starts with "def".

14:13 ro_st: hey lynaghk :-)

14:15 lynaghk: ro_st: what's up?

14:16 ro_st: contemplating a rather large noir -> lib-noir refactor. the technical debt is strong with this one.

14:21 Raynes: can i bring in lib-noir 0.5.2 and noir 1.3.0 at the same time and have things stay sane?

14:22 i've already removed uses of noir.request/ring-request

14:22 Raynes: Possibly. I'm not sure.

14:24 ro_st: seems like a good time to put clojure.tools.namespace/refresh to use

14:25 enjoying your new hometown, Raynes?

14:25 Raynes: Today? Not really. Occasionally.

14:28 SegFaultAX: Raynes: I hear the weather has been pretty shitty down there, actually.

14:28 Rainy and stuff.

14:28 Raynes: SegFaultAX: Well, it rained night before last.

14:28 I'm perfectly fine with rain. The weather is positively boring otherwise.

14:29 SegFaultAX: I love when it's cold and rainy.

14:29 Raynes: I could do without cold.

14:29 SegFaultAX: SF has been a friggin oven lately.

14:30 Raynes: I can recall one day (last week in fact) that it was really warm here.

14:30 SegFaultAX: I work across the street from the Embarcadero and its gotten up into the 80's multiple times (which is rare for SF in general)

14:30 technomancy: I really liked the rain when I was in LA because it meant things would be less brown for a while.

14:31 SegFaultAX: technomancy: Y u no like wall of smog?

14:31 Raynes: I haven't seen anything brown except for a pile of manshit on the sidewalk in Santa Monica yesterday.

14:32 SegFaultAX: Raynes: It's really obvious when you're coming over the grapevine.

14:32 nDuff: Raynes: If you'd rather do without cold, come to Austin! I'm getting ready to head in the other direction and move to Chicago.

14:33 SegFaultAX: nDuff: Ugh.

14:33 ro_st: has anyone solved automatically removing unused :require / :use defintions yet?

14:33 nDuff: SegFaultAX: With respect to which?

14:33 SegFaultAX: nDuff: Austin. It's better than Houston though.

14:33 * nDuff quite likes Austin -- unlike the rest of Texas -- but for the weather and the transit. That's a big, big "but for", though.

14:34 SegFaultAX: Haha, yes it is.

14:34 hammer_: what's a but for

14:34 SegFaultAX: For pooping, silly.

14:34 hammer_: (inc SegFaultAX)

14:34 lazybot: ⇒ 2

14:34 technomancy: ro_st: slamhound is the only attempt at that afaik

14:34 SegFaultAX: :D

14:34 technomancy: it works to various degrees of success

14:35 SegFaultAX: nDuff: There is a pretty sick tech bubble in Austin growing.

14:35 ro_st: we use :require [n.s :as alias] consistently

14:35 no :use or :refer

14:35 how will slamhound deal with that?

14:36 dnolen: tomoj: that's not going to work. the second branch of reduceo will never terminate

14:36 ro_st: hey dnolen!

14:36 dnolen: sorry of reduceo*

14:36 ro_st: hullo

14:37 ro_st: happy to see you mucking about in cljs land again :-)

14:37 dnolen: tomoj: you'll only getting an answer from the first branch

14:37 ro_st: hehe yes, will probably taking a break from that to focus on core.match for a while

14:37 ro_st: we're on 1803 / 1.5.1 with no issues

14:37 nDuff: SegFaultAX: Yup -- been turning down a pretty ridiculous number of recruiters in the last several months.

14:38 ro_st: just had to tidy up some sloppy code that tried to use map access on strings, that's it

14:38 technomancy: ro_st: as long as you don't use resolve/eval or fully-qualified vars you should be good

14:38 dnolen: ro_st: sweet, there's a bad bug around empty arrays, will ping stuartsierra to push out another fix soon as he's around.

14:38 technomancy: oh, or macros that rely on :as clauses which aren't called in the namespace they're defined in

14:38 SegFaultAX: nDuff: How is the property value doing out there? Historically its always been like an order of magnitude less than the Bay Area but there's a lot of money moving out there in recent years.

14:38 technomancy: that one is tricky

14:38 ro_st: dnolen: would you mind describing briefly the change to keywords? they're no longer strings?

14:39 nDuff: SegFaultAX: Land's still cheap here.

14:39 SegFaultAX: A bit more than I'd like -- have a house I'm looking to unload.

14:39 tomoj: dnolen: hmm, you mean only in the context of the last example and after the first answer has already been found?

14:39 ro_st: technomancy: ok. i'll walk-with-scissors around our macros namespace

14:39 silasdavis: if I have function defined in the outer scope with the same name as a function argument

14:39 technomancy: ro_st: there's a workaround for the macro issue, but it doesn't work cleanly out of th ebox

14:39 SegFaultAX: nDuff: Are the salaries still competitive with the valley?

14:39 ro_st: i'll give it a go and let you know

14:39 thanks technomancy!

14:39 silasdavis: how can I reference the outer scope from within the function

14:39 ?

14:39 dnolen: tomoj: yes the reason the last example (counto) doesn't terminate is because the second branch of reduceo* won't terminate with run 2

14:39 technomancy: sure

14:39 nDuff: SegFaultAX: Yes.

14:40 tomoj: ah, ok, thanks

14:40 nDuff: SegFaultAX: ...after taking into cost-of-living differences, superior to.

14:40 SegFaultAX: nDuff: Yea, definitely.

14:40 dnolen: ro_st: keyword change hasn't landed yet, but the idea is to move way from keywords as strings, V8 penalizes modifying the string prototype

14:40 ro_st: but there are other benefits, with keywords as strings we'll probably land constant literal optimization as well

14:41 ro_st: will it just be some sort of singleton instance per keyword then?

14:41 SegFaultAX: nDuff: I have family all over southeast TX. Mostly Houston, Baytown, Orange, Beaumont, etc.

14:41 dnolen: tomoj: there's no reason for reduceo* to fail, it'll just keep adding up numbers

14:41 SegFaultAX: nDuff: It staggers me how cheap property is out there comparatively speaking.

14:41 dnolen: ro_st: yes with some special handling of the dynamic read keyword case

14:42 ro_st: gotcha

14:42 kinda hard to write cljs without keywords, so it's a big decision :-)

14:43 Raynes: so, noir.statuses gives you a nice way to set a 500. compojure only does not-found. how do you handle your 500?

14:43 Raynes: I return {:status 500} :p

14:44 ro_st: ok so you don't keey your 500 error page centralised?

14:44 technomancy: ro_st: I have a simple middleware to catch and set status

14:44 if it's an ex-info, I pull :status out of the ex-data

14:44 you could dispatch HTML error pages based on ex-data easily too

14:45 ro_st: technomancy: thanks. is that online somewhere?

14:45 technomancy: sure: https://github.com/technomancy/syme/blob/master/src/syme/web.clj#L111

14:45 ro_st: great, thank you

14:45 akells`: (reset! storage-map (merge @storage-map (hash-map posted-data posted-data))) this works completely fine in the repl, but in actual practice its giving me 'PersistentArrayMap cannot be cast to clojure.lang.IDeref' -- is there something special about the repl in this case?

14:46 amalloy: (throw (ex-info {:status 200 :body "lol who needs to return values via the stack"})) ;; technomancy, make this work

14:46 akells`: storage map is an atom in this case

14:46 technomancy: amalloy: evil

14:46 amalloy: akells`: you hope storage-map is an atom, but apparently it's a map

14:47 akells`: amalloy: well its a map when its @storage-map, which is what I was intendin

14:47 g

14:47 amalloy: no, storage-map itself is a map, or you wouldn't get this exception

14:48 akells`: oh my god you're right. I am an idiot

14:48 thank you

14:48 ro_st: noir/defpartial is utterly useless

14:48 i'm pretty certain the source code is (def defpartial defn)

14:49 hey dobladez! how's life in Argentina?

14:51 amalloy: tomoj: reduceo is trying longer and longer lists, and has no way to know one of them won't eventually return 10

14:52 tomoj: I tried adding some < constraints in counto but no luck

14:52 amalloy: oh, dnolen already got there and i missed it

14:53 i don't think you can fix it in counto. reduceo will just keep going forever

14:56 edtsech: guys, anybody know why ring/compojure display exception on the web only once and remove it after reload? and how to fix it?

14:57 tomoj: seems foldro in 'from variadic functions to variadic relations' fails the same way

14:57 so I guess it's unfixable :)

14:58 amalloy: ~helpme

14:58 clojurebot: A bug report (or other request for help) has three parts: What you did; what you expected to happen; what happened instead. If any of those three are missing, it's awfully hard to help you.

14:58 technomancy: edtsech: compojure won't display exceptions unless you have some kind of stacktrace middleware

14:58 amalloy: hiredman: does clojurebot have a syntax whereby i could ~helpme and also highlight a user, so it's clear who the message is intended for?

14:59 hiredman: no

15:02 tomoj: actually foldro can't even find the first answer

15:03 amalloy: tomoj: where is foldro? i wouldn't expect foldr to work very well relationally, compared to foldl, but i haven't thought very hard about it

15:06 ro_st: easy bits done. 166 defpages to refactor :-(

15:07 tomoj: amalloy: my current attempt at translating it https://www.refheap.com/paste/864c78faff82f4f8c7699d4ba

15:07 it's on page 5 of the referenced paper

15:07 amalloy: oh man. here's an unpleasant surprise: ##(clojure.string/replace [1 2 3 4] " " "|")

15:07 lazybot: ⇒ "[1|2|3|4]"

15:07 amalloy: clojure.string/replace implicitly converts any input into a string by calling .toString on it

15:08 tomoj: amalloy: well obviously my current attempt is wrong :)

15:08 amalloy: tomoj: i don't see a referenced paper

15:09 tomoj: $google from variadic functions to variadic relations

15:09 lazybot: [From Variadic Functions to Variadic Relations] http://repository.readscheme.org/ftp/papers/sw2006/12-byrd.pdf

15:10 tomoj: this one gets the first answer and then diverges https://www.refheap.com/paste/854b10b81ec3bec746caba56e

15:11 edtsech: technomancy: I use https://github.com/weavejester/compojure/blob/master/src/compojure/handler.clj#L28 and it already display smth http://dl.dropboxusercontent.com/u/2428018/Screenshots/12.png

15:12 I don't know if ring already don't use this https://github.com/mmcgrana/ring/blob/master/ring-devel/src/ring/middleware/stacktrace.clj#L83

15:12 tomoj: (and stabbing away with (fd/< val c) (fd/<= out c) doesn't help)

15:16 hmm, this works though https://www.refheap.com/paste/6cd808869ada988874d3c99d8

15:16 that's silly, https://www.refheap.com/paste/8e84c6953ee66aea776fa904f

15:20 gfredericks: amalloy: I dunno that doesn't seem like the worst sort of duck-wrapping to me

15:20 given that it's basically inconceivable to call a clojure.string function on anything but a string

15:21 amalloy: gfredericks: i did it accidentally, and took ages to find it because it didn't break until much later in my program

15:21 gfredericks: yeah I believe it

15:25 ro_st: Raynes: how do i deal with migrating :session-cookie-attrs values for server/start ?

15:25 we set {:secure true :http-only true}

15:26 i guess i could just ask weavejester :-)

15:26 weavejester: Ask me what?

15:26 Glenjamin: ro_st: http://ring-clojure.github.io/ring/ring.middleware.session.html

15:27 ro_st: weavejester: i'm migrating from noir to lib-noir. we use session-cookie-attrs in noir's server/start

15:27 Glenjamin: you want :cookie-attrs

15:27 ro_st: aha

15:27 Glenjamin: compojure mostly uses ring middleware :)

15:28 ro_st: ok. the migration path is to move it to :cookie-attrs in noir-wrap-session

15:28 Glenjamin: oh right, noir to lib-noir, not to compojure :)

15:29 weavejester: would you be able to tag/release a new ring-mock soonish? I'd like to depend on the new functionality in peridot

15:29 not urgent though :)

15:30 ro_st: werrrrl, yes-ish. once i get noir out, i'll see what stuff from lib-noir we want to keep. as simple as -ing possible is my preference

15:30 weavejester: Yeah, I can do that tonight

15:30 Glenjamin: excellent, thanks

15:33 ro_st: so, lein-ring gives me a nifty way to start ring from shell. is there a way to start and stop ring apps from the repl? a year ago there was something but it was lein 1.x

15:34 weavejester: ro_st: You can do it with the standard Ring adapter.

15:34 Glenjamin: 0.1.4 of ring-mock released.

15:34 Glenjamin: cool, thanks

15:35 that reminds me, i was going to try and add pluggable http-kit support into ring-server

15:35 weavejester: ro_st: There's also a ring-server library that makes adds a few extra pieces.

15:35 Glenjamin: but i couldn't see how to only optionally include the default jetty adapter

15:38 ro_st: weavejester: ring-server/serve returns something i can stop?

15:38 Glenjamin: ro_st: https://github.com/weavejester/ring-serve

15:39 ro_st: that's the old one, Glenjamin

15:39 weavejester: ro_st: If you have {:join? false}. I can't remember whether it has it automatically.

15:39 ro_st: here's the new one https://github.com/weavejester/ring-server

15:39 ok, i'll poke at it. thanks

15:39 Glenjamin: oh, whoops - the example looks like the right thing :)

15:40 weavejester: ro_st: Passing {:join? false} to the standard Jetty adapter means it won't block, and returns a Server object

15:40 ring-serve was just a small wrapper around that

15:40 ro_st: ok, great! join false it is!

15:55 _{^_^}_: if combinator caluclus is to concatenative languages what lambda calculus is to lisp, is there a calculus that relates to OO or am i just making up random bollocks? ;)

15:56 bbloom: guy who's name i can't get to tab complete: i'm sure there could be a calculus to study OO, but you'd need to define OO first :-P

15:57 dnolen: _{^_^}_: might want to take look a the Abadi & Cardelli book, A Theory of Objects

15:58 _{^_^}_: (inc dnolen)

15:58 lazybot: ⇒ 9

15:58 _{^_^}_: it always irks me that inc is a function that side affects in here heh

15:59 bbloom: (dec inc)

15:59 lazybot: ⇒ 0

16:00 bbloom: _{^_^}_: btw, i made that combinator/lambda comparison in my talk at clj/west (although i took it from somewhere else)… may i ask where you're coming from with that question? just curious about how people are finding their way around the concatenative world

16:00 wink: (dec (hex (inc 0)))

16:00 lazybot: ⇒ -1

16:02 _{^_^}_: bbloom: i watched your talk and messed with factjor/factor but didn't remember you made that connection, must have been subconscious association

16:02 bbloom: _{^_^}_: then it's working :-) haha

16:03 _{^_^}_: (and dnolen too) i also really liked this paper http://www.vpri.org/pdf/tr2011003_abmdb.pdf for formalizing object message sending & what not as associative memory

16:04 bonus: it's pretty brief and easy to understand

16:05 rbxbx: double bonus: it's not $150

16:07 bbloom: well while we are discussion free descriptions of calculi related to objects, see the original Communicating Sequential Processes paper too: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=

16:09 dnolen: bbloom: thanks for the links

16:13 svedubois: How I can translate this to CLJS?

16:13 var metadata = [];

16:13 metadata.push({ name: "name", label: "NAME", datatype: "string", editable: true});

16:15 _{^_^}_: http://images.wikia.com/uncyclopedia/images/math/a/2/a/a2a900751fb30591f371d3e29a990654.png

16:15 wrong channel

16:16 vgrbr: hi, i was thinking about some tools for manipulating maps, https://github.com/vgrocha/map-lib , would it make sense?

16:16 Raynes: tpope: You should write an ido-mode thing for vim.

16:17 mthvedt: can mutually recursive defns be inlined with each other by the jvm in clojure?

16:17 gtrak: mthvedt: defns can't be inlined

16:17 rbxbx: Raynes: rails.vim has things similar to ido mode, but they're scoped to rails-y things.

16:17 Raynes: which features of ido-mode are you missing in vim?

16:17 Raynes: rbxbx: All of them

16:18 rbxbx: heh

16:18 Raynes: File system navigation.

16:18 It's seriously the one thing from Emacs that it physically hurts me to not have.

16:18 tos9: Raynes: That exists.

16:18 rbxbx: Raynes: have you tried https://github.com/kien/ctrlp.vim ?

16:18 Raynes: wildmenu kinda sorta works that way but...

16:18 tos9: Raynes: In at least 3 filesystem fuzzy matcher plugins.

16:18 rbxbx: It gets you pretty close.

16:18 Raynes: None of those do what ido-mode does.

16:18 tos9: Raynes: CommandT, CtrlP and Fuzzy*

16:18 rbxbx: and is the best of that lot that I've tried.

16:18 mthvedt: gtrak: i'm finding references to ^:static for inlining and primitives, but this was declared not necessary for performance later

16:19 and it is not clear to me why

16:19 tos9: Raynes: Oh. What else does it do?

16:19 Raynes: If I ctrlp from /, it is going to try to index every file in my filesystem.

16:19 tos9: Yes.

16:19 gtrak: mthvedt: the static was for primitive-stuff, I think the compiler can figure it out now, here's an example of inlining: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L936

16:19 tos9: What will ido do there?

16:19 gtrak: mthvedt: definline is another relevant macro

16:20 ppppaul: can someone help me in the datomic channel

16:20 mthvedt: is this clojure compiler inlining, enabling jvm inlining, or a combination of both

16:20 ppppaul: definline?

16:20 Raynes: It will show you the files in the top-level there and let you cycle through them and narrow the list as you type like ctrlp does. Wildmenu works kind of like it in a certain mode, but not quite the same experience.

16:20 ppppaul: ,(doc definline)

16:20 clojurebot: "([name & decl]); Experimental - like defmacro, except defines a named function whose body is the expansion, calls to which may be expanded inline as if it were a macro. Cannot be used with variadic (&) args."

16:21 tos9: Raynes: So basically the same thing just not recursive?

16:21 rbxbx: Raynes: I think I actually prefer ctrl-p style, it's nice that ido-mode is everywhere though.

16:21 Raynes: ctrlp is great for project scope.

16:21 Not for whole file system scope.

16:21 rbxbx: Probably just a matter of whichever you were raised on.

16:21 technomancy: what happens if you rebind ctrlp

16:21 Raynes: tos9: Also, if I backspace, it cd ..

16:21 technomancy: do you have to rename it?

16:21 tos9: Yeah I think I also prefer recursive, but I can't say without trying it. I wouldn't ever try to do it on /, I basically always want project scope.

16:21 rbxbx: tos9: ditto.

16:22 Raynes: I never want project scope.

16:22 tos9: technomancy: what happens if you're not on OSX but want to use commandt? Do you have to switch OSes :)

16:22 rbxbx: tos9: another reason not to use commandt ;)

16:22 technomancy: tos9: sounds like trouble

16:22 Raynes: amalloy: Nobody gets ido-mode unless they've used it. :(

16:22 We need to shove Emacs down these people's throats.

16:22 gtrak: mthvedt: the problem with defns is the var, fn's can be inlined

16:22 ro_st: Raynes: +1

16:22 tos9: rbxbx: yeah, too bad it's better than ctrlp :D

16:22 ro_st: emacs -chant-

16:22 gtrak: mthvedt: or you can hint the compiler a-la +

16:23 rbxbx: Raynes: I've been using emacs/ido mode for about 5 weeks now. I think it's just a matter of what you're raised on.

16:23 discomfort breeds contempt, or something.

16:23 technomancy: isn't vim supposed to be good about separating objects from commands?

16:23 ro_st: been using projectile since rkneufeld's talk. using his config verbatim, actually. works great

16:23 rbxbx: technomancy: text objects?

16:23 ppppaul: hey guys. i could really us some help on a simple datomic query against an empty db... getting an error and i don't know why (no error when the db has something in it) https://gist.github.com/boxxxie/09bf48ebdfcfc0f99433

16:23 technomancy: seems weird that they wouldn't understand that fuzziness is an orthogonal top-level concept, not something that should be tightly coupled to a specific command

16:24 rbxbx: technomancy: there's wildmode/wildmenu which are decoupled

16:24 but not quite the same.

16:24 technomancy: I see

16:25 anyway, I think project-scoped fuzziness can be useful, but having it project-scoped by default is stupid

16:26 tos9: It *isn't* project scope. It's "from here, recursively", whatever recursively means.

16:26 rkneufeld: technomancy: can I ask why? projectile doesn't really re-invent the wheel, it just re-orients useful commands *at* the project.

16:26 technomancy: rkneufeld: I've never heard of projectile

16:26 tos9: I don't personally ever want to locate files on my file system randomly, but I could imagine someone wanting that. If I wanted that I'd use something else

16:27 Also g:CommandTMaxDepth looks like a thing, though once it reaches that depth I doubt it will then search again if you select the directory.

16:27 rkneufeld: technomancy: ahh, it is a little library for emacs that wraps a number of commands like fuzzy-find, grep in project, etc. with a project focus. https://github.com/bbatsov/projectile

16:27 technomancy: rkneufeld: I'm saying the default operation for fuzzy finding should be scoped to the current directory, which is how ido works.

16:28 rkneufeld: I agree.

16:28 tos9: There's also https://github.com/burke/matcher

16:28 technomancy: project-scoped variants are nice, but they should be layered on top of existing versions

16:28 rkneufeld: technomancy: bingo, afaik projectile does (mostly) that.

16:28 tos9: technomancy: I disagree, which means it'd be good to have both options.

16:28 In ido mode, how do you select a thing once you've matched it?

16:28 Do you ahve to hit a key?

16:29 rbxbx: tos9: yes.

16:29 technomancy: as opposed to...?

16:29 tos9: technomancy: If I want to locate foo/bar/baz/quux.clj I just type fbbq and hit enter faster than I can look at the results

16:29 Raynes: I think he is arguing multiple key presses to get through directories.

16:29 But that's what I want.

16:29 Exactly what I want, in fact.

16:29 rbxbx: haha

16:29 Raynes: And if there is a way to make ctrlp do that please let me know.

16:29 technomancy: tos9: sure; find-file-in-project works that way

16:30 hiredman: enter isn't a key?

16:30 rbxbx: seems like a matter of taste not worth discussing :p

16:30 tos9: technomancy: Is the other thing you were referring to something else than that?

16:30 rbxbx: eh this seems kind of informative. I like hearing how other people work as long as everyone's got level heads.

16:31 technomancy: tos9: that's a lot of pronouns

16:31 pjstadig: technomancy: they don't call them 'pro' for nothing

16:33 technomancy: here's the thing. you should have an orthogonal "fuzzily select from this list" function, and a function for getting a list of files in the current directory, and functions for getting some other sets of files, maybe some stuff for filtering and sorting. compose as you like.

16:33 tieTYT2: I wrote this code that's a web crawler. You give it a url, it gets the html of that url, finds all the images, then downloads all the images. But my code is kind of hard to test because this all is done by calling "crawl-site" and it has IO 3 times

16:34 technomancy: that's it =)

16:34 tieTYT2: or twice, or whatever, the point is

16:34 unlike a haskell program, i'm mixing the functional part and the side effect part

16:34 i'm assuming a better way to organize the code would be to put all the IO/side effect parts at the top level

16:36 tos9: technomancy: That seems fairly obvious, these fuzzy matchers don't exist as one long procedural thing, so I guess you mean "and that should be built into the editor" or "and that should be exposed as library code" or something. The first well, and the second probably exists. Matcher I linked and probably there's a VimL thing somewhere, I know there are other matchers for ctrlp. But yeah all of thsoe pieces exist either in Vim itself or within ...

16:36 ... the fuzzy matcher plugins, and you're obviously free to use those pieces

16:36 It's likely not as easy as in emacs though.

16:39 killing-joke: are there any gotchas/shortcomings in learning Clojure on YARV instead of the LVM?

16:40 technomancy: it's generally regarded as difficult to run clojure on a VM it hasn't been ported to, yes

16:41 killing-joke: technomancy, thanks. have you seen https://github.com/rouge-lang/rouge ?

16:41 amalloy: technomancy: LVM would be even worse, though: running it on a VM that doesn't exist?

16:41 Raynes: Rouge is pretty immature and unmaintained.

16:41 amalloy: sounds like Raynes

16:42 Raynes: Sounds like your mom.

16:42 pjstadig: wat

16:42 technomancy: very skeptical that you could call rouge a clojure implementation

16:42 killing-joke: ok. reason #1 sounds like "early". reason #2 sounds like "buggy", which usually follows "early".

16:43 and reason #3 (per technomancy) "not a faithful implementation"

16:43 Raynes: Well, I'm talking about the fact that there haven't been any useful commits in 4 months.

16:43 killing-joke: any others?

16:44 Raynes: If your'e got an early implementation and it isn't being made not-early, it's probably unmaintained.

16:44 amalloy: killing-joke: so far it sounds to me like racket might be closer to clojure than rouge is

16:45 Raynes: There's that.

16:45 killing-joke: ah. that's different. that could be reason #4 "low rate of fixes/features/improvements"

16:45 amalloy: i mean, feel free to use rouge if you want

16:45 technomancy: it sounds like it's explicitly "clojure-inspired", not an implementation of clojure

16:45 Raynes: Why are you changing everything we say?

16:45 :\

16:45 amalloy: but you asked for problems, and the channel seems to be saying "it is nothing but problems"

16:45 killing-joke: amalloy, i like Racket. i was looking for something with a really quick startup time, which rules out some larger runtimes.

16:45 Raynes: If I say something I probably mean it.

16:46 You don't have to truncate it or try to decipher it because it isn't a riddle or code.

16:46 :p

16:46 IIRC racket is pretty fast to startup.

16:46 SegFaultAX: Raynes: What did you decide on for the topic of your talk?

16:46 wink: the oracle hath spoken!

16:46 killing-joke: Raynes, sorry if i offended you. i'm summarizing, like a journalist.

16:46 Raynes: SegFaultAX: Laser.

16:46 mthvedt: gtrak: how does :inline work? does it plug the fn object into call sites, making them eligible for JIT inlining?

16:46 Raynes: killing-joke: 'corse not

16:46 SegFaultAX: Raynes: Is this the first time you've talked about it publicly?

16:46 Raynes: SegFaultAX: Yes.

16:47 SegFaultAX: Raynes: Sick! Do you know if they are going to record the talk? It's just at your local meetup right?

16:47 Raynes: Yeah, they don't record talks.

16:47 technomancy: Raynes: are you going to bring a laser pointer to demonstrate?

16:47 wink: I got a style question. how deep can you nest if-let and let before gets weird?

16:47 hiredman: mthvedt: :inline works exactly like macro expansion, the body is literally replaced in

16:47 Raynes: technomancy: Unfortunately no.

16:48 gtrak: mthvedt: I don't know the details as I haven't had to rely on it :-), but it's there, I think the compiler does it

16:48 gfredericks: wink: nine levels

16:49 SegFaultAX: wink: If you're nesting very deeply that's usually a good indication that something needs to be factored out.

16:49 wink: SegFaultAX: but how deep is very deeply? :)

16:50 gfredericks: I know, badly phrased

16:50 https://github.com/winks/multiplex/blob/master/src/multiplex/routes/home.clj#L45

16:50 it would be if-let .. if-let, let

16:50 SegFaultAX: wink: Probably a couple levels.

16:50 wink: I find 3 already.. not pretty

16:50 mthvedt: hiredman: is there a way to get to a var that points to something hotspot can inline

16:50 SegFaultAX: wink: That code you pasted there looks fine.

16:50 gfredericks: the if-let monad

16:50 wink: SegFaultAX: it's only 2, would add a 3rd.

16:51 killing-joke: amalloy, thanks. :) i did ask for gotchas. i should have asked for positive items, reasons TO switch (instead of reasons NOT to switch).

16:51 hiredman: mthvedt: inlining in hotspot is very complicated, why are you so concerned with it?

16:51 FireFly: I might very well be missing something here, but.. question: why "some" and not "some?" (especially in comparison with "every?") The docs don't seem to clarify on the naming

16:51 SegFaultAX: FireFly: Because some isn't a bollean operator.

16:51 FireFly: Oh

16:51 shriphani: hi. I have been trying to get ac-nrepl to work in emacs. Currently, when I hit RET on my keyboard, I get : nrepl-return: Wrong type argument: integer-or-marker-p, nil and I can't obtain a newline. My .emacs is here: https://gist.github.com/shriphani/5535977

16:51 technomancy: FireFly: the "some" name was inherited from CL; it was chosen for historical reasons rather than clarity.

16:51 mthvedt: hiredman: i'm writing an experiment that generates code for performance purposes, and java performance best practices is to let the hotspot worry about inlining methods

16:51 SegFaultAX: FireFly: It returns the first item that matches the predicate, not whether any of the items match the predicate.

16:52 mthvedt: in most cases

16:52 hiredman: mthvedt: same for clojure

16:52 technomancy: (but also what SegFaultAX said about bools)

16:52 FireFly: SegFaultAX: I see, so that's why. that makes sense

16:52 SegFaultAX: FireFly: In other lisps, it's common to denote predicate functions with a p suffix.

16:52 FireFly: Clojure is much more forgiving about valid identifiers in that it allows ?

16:53 mthvedt: hiredman: so that's why i'm wondering about def-ing fns that are eligible for hotspot inlining. as i understand it the default code path is a var lookup

16:53 SegFaultAX: (CL has lots of -p functions)

16:53 wink: does CL have truthiness?

16:53 FireFly: Yeah, it was mostly the difference between some and every? that caught me, I overlooked that every? strictly returns a boolean

16:53 amalloy: SegFaultAX: i think even CL supports ?, it's just that -p is traditional

16:53 hiredman: mthvedt: no, vars are looked up at code load time

16:53 SegFaultAX: wink: Not in the same way clojure does.

16:53 technomancy: yeah, I think -p is just a CL-ism

16:53 or maybe a maclisp-descendant-ism

16:53 SegFaultAX: Yea probably.

16:54 wink: SegFaultAX: thought so. (if (some ...) does not 100% care for strict bools.

16:54 SegFaultAX: I almost never see ? used as a predicate suffix in CL.

16:54 hiredman: mthvedt: there is a var deref, which can be inlined (for non-dynamic vars)

16:54 SegFaultAX: wink: Well, in clojure you have to think about what counts as a truthy value.

16:54 FireFly: Okay, so, this inevitably leads to the question.. why every? rather than every (i.e. why not return the first truthy value?)

16:54 SegFaultAX: wink: In a boolean context, everything except for nil and false evaluates to true in a boolean context.

16:54 wink: SegFaultAX: yeah, that

16:54 SegFaultAX: Whoops, one too many boolean contexts there.

16:54 wink: 's why it works

16:55 SegFaultAX: FireFly: Think about it, what would you return if not a bool for that. Does every single item match this predicate?

16:56 FireFly: Well, I'd return the last evaluated value I think, which is either the last value if every value is truthy, or the first falsy value otherwise

16:56 Hm

16:56 mthvedt: hiredman: right, but hotspot is better at ref chasing when the refs are final, whereas vars can be redef'd

16:56 FireFly: Never mind

16:57 SegFaultAX: FireFly: So you basically want some and any? to work like or and and, respectively?

16:57 clojurebot: Gabh mo leithscéal?

16:57 SegFaultAX: (But with a predicate function, obviously)

16:57 hiredman: mthvedt: in practive they are effectively final at runtime

16:57 FireFly: SegFaultAX: yup, that seems to make sense to me

16:58 hiredman: which is what hotspot looks for, it doesn't actually care about the "final" modifier

16:58 SegFaultAX: FireFly: Not an entirely unreasonable request. That's effectively how they work in other languages.

16:58 FireFly: Except that they /always/ return boolean values.

16:58 hiredman: mthvedt: http://www.azulsystems.com/blog/cliff/2011-10-17-writing-to-final-fields-via-reflection and http://www.azulsystems.com/blog/cliff/2011-10-27-final-fields-part-2

17:00 SegFaultAX: FireFly: Anyway, if you really want any? that should be very easy to write. It turns out that some a) does the same thing if you consider what sorts of things evaluate to true in a boolean context and b) has other useful properties for finding values given some fn.

17:00 tl;dr you'll get used to it.

17:01 FireFly: Yeah, okay, good enough :p

17:01 * FireFly goes back to the clojure tutorial

17:01 SegFaultAX: FireFly: Good luck!

17:01 FireFly: :-) thanks

17:03 pandeiro: is there a way to clear the terminal like C-l does from clojure?

17:04 TimMc: pandeiro: C-l works fine from `lein repl`

17:04 amalloy: yeah, use anything with readline, pandeiro. lein repl, rlwrap, whatever

17:05 shriphani: hi. I have a file that I am updating and want to see the updates reflect in the repl. I have :aot :all in my project.clj and doing (use '<namespace>) doesn't update the repl with the newer routines. what am I doing wrong?

17:05 pandeiro: TimMc: programatically?

17:06 not talking about a repl, sorry, but a cli app

17:07 technomancy: shriphani: I strongly recommend not using :aot :all outside deployment

17:07 shriphani: technomancy, I see. why?

17:08 gfredericks: guys have we made sufficient use of the term "technomantic" yet?

17:08 technomancy: shriphani: because it doesn't work very well with reloads if you use protocols or records or something like that

17:08 SegFaultAX: pandeiro: The common way is to get the term info and scroll the screen up.

17:08 amalloy: even in deployment it doesn't sound good

17:08 technomancy: amalloy: eh?

17:08 SegFaultAX: pandeiro: That's effectively what `clear` does.

17:08 amalloy: i mean, i guess i don't know what "deployment" means. but i've never wanted to :aot :all

17:09 SegFaultAX: I'm assuming that means "in production" or something.

17:09 technomancy: amalloy: "that environment in which you produce a unit of deployment" I guess

17:09 amalloy: i'd guess that as well, and can't think why you'd want to aot-all just because it's in production

17:09 i guess faster startup?

17:09 technomancy: faster boot times; catching compilation errors before you deploy

17:09 pandeiro: SegFaultAX: thanks, where should i be looking to find out how to get the term info?

17:10 technomancy: granted a test run (which you should be doing anyway) will catch the former

17:10 latter

17:10 SegFaultAX: pandeiro: I think laterna has a module for doing that. I could be talking out of my ass though.

17:10 wink: when I have some macro like sqlkorma's (select (limit n)) - (via ~@args I think) - is there a way to use some nil-value for one of the inline values? like (select table (if (whatever) (limit n) ???))

17:11 SegFaultAX: pandeiro: https://github.com/sjl/clojure-lanterna/blob/master/src/lanterna/terminal.clj

17:11 pandeiro: See if that has anything useful.

17:12 wink: seems a simple (identity) helps

17:13 I really need to join #rubberduckdebugging for such questions.

17:13 dnolen: gtrak: mthvedt: the point of inline is to leverage type information if available at compile time, Clojure does this to make many operations faster, especially arithmetic.

17:14 SegFaultAX: wink: Sometimes just explaining the problem you're having to someone else is the most effective way to solve it.

17:14 wink: I prefer a plastic Android on my desk.

17:14 wink: :D

17:14 gfredericks: dnolen: I was thinking the jvm's :inline feature would be interesting as an emulator for cljs's fn-macro-combo feature

17:15 hiredman: dnolen: well, that is the most extensive use of it, largly to target the compiler's limited set of intrinsics

17:15 mthvedt: dnolen: generally, i believe programming languages shouldn't be teleological; specifically, i'm interested in having clojure fns that can be inlined as effectively as a final field method call in java

17:16 hiredman: :inline has nothing to do with jvm inlining

17:17 mthvedt: if there's no way to make clojure defns that play nicely with hotspot, that's really bad news for performance

17:17 pandeiro: SegFaultAX: seems like i would have to create the terminal from my program in order to query it w/ lanterna; i'm planning on running the app from an existing terminal, so i would need to get _its_ size i guess?

17:17 SegFaultAX: Yes. No idea how to do that in Java.

17:18 pandeiro: np thanks for the link to lanterna anyway

17:18 hiredman: mthvedt: they play nicely with hotspot by default

17:19 mthvedt: hiredman: hotspot might not optimize non-final lookups even if they're 'effectively final'

17:19 for example

17:19 hiredman: mthvedt: hotspot my not optimize final lookups

17:19 hotspot is complicated

17:19 mthvedt: hiredman: it's more likely to

17:20 SegFaultAX: In what case would it not optimize a final lookup?

17:20 That's like the easiest optimization ever I'd have thought.

17:21 hiredman: SegFaultAX: non-hot paths, and final is not really enforced

17:21 what happens to inlined finals when you reflectively change the value

17:22 dnolen: gfredericks: hrm, what do you mean? They do serve somewhat the same purpose.

17:23 mthvedt: hiredman: i cannot say for sure for that specific case, but the jvm supports tracking constants and deoptimization when they change

17:23 hiredman: mthvedt: right, which is the effectively final stuff

17:23 gfredericks: dnolen: I just don't know of anybody using :inline in that manner, or if that's a supported usage. E.g., should hiccup's html macro be an :inline function instead?

17:23 so it has the flexibility of a function but can still do compile-time optimizations when possible

17:24 gtrak: gfredericks: I've abused definline just to not have an extra stack-frame :-), clojure.test reporting...

17:24 mthvedt: hiredman: but the jvm is worse at figuring out 'effectively final' than actually final

17:24 this is a well known factor in java performance

17:24 gfredericks: I just didn't know if that tactic was a hack or a recommended usage

17:24 SegFaultAX: How does something become effectively final?

17:25 hiredman: mthvedt: it was on very early versions of the jvm

17:26 http://www.infoq.com/presentations/JVM-Mechanics is pretty good

17:26 killing-joke: amalloy, thanks for the Racket / PLT pointer. TIL that (in chapter 19 of the Racket docs) you can say '#lang racket/base'

17:26 in a script for about a 4x faster startup

17:26 SegFaultAX: hiredman: Thanks!

17:26 There's also a decent talk on JVM GC on infoq if anyone is interested.

17:27 mthvedt: hiredman: per oracle docs (and personal experience) it is still the case

17:27 better at figuring out effectively final != as good in practice

17:27 SegFaultAX: mthvedt: How can you make something effectively final?

17:27 What exactly does that mean?

17:28 hiredman: SegFaultAX: it means it is never changed

17:28 SegFaultAX: it is also part of the java closure spec

17:28 mthvedt: segfaultax: the JVM can take certain decision points in code, look at what path it takes, and optimize if it always takes the same path

17:28 hiredman: the closures close over "effectively final variables"

17:28 SegFaultAX: Like methods that always return the same value but are not final?

17:28 (In the simplest case)

17:29 hiredman: http://mail.openjdk.java.net/pipermail/lambda-dev/2011-August/003834.html

17:29 SegFaultAX: not methods, fields

17:30 SegFaultAX: hiredman: Ah.

17:30 mthvedt: i don't know all the specific cases. one commonly cited one is that if a polymorphic call always goes through one subtype, it will optimize for that subtype, so you shouldn't worry about whether a polymorphic method is overridable for performance

17:30 the compiler will stick a deoptimization check if the type ever changes

17:31 SegFaultAX: Oh neat.

17:31 mthvedt: then calling some other method becomes very expensive once, but at the trade-off of the method call being a jump or inline call a million times

17:33 in particular, an IFN call can be as fast as inline code, once the JIT warms up… but that depends on if the IFn lookup itself can be optimized away, also

17:34 wait, it might not

17:35 if the call site is smart enough to do the inlining… hm

17:37 svedubois: If I have a map where (nth metadata 4) is:

17:37 {:editable true, :datatype "string", :name "country", :label "COUNTRY"}

17:37 How I can change the value of "country" to for example "USA"?

17:38 tieTYT2: i've got this fn that takes in a java ArrayList as input and processes the elements in complex ways (deleting, overwriting, etc.). This works, but I also need to audit the changes I'm making. What's a good way to add this functionality? My first thought is an atom that collects the changes as they're happening, but this is probably the worst way

17:39 mthvedt: hiredman: effectively final in the closure spec seems to refer to variables that are effectively final at compile time, not run time

17:42 amalloy: mthvedt: there's no such thing as effectively-final for runtime. a local variable is effectively final if nothing ever writes to it. it is not possible for anything but a local to be effectively final, because anything can write to it; and for a local there's no need to do runtime checks because the set of things that can write to it is fixed

17:43 tieTYT2: don't modify an arraylist? copy it into something persistent, and then while you work on it you'll implicitly generate an audit trail of all the old versions

17:43 mthvedt: amaloy: then it seems we are talking about two different things--the claim was that fn invocations through vars can be JIT optimized if they are "effectively final" at runtime, and the citation was for the notion of effective final in the closure spec

17:43 tieTYT2: amalloy: how do I implicitly do that?

17:44 wouldn't I have to explicitly do that?

17:44 amalloy: you just...keep the old versions around. (let [init [1 2 3], v2 (conj init 4)] {:states [init v2]})

17:45 tieTYT2: oh wow

17:45 amalloy: i would say that's the whole point of functional programming, but of course that's only one of the benefits

17:45 tieTYT2: and I assume :states will grow?

17:45 and then I need to write functions that can see the changes between init and v2, then v2 and v3?

17:46 amalloy: states is whatever you want. i just wrote it. you can write it however you want

17:48 SegFaultAX: tieTYT2: Fun fact for you: if you're doing a lot of repeated modifications `reductions` is a nice way to see each successive state.

17:49 tieTYT2: let me google that

17:49 SegFaultAX: tieTYT2: Think of it like reduce, but instead of only returning the final state of the accumulator, it returns all of its states.

17:50 ,[(reduce + (range 10)) (reductions + (range 10))]

17:50 clojurebot: [45 (0 1 3 6 10 ...)]

17:51 tieTYT2: that seems like it'd work if i could turn my whole algorithm int one reduce

17:51 but right now it's this:

17:51 (->> input (group-by should-remove) vals (map sort-by-start-time) (map remove-inputs) flatten)

17:52 starting with amalloy's suggestion, am I supposed to change every step so it returns a map with states in it instead of what they're currently returning?

17:53 SegFaultAX: That's an odd looking algorithm.

17:53 tieTYT2: since I'm a newb, it's probably wrong

17:54 SegFaultAX: Why group them if you're just going to flatten them back out?

17:54 tieTYT2: it's all about the remove-inputs

17:54 it has a very complicated reduce algorithm

17:54 with a (cond) with 6 branches

17:55 clojurebot: ,(let [testar (fn [x y] (cond (= (reduce + (filter odd? (range 0 x))) y) (str y " is a")) )] (testar 11 25))

17:55 amalloy: thank you, clojurebot

17:55 SegFaultAX: tieTYT2: I'm assuming should-remove returns true or false?

17:55 tieTYT2: no, it returns a vector of 3 fields in the input

17:56 so it groups things that are similar in this way, then it decides if it should remove certain elements in the group

17:56 then it flattens them back out

17:57 so the list ends up as a homgeneous list of input

17:57 SegFaultAX: But remove-inputs knows nothing about which group each was in.

17:57 tieTYT2: why would it need to?

17:57 SegFaultAX: Dunno, it's your program.

17:57 svedubois: In CLJS with:

17:57 (nth country 0)

17:57 ;-> {:America {:br "Brazil", :ca "Canada", :us "USA"}, :Africa {:ng "Nigeria", :za "South-Africa", :zw "Zimbabwe"}, :Europe {:be "Belgium", :fr "France", :nl "Nederland", :uk "Great-Britain"}}

17:57 I am not able to obtain the value of the map:

17:57 (get (nth country 0) :br)

17:57 nil

17:57 Why? Is there something wrong?

17:58 tieTYT2: hehe, it just knows all the things in the group are the same by those three fields and that's the assumption it needs to make

17:59 tomoj: svedubois: :br is nested under :America

17:59 (get-in (nth country 0) [:America :br])

18:00 assuming (nth country 0) is really the map you showed, which would be somewhat surprising..

18:00 amalloy: incidentally, having :America and :br as keywords sounds like a mistake. you quite likely want those to be strings

18:00 SegFaultAX: What does it mean to get the 0th index of a map?

18:01 technomancy: eh; :br isn't bad because it's clearly not intended for display

18:01 well, presumably not

18:02 Foxboron: SegFaultAX: we count from 0. So the first index is essentially 0

18:02 technomancy: but the capitalization on :America makes me wonder

18:02 SegFaultAX: Foxboron: What? ##(nth {:a "foo" :b "bar"} 0)

18:02 lazybot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

18:05 amalloy: SegFaultAX: i don't think he claimed country was a map. perhaps it's a vector containing maps, in which case (get (nth country 0) whatever) makes sense

18:06 Foxboron: lol, sorry SegFaultAX. Didn't read the context.

18:06 SegFaultAX: amalloy: Fair. I assumed country was the country map he pasted. More logical to assume it's the result of the nth expression.

18:06 Foxboron: Np.

18:08 svedubois: Also, you may not need the inner nth if you use get-in, since get-in can traverse vectors.

18:08 (get-in [0 {:a {:b "foo"}}] [1 :a :b])

18:08 ,(get-in [0 {:a {:b "foo"}}] [1 :a :b])

18:08 clojurebot: "foo"

18:08 svedubois: One part of the original JS is here https://www.refheap.com/paste/14276

18:09 And the clojurescript conversion that I have done here: https://www.refheap.com/paste/14277

18:11 SegFaultAX: svedubois: I tend to agree that you probably don't want those countries and codes as keywords. It may incur a lot of sense name/keyword calls depending on your usage.

18:11 Senseless*

18:38 tieTYT2: is there a better way to write this: #(reduce remove-algorithm [(first %)] (rest %))

19:11 does clojure have a library that's an alternative to drools?

19:12 hiredman: tieTYT2: not real, but you an java interop with it

19:12 can

19:16 mthvedt: drools is a nightmare

19:16 hiredman: the alternative is what, jess?

19:17 http://java-source.net/open-source/rule-engines I guess there are more then just those two

19:18 mrcheeks: tieTYT2: I guess, you'll likely need to write a 'nice wrapper', instead of type those "." everywhere in most cases, unless there's dedicated 'clojure' effort.

19:19 mthvedt: i suspect the question is that 'clojure library that's an alternative to drools' => not a nightmare

19:20 technomancy: with clojure you can experience the nightmare of drools outside Java

19:20 will the marvels of this modern world ever cease to amaze

19:20 mthvedt: it's terrible, but with more parens

19:20 sweet

19:20 hiredman: mthvedt: I would love to hear a more detailed critique of drools

19:21 technomancy: drools actually has this jess compatibility mode, which on the surface looks lispy, but under the hood is really weird

19:21 tieTYT2: i don't really know drools. I had no idea it was a nightmare

19:21 but we use it at work (I never have)

19:21 and soon, I'm going to have to have a talk with the "architects" about whether or not we should use clojure

19:22 and I figured I could make a comparison between clojure and drools in terms of effort it takes to learn

19:22 (I know that wasn't my original question, I'm just ranting)

19:22 hiredman: ~google clojure drools

19:22 clojurebot: First, out of 1880 results is:

19:22 javierdallamore/drools · GitHub

19:22 https://github.com/javierdallamore/drools

19:22 hiredman: feh

19:22 tieTYT2: interesting

19:22 pjstadig: http://jamesfindonblog.files.wordpress.com/2012/12/the-architect.jpg

19:23 tieTYT2: pjstadig: yep

19:23 brehaut: that dude needs to eat more fibre

19:23 hiredman: there are definitely google hits for clojure and drools, even hits for reasoning over clojure maps instead of pojos

19:24 mthvedt: well, i might be a little biased because the place i worked at used it in nightmarish ways

19:24 tieTYT2: so I wrote this clojure code to solve this complex problem, but now we're going to have a meeting about whether we should rip out the clojure code to use pure java

19:24 hiredman: I've never used drools for anything, but it is interesting

19:24 tieTYT2: and I want to defend clojure but I'm not sure how to go about it

19:27 hiredman: "look at all the code I'm not writing" -- guy in that rails video

19:29 bbloom: tomoj: of course just as i'm telling you yesterday i know the vars i want to bind statically… i find a use case where knowing them dynamically would be lovely haha

19:29 gtrak: tieTYT2: tell em lisp is good for AI

19:29 tomoj: I feel like dynamic vars are basically meant for the cases where you don't

19:30 bbloom: tomoj: well the binding macro can be resolved statically

19:31 tomoj: but what about pre-existing bindings? or what if you call binding in a function called from inside your macro?

19:31 bbloom: tomoj: so the challenge i have is that i want to assign names to values dynamically matching a view hierarchy

19:32 at first, i knew all those var names lexically by analyzing the view definitions

19:32 but the theming system might want to override some of those values dynamically

19:34 patchwork: tieTYT2: Just spit in their face about what fools and simpletons they are

19:34 That usually does the trick

19:34 tieTYT2: i'm doomed

19:34 gtrak: if they're making you have a meeting about it, sounds like they already made up their mind

19:34 tieTYT2: most likely, yes

19:34 patchwork: tieTYT2: In all seriousness, just show them how many fewer lines of code it takes, and how it works in a concurrent environment without modification

19:35 tieTYT2: you mean current?

19:35 patchwork: Well, I meant it would work concurrently, if your app has multiple threads

19:36 technomancy: the trick is to get out of the way and let Clojure defend itself

19:36 tomoj: bbloom: view definitions can't call functions which call binding? not sure I follow your use case

19:36 technomancy: but that only works if people aren't already prejudiced against it

19:36 patchwork: Isn't there a good "Why to use clojure over java" writeup online somewhere?

19:36 gtrak: rationale?

19:36 clojurebot: rationale is http://clojure.org/rationale

19:37 tieTYT2: ooh thanks I'll read that

19:37 technomancy: patchwork: I dunno; if "it's not Java" isn't convincing enough I'm not sure where to go from there

19:37 tomoj: in general I vaguely suspect that if you know statically the vars you need to convey, you're not really using the full power of dynamic scope anyway. or conversely, in the cases where dynamic scope is absolutely necessary, you can't know all the vars

19:37 very vaguely..

19:37 patchwork: technomancy: "It's not java" is usually the one and only sin, to management trying to avoid taking blame for things

19:38 We recently had a client demand that we stop using clojure

19:38 hiredman: tieTYT2: just tell them it is a DSL for ETL jobs

19:38 patchwork: They only thing they cared about was that it wasn't java so they couldn't run their static analyzer on the code

19:38 gtrak: decompile it and let them run it on that?

19:38 hiredman: wow

19:39 patchwork: gtrak: I wanted to do that but it turns out that though the clojure compiler is written in java, there are things clojure does that can not be emulated in pure java code

19:39 java bytecode sure

19:39 but no java code can generate certain clojure bytecode

19:39 gtrak: ah, that would throw a wrench in it :-)

19:39 hiredman: the locals clearing stuff

19:40 patchwork: Yeah

19:40 hiredman: a shame

19:40 patchwork: hiredman: Truly, especially since we already had a couple projects in flight

19:41 hiredman: well, you just have to write clojue code that generates java code then :)

19:41 technomancy: I wonder if turning of locals clearing would fix that

19:41 bbloom: maybe you should just use guava's immutable types & start with just that tiny battle :-)

19:41 patchwork: All this will change with time, the inertia of the past always resists progress, but in the end it is inevitable

19:41 hiredman: write a java source backend for clojurescript

19:42 gtrak: hiredman: I'd like that for android :-)

19:42 patchwork: technomancy: Would it? I imagine there are other obstacles

19:42 technomancy: patchwork: that's the only case I know of where Clojure bytecode is not representable by Java source

19:43 tieTYT2: hiredman: that might work

19:43 * gtrak at least thinks he would

19:43 technomancy: but then again I don't know Java, so ... ?

19:43 patchwork: technomancy: What triggers locals clearing?

19:43 tieTYT2: patchwork: that's why everyone uses haskell and lisp

19:43 patchwork: IE: what clojure code would trigger a locals clearing event?

19:43 hiredman: I guess it would be more traditional to write an xml backend for clojurescript and generate java from that

19:43 gtrak: let, i believe

19:43 technomancy: patchwork: if you have a lazy seq in a local that is passed to another function but not used after that

19:44 hiredman: technomancy: it is not that specific

19:44 technomancy: oh right; not just lazy seqs?

19:44 I mean that's *why* it's there, but it's not picky

19:44 hiredman: basically if the compiler figures out that any local isn't used again, it emits code to load it on the jvm stack, then null it out at the last use

19:45 technomancy: and the bit that isn't representable is performing the nulling out *after* the return

19:45 or something

19:45 I don't know java

19:45 hiredman: no

19:45 mthvedt: nulling it out before the call, i think

19:45 hiredman: yeah

19:45 technomancy: oh right

19:45 tieTYT2: technomancy: does lein use maven behind the scenes, or just know how to use the repositorys?

19:46 repositories

19:46 technomancy: and stack manipulation

19:46 hiredman: clojure.lang.* has a method somethere the java code can use to fake it

19:46 technomancy: tieTYT2: there's a library called aether that's extracted from maven

19:46 hiredman: RT.return1(o,o=null) or something

19:46 tieTYT2: i see

19:46 i'm surprised you don't know java but you build a build tool for clojure

19:46 technomancy: tieTYT2: so it's literally the same code as mvn uses when it comes to repos

19:47 tieTYT2: I have been extraordinarily fortunate

19:47 tieTYT2: i just started clojure, but it seems like lein gives you a way to avoid java. I don't know how you could avoid it to bootstrap your program before it existed

19:47 didn't you have to learn java to use aether?

19:47 technomancy: I used maven for like six months =)

19:47 hiredman: maven multi module builds!

19:48 patchwork: tieTYT2: You can't avoid java entirely, if you spend enough time with clojure

19:48 xeqi: technomancy: haha, I wouldn't call the maven-ant-tasks stuff fortunate

19:48 technomancy: you have to learn the JDK's classes and how to read javadoc and stuff

19:48 patchwork: eventually the quirks of the VM show through

19:48 technomancy: xeqi: it was all over and done in like three pages of code though

19:48 tieTYT2: or the quirks of the language, if you're using a pure java library, I'd think

19:49 technomancy: (perhaps you have a blog article about this) what attracted you to clojure when you seem so repelled by java?

19:50 technomancy: tieTYT2: I did a bunch of JRuby for about a year before picking up clojure

19:50 and I saw all the undeserved crap headius gets due to the JVM

19:51 headius: I don't even get to be a Ruby hero ;-(

19:52 technomancy: I believe in you headius =)

19:52 headius: thank you!

19:52 technomancy: how is Mirah coming these days?

19:53 tieTYT2: headius: did you write jruby?

19:53 gtrak: headius: you're a ruby hero to clojurists :-)

19:54 brehaut: gtrak: is that damning with faint praise ;)

19:54 hiredman: <headius> tieTYT2: I am but the project lead, many others have contributed

19:55 oh headius, you are too modest

19:55 tieTYT2: nice

19:55 headius: technomancy: others are continuing to move Miraah forward

19:55 brehaut: hah

19:55 gtrak: I guess it could be taken that way, but I'm serious, it's impressive.. especially since I was involved with python 4 years ago, and jruby is light-years past jython

19:55 similar engineering challenges, I think, the GIL, hashmaps everywhere

19:58 headius: tieTYT2: me and others, but I have the most commits

19:58 if that means something :-)

19:58 it could just mean I slice my commits finer

19:59 tieTYT2: so why are you hanging out in #clojure? Are you learning/using the language?

20:02 gtrak: I got a chance to sit through a talk at pycon 2009 which fully consisted of a guy apologizing about the GIL

20:04 technomancy: headius: still planning on using it for jruby's implementation at some future point?

20:04 headius: it's certainly a possibility, but it's also not usually valuable to reimpl known-working code just for the sake of using a new language

20:04 technomancy: headius: an age-old conundrum

20:05 headius: indeed! it might be more attractive to rubyists that want to impl exts for JRuby though

20:32 cfleming: Hi everyone

20:33 Is it possible to call the Clojure compiler from Clojure as part of a macro?

20:33 gtrak: eval?

20:33 clojurebot: eval is evil

20:33 gtrak: no it's not, don't listen to clojurebot

20:33 cfleming: I'm interested in integrating a Java library that uses byte code weaving

20:34 gtrak: what's your expected output of the clojure compiler?

20:34 technomancy: cfleming: the compiler isn't special

20:34 it's just defns and methods like any code

20:34 cfleming: Ideally I'd be able to define a new type of fn where I could call the compiler to compile the body of the function, get the byte code back and weave it

20:35 But the actual compilation happens in clojure.lang.Compiler, and it's not immediately clear to me whether I can call that directly

20:35 hiredman: no, the compiler doesn't expose bytecode

20:35 cfleming: And still get correct line numbers for debugging, for example

20:36 The other option would be to macro expand the fn body and try to manipulate that to mimic the effect of the weaving, but I suspect I'd still screw up line number mappings doing that

20:37 hiredman: what do you mean by weave?

20:37 gtrak: i think you need a custom ClassFileTransformer and classloader isolation of the compiler to pull this off, unless you want to hack up clojure source.

20:37 cfleming: hiredman: the lib modifies the byte code after compilation, usually the compilation is Java via javac

20:38 hiredman: cfleming: for what purpose?

20:38 cfleming: gtrak: could you elaborate on that a little? How would I do that?

20:38 hiredman: In this case it's for lightweight threads, but there are lots of similar libs in the java world

20:39 AOP and so forth, although that's less necessary in Clojure with macros

20:39 hiredman: cfleming: ah, have fun

20:39 gtrak: cfleming: classlojure is a convenient library to look into, and I think the eval stuff goes through here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/DynamicClassLoader.java

20:40 here's an example of a ClassFileTransformer: https://code.google.com/p/java-profiler/source/browse/trunk/profiler/src/main/java/org/glandais/profiler/ClassFileTransformer.java?r=3

20:41 cfleming: Ah, this is for a JVM agent, right?

20:41 gtrak: I'm not sure of the significance of ClassLoader arg, but that might be something to look into: transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)

20:41 yea

20:41 cfleming: The lib already has one of those

20:41 gtrak: perfect :-)

20:42 cfleming: The issue is marking which things I need to transform

20:42 gtrak: right

20:42 cfleming: In Java it's done using methods which throw a particular exception

20:42 gtrak: like I said earlier, clojure spins up its own classloaders

20:42 if you can track those somehow, then you've got it

20:42 cfleming: Unfortunately Clojure fns don't even have Clojure metadata

20:43 arohner: This is kind of a crazy question, but is there a way to stick conditionals into a project.clj? specifically I want (when (System/getenv "foo")) in my :jvm-opts

20:43 gtrak: ah, here! 'loader - the defining loader of the class to be transformed, may be null if the bootstrap loader'

20:43 cfleming: yeah, I can check if the class loader for a particular class is a DCL, but I can't mark certain fns for weaving from a Clojure macro

20:43 arohner: cfleming: clojure fns have had metadata since 1.3 I believe

20:44 gtrak: arohner: the classes or the instances?

20:44 hiredman: arohner: you can use unquote in project.clj

20:44 cfleming: arohner: I might be wrong, but I think that's the var that defn assigns to, not the fn itself

20:44 gtrak: the fn itself is an instance of a class..

20:44 arohner: hiredman: is there a way to do it that can be read w/ EDN?

20:45 hiredman: arohner: no

20:45 arohner: cfleming: pre 1.3, only the var. post 1.3, the fn as well

20:45 gtrak: instances

20:45 gtrak: arohner: right, so I think that doesn't help here

20:45 since this is classloading-time

20:45 arohner: gtrak: ah, sorry, I'll read for context more next time

20:47 cfleming: Interesting, neither IFn nor AFn implement IMeta, so I guess the fn class does?

20:48 I'd have to check what the compiler does in that case

20:48 gtrak: I guess you could transform all classes, look for instances :-), check their metadata, and retransform

20:49 tomoj: AFunction is the IObj

20:49 this is part of the reason why fns with metadata are ugly

20:51 &(with-meta + {})

20:51 lazybot: ⇒ #< clojure.lang.AFunction$1@81d54e>

20:51 tomoj: hmm but wait

20:52 cfleming: This is weird

20:52 tomoj: &(satisfies? clojure.lang.IObj +)

20:52 lazybot: java.lang.NullPointerException

20:52 tomoj: &(instance? clojure.lang.IObj +)

20:52 lazybot: ⇒ true

20:52 cfleming: The Clojure compiler is definitely checking metadata on the fn

20:52 But I can't see anywhere where it emits anything different based on that

20:53 &(instance? clojure.lang.IMeta +)

20:53 lazybot: ⇒ true

20:53 cfleming: I'll have to check how that metadata is restored when a ns is AOT compiled

20:54 tomoj: &(instance? clojure.lang.AFunction +)

20:54 lazybot: ⇒ true

20:55 tomoj: scratch what I said about AFunction then..

20:55 it's just ugly cus it's ugly :)

20:56 cfleming: Yeah, the compiler emits AFunction for fns when they're single-arity and RestFn when they're variadic

21:00 gtrak: thanks for the pointer to classlojure, I'll check it out

21:02 gdev: is there a way for nrepl to startup as soon as emacs starts up to edit a clojure file?

21:05 i'm using emacs live and I'm afraid to touch the init.el file...it has ascii pictures of nuclear explosions 0_o

21:20 technomancy: that's terrible

21:22 gdev: it's a pretty effective error message

21:23 technomancy: telling someone not to edit init.el is against everything Emacs stands for

21:24 gdev: technomancy, no it's not to keep people from editing it, it's just for error messages at startup

21:25 was being melodramatic since i'm always intimidated by config files that have a lot of clever ascii art

21:26 technomancy: oh, I see

21:29 gdev: hrm, wonder how long it will be before we get emacs written in clojure. i guess it couldnt hurt to learn a little emacs lisp if it means I can shave the yak quicker

21:29 SegFaultAX: gdev: Then you might not want to ever read a gamefaq tutorial.

21:29 Your average gamefaq tutorial has at least 2MB of ascii art.

21:30 gdev: SegFaultAX: oh yeah I know, luckily those aren't config files

21:30 SegFaultAX: Heh, true.

21:31 bruceadams: gdev: Emacs in Clojure being worked on :-) https://github.com/hraberg/deuce

21:31 gdev: bruceadams: =D that just made my whole night

21:33 work must be slow at the bank if he has time to work on that

21:35 SegFaultAX: Also, light table.

21:37 gdev: he works on light table as well?

21:37 mthvedt: is there a way to tell if a given expression is constant, by the clojure compiler's definition of constant

21:43 hiredman: mthvedt: it depends what you mean

21:43 the compiler has this thing called a ConstantExpr, which is just quoted values

21:45 what happens for ConstantExprs is the values are put in to static final fields, but there are other kinds of Exprs that also happens for

21:45 mnemnion: There is also Catnip, in the general family of Clojure editors in Clojure

21:45 the actual code base is pleasingly polyglot

21:45 hiredman: there is also :const which is another thing entirely

21:47 mthvedt: hiredman: well i was looking at the docs for case and wondering about macros/evals that can generate a case

21:47 but playing in the repl, it looks like anything can go in a case

21:48 hiredman: mthvedt: literals can go in case

21:48 symbols won't be evaluated

21:48 lists are treated as an or

21:48 mthvedt: yes, i was mistaken

21:48 hiredman: (case x (1 2) :foo) x can be 1 or 2 for :foo

21:48 mthvedt: i thought i was embedding a new object in the case

21:49 hiredman: :const might not be a thing anymore

21:49 mthvedt: but it was a list containing an object constructor, whatever that does

21:50 hiredman: mthvedt: a list with a symbol

21:50 ,(type '(Foo.))

21:50 clojurebot: clojure.lang.PersistentList

21:50 hiredman: ,(type (first '(Foo.)))

21:50 clojurebot: clojure.lang.Symbol

21:50 hiredman: ,(first '(Foo.))

21:50 clojurebot: Foo.

21:51 amalloy: hiredman: afaik :const still exists

21:51 hiredman: amalloy: hmmm, I wonder what version of the compiler I am looking at

21:52 mthvedt: hey, is const a solution to the static linking question i was asking way earlier

21:53 amalloy: hiredman: i could be wrong, for sure. looking now, i don't see it, but i don't remember where it was before :P

21:53 mthvedt: anyway, the case expression was about

21:53 hiredman: mthvedt: no, :const is weird

21:54 mthvedt: oh?

21:54 weird how

21:55 hiredman: if I recall (and I may not since I have never had cause to use it) you do something like (def ^:const x foo) and now the compiler will replace x with 'foo everywhere

21:55 amalloy: hiredman: yeah, :const is still around. RT.CONST_KEY, used in Compiler.analyzeSymbol

21:56 tomoj: whoa, nuts

21:56 hiredman: yep

21:56 nuts

21:59 interesting that is not exactly right

21:59 it would eval foo, and whatever the value of foo is there, would be inserted quoted

22:07 amalloy: right, the idea being to (def ^:const pi (approximate pi...))

22:08 and then you can use the approximation anywhere cheaply

22:09 SegFaultAX: Has anyone played with dropwizard?

22:13 mthvedt: but ^:const must be a primitive or something?

22:13 you can't def const, say, a fn

22:17 gdev: SegFaultAX, no, but it does look interesting

22:24 supersym: Oh how did 2 weeks of full-time clojure improve my understanding of any other language as if magic,...I'm literate/meta-programming and writing my own DSL where I can :D

22:24 gdev: but not english ;)

22:24 supersym: *sacrifices a goat*

22:24 that's just for fun ;)

22:25 gdev: I give up, how?

22:25 supersym: well if only I knew

22:26 s4muel: it's a side-effect of clojure itself

22:26 supersym: but significant part has to do with changing from OOP -> functional

22:26 though also I tend to map much more, use hashes differently, even a monad or two

22:27 yeah I believe so as well, the ideas expressed in it come from every-day life so I recognize the problems that rich addressed much easier

22:28 but also I read that Lisp-languages tend to have had such an effect in general through history

22:31 gdev: maybe this one will stick around for a while and we won't have to keep solving problems that were solved before the internet was invented

22:33 arrdem: gdev: hah

22:33 gdev: a likely story

22:33 s/story/proposition

22:49 gdev: according to xkcd http://xkcd.com/1205/ figuring out how to get nrepl to startup automatically when emacs starts is no longer worth the time

22:55 Apage43: gdev: I should print that out

22:57 gdev: Apage43, yeah it's saved me a lot of time. If I spend so much time shaving the yak that I have to consult the chart, i've spent too much time

Logging service provided by n01se.net