2013-04-01
| 00:07 | technomancy | arg... four years of doing clojure and still get bit by that stupid stupid dashes-to-underscores nonsense |
| 00:08 | technomancy | the things we put up with for no good reason =\ |
| 00:30 | callenbot | technomancy: worth it to be using a language that isn't spoiled-milk stupid. |
| 00:31 | technomancy | callenbot: sure, but that doesn't mean we shouldn't be embarrassed when it is stupid |
| 00:31 | callenbot | Of course. |
| 00:32 | callenbot | technomancy: honestly I'm just grateful for the graceful nil handling. I could do without the copious if-statements I have to write in Python. |
| 00:32 | technomancy | "graceful" nil handling? |
| 00:32 | technomancy | spoken like someone who hasn't used an HM type system? =) |
| 00:32 | callenbot | technomancy: I have, but you know what I mean. |
| 00:33 | callenbot | technomancy: compared with Python and Go which just let your shit fall apart every time... |
| 00:33 | MikeSeth | goddamn you, just by lurking in here I learn something new |
| 00:33 | technomancy | I dunno; clojure's handling of nil is also fairly embarrassing, but at least in this case we can blame the JVM |
| 00:33 | callenbot | bladeeblah I know Maybe/Either is better but it's still an improvement. |
| 00:34 | callenbot | technomancy: if you *really* cared you'd use algo.monad |
| 00:34 | technomancy | I haven't written any nontrivial python... clojure's nil handling seems the same as ruby's |
| 00:34 | callenbot | technomancy: but deep down, you know that Haskell and Scala's type systems are the Gentoo Ricers of the modern age. |
| 00:34 | technomancy | callenbot: if I really cared I'd fork core.typed |
| 00:34 | callenbot | technomancy: you want a typed lisp? |
| 00:34 | technomancy | callenbot: no, I just want NPEs to go away |
| 00:35 | technomancy | that accounts for 70-80% of type errors |
| 00:35 | callenbot | technomancy: this is why I implemented my own func call chain + maybe monad wrappers in python |
| 00:35 | callenbot | NoneType errors were driving me up a wall. |
| 00:35 | callenbot | I don't really need it in Clojure though, the Ruby-esque nil handling is (usually) enough for me. |
| 00:36 | callenbot | Perhaps partly because I don't chuck shit at JVM libraries very often. |
| 00:36 | callenbot | not directly, anyway. |
| 00:37 | callenbot | technomancy: the unspoken assertion here is that one advantage Ruby has on Python is nil handling. |
| 00:38 | callenbot | short-circuiting and kicking nils through the call chain is my preferred way of working. |
| 00:38 | technomancy | because nil can receive certain method calls? |
| 00:38 | technomancy | like .nil? |
| 00:40 | callenbot | technomancy: no, more monadically in that functions can receive a nil argument and just spit back out |
| 00:40 | callenbot | and a monadic wrapper can short-circuit before it gets to that if you have that available |
| 00:40 | callenbot | but if you don't, the behavior is baked in. |
| 00:41 | callenbot | technomancy: .nil? is pretty trivial and doesn't really fix anything, Python's problem wasn't that None makes every action except comparison fail, it was that some fairly common sense operations wouldn't just spit the None back out like Clojure tends to in similar circumstances. |
| 00:42 | callenbot | technomancy: if Haskell and Scala type systems are the cost of wrapping and compile-time checking for nils properly, then I'd rather stay on the other side of the fence. |
| 00:42 | callenbot | I like HM, but I don't like actually being forced to interact with the practical products of it (currently) |
| 00:42 | technomancy | eh; from what I gather scala doesn't really prevent NPEs properly anyway |
| 00:43 | technomancy | OCaml does though, without all the hoops of Haskell |
| 00:43 | callenbot | their Option handles it. |
| 00:43 | technomancy | right, but only if you explicitly opt-in |
| 00:43 | callenbot | technomancy: gods, don't remind me of OCaml. That's a heartache like Common Lisp. |
| 00:43 | MikeSeth | holywar commenceth |
| 00:43 | technomancy | =\ |
| 00:43 | callenbot | technomancy: I mean heartache like I wish it was more successful. |
| 00:43 | callenbot | yearning :P |
| 00:43 | technomancy | yep, I hear you there |
| 00:44 | technomancy | I had such a great time with the language and such a wretched time with the libraries/tooling |
| 00:44 | callenbot | MikeSeth: 'fraid not. |
| 00:44 | callenbot | technomancy: well the system type sizes thing was annoying. |
| 00:44 | callenbot | and the 31-bit integers |
| 00:44 | callenbot | the tagging |
| 00:44 | technomancy | oh, for numerics? |
| 00:45 | callenbot | yeah it was janky. |
| 00:45 | callenbot | technomancy: that there are multiple stdlib alternatives is disconcerting as well. |
| 00:45 | technomancy | I have a hard time getting bothered by numerics that are less horrible than JS I guess |
| 00:45 | callenbot | true. |
| 00:45 | technomancy | eh; are you sure you're not thinking of D? |
| 00:46 | callenbot | no I'm thinking of Jane Street + the batteries included ecosystem |
| 00:46 | callenbot | it's really ghetto. |
| 00:46 | callenbot | although D is too. |
| 00:46 | technomancy | oh, sure; it's a bit different |
| 00:46 | technomancy | I mean with D there are literally two libraries claiming to be "the standard library" right? |
| 00:46 | callenbot | I don't know if I'd put it like that. |
| 00:46 | callenbot | it's more that there's an old and a new |
| 00:47 | callenbot | phobos was the new one i think? |
| 00:47 | technomancy | I thought it was one with a good license and one that was "official" |
| 00:47 | callenbot | oh, yeah. |
| 00:47 | callenbot | I mean there's the GNU D compiler. |
| 00:48 | callenbot | But really, if you want something with strict semantics and HM like Ocaml, what's your practical options? |
| 00:48 | technomancy | jane street seemed like just a bunch of guys tired of the slow evolution of the language |
| 00:48 | technomancy | which I can empathise with |
| 00:48 | callenbot | of course, they had work to do. |
| 00:48 | callenbot | unlike the french. |
| 00:49 | callenbot | from the OCaml wiki page: "Influenced F#, Scala, ATS, Opa, Rust" - frick. |
| 00:49 | callenbot | A list best summarized as: Microsoft, Insane, More insane, Weird and misguided, 20% done afters of dev. |
| 00:49 | callenbot | after years* |
| 00:50 | technomancy | Opa =( |
| 00:50 | technomancy | so much promise, and then they careened off the deep end |
| 00:52 | callenbot | technomancy: I think they saw Meteor and Derby and said, "WE SHOULD DO THAT" |
| 00:52 | technomancy | "you know how we could get funding or something? JAVASCIRPT" |
| 00:53 | callenbot | they weren't wrong. |
| 00:53 | technomancy | sad but true |
| 00:53 | callenbot | Rust is disturbingly gnarly though. |
| 00:53 | technomancy | statements, right? |
| 00:53 | callenbot | I'd call that one of the lesser sins. |
| 00:54 | callenbot | the type system seems good, but the actual *experience* of writing code is Rust is generally fraught with fear, confusion, and hate. |
| 00:54 | technomancy | yes, but all the more damning due to the fact that you have to go out of your way to make it worse |
| 00:54 | callenbot | that might be due to the fact that it's 0.6 right now, but I can't really know for sure. |
| 00:54 | callenbot | I'm not actually sure if the developers care if anybody other than the internal Mozilla Servo developers are able to use Rust |
| 00:55 | callenbot | I don't think they actually care because they're too busy being ecstatic that they're getting paid to write a compiler on top of LLVM. |
| 00:55 | technomancy | clojurebot: creating a language with statements is a great way to broadcast your inexperience with languages to the world |
| 00:55 | clojurebot | You don't have to tell me twice. |
| 00:56 | callenbot | technomancy: unlike Go and OCaml, Rust is actually intended to go head to head with C++. |
| 00:56 | callenbot | technomancy: so I'm less apt to question the statements. |
| 00:56 | technomancy | which means what, appealing to people with severe head trauma? |
| 00:57 | callenbot | technomancy: funny but I could imagine some edge cases where being able to decl a var is somehow helpful to the compiler. |
| 00:57 | callenbot | the thin red line separating systems and applications programming is usually the dividing line at which the programmer services the compiler rather than the other way around. |
| 00:59 | technomancy | think about what it means that no one who understood scheme or forth or smalltalk was exposed to the design of the language before the point at which it was considered too costly to fix |
| 01:00 | callenbot | technomancy: I don't know, pcwalton seemed pretty intelligent to me. I don't know why they did it. |
| 01:01 | callenbot | technomancy: they have random cherry-pickings of Ruby-esque syntax like implicit return |
| 01:04 | callenbot | technomancy: case in point, if you need to declare a range of memory "volatile", how do you do that without statements? |
| 01:08 | huwt | HI |
| 01:08 | huwt | hi* |
| 01:09 | huwt | (list '(:a :b)) vs (list '(a b)) |
| 01:09 | amalloy | callenbot: the same way you do anything without statements: make it an expression that returns nil or some analogue thereof. statements are just "expressions that are invalid in some contexts" |
| 01:09 | huwt | I don't get the difference... just started studying it 3hrs in but confused |
| 01:10 | huwt | one is a keyword, but what does this mean in implication... |
| 01:10 | callenbot | amalloy: you could do that, and that occurred to me, but it's a weird special case to have functions or expressions that act as pragmas. |
| 01:11 | callenbot | I have no qualm with getting rid of statements, I just find the offensiveness of them to other people in non-Lisp languages to be a bit extreme. |
| 01:11 | callenbot | it's not like anybody expected Rust to be a particularly powerful or elegant language. |
| 01:12 | callenbot | it's an experiment in writing a highly concurrent and powerful web browser. |
| 01:51 | rplaca | huwt: one is a keyword and one is a symbol. They're just different things in clojure |
| 01:51 | rplaca | 'a is a symbol. If you use it without the quote, clojure will try to use it as a name |
| 01:51 | rplaca | for a let-bound value or a var |
| 01:52 | rplaca | :a is a keyword, it will evaluate to itself |
| 01:52 | rplaca | so in most contexts, you can use it without quoting |
| 01:59 | Raynes | hyPiRion: Dude. Your Github contributions graph is going crazy. |
| 02:01 | Raynes | hyPiRion: A friend on another network was admiring swearjure a moment ago. I told him of your awesomeness. |
| 02:19 | phatpenguin | #neo4j |
| 02:24 | amalloy | speaking of swearjure, hyPiRion, i think first/rest, and CPS are a universal solution to the large-number representation problem, as long as you have a way to get lambdas anywhere in an expression |
| 02:24 | amalloy | like, i don't know how you manage lambdas, but for large expressions the transformation at https://www.refheap.com/paste/13171 generates a large number of small lambdas instead of one large lambda |
| 02:25 | tieTYT2 | what's the point of defining something as dynamic when you don't need to define something as dynamic to with-redef it? |
| 02:25 | amalloy | instead it has stackoverflow issues, of course, but if you pass it through a trampoline or some other CPS transformer it will get you around the large-method problem |
| 03:17 | noonian | Hi, is there a standard way to get the name and version of my project from leiningen as defined in project.clj? |
| 04:34 | borkdude | so any nice clojure April fool jokes so far? |
| 04:44 | ivan | I believe the wise Clojurians have simply turned off their Internet for 48 hours |
| 04:47 | hyPiRion | Raynes: Well, I'm trying to do at least one commit per day, and one bugfix on Lein per week. It's not that much work really, but it looks nice on the contrib graph, yeah |
| 04:49 | tomoj | hyPiRion: seen gitminder? |
| 04:50 | hyPiRion | tomoj: nope, what is it? |
| 04:50 | tomoj | https://www.beeminder.com/gitminder |
| 04:50 | tomoj | uh.. sign up to give someone money if you don't keep your commit rate goal |
| 04:50 | tomoj | :/ |
| 04:50 | borkdude | what is the best practice when doing multiple apps using a postgresql db? one database, multiple schemas? or one db per app? and one user per app, or just one user to rule all dbs? |
| 04:52 | borkdude | yogthos I am trying postgresql - I noticed I have to change the sql to make it work from the guestbook example |
| 04:52 | borkdude | yogthos for example, I have to convert java.util.Date to java.sql.Date |
| 04:53 | hyPiRion | tomoj: heh, well, if I suddenly get ill I don't want even more expenses |
| 04:53 | hyPiRion | amalloy: "as long as you have a way to get lambdas anywhere in an expression |
| 04:53 | hyPiRion | is probably the hardest part of Swearjure as of now |
| 04:54 | amalloy | i thought it might be, which is why i included the stipulation :P |
| 04:54 | amalloy | but i thought you had solved it |
| 04:55 | hyPiRion | well, I can do it if I make a form and eval it |
| 04:57 | hyPiRion | I'll have to revisit lambdas within lambdas soon I think |
| 05:04 | McTehranBurger | ,"Hallowed are the Ori" |
| 05:04 | clojurebot | "Hallowed are the Ori" |
| 07:19 | borkdude | lol, stackoverflow has "chat with an expert" as 1 april joke? |
| 07:22 | arcatan | my expert wasn't very fun :( |
| 07:22 | borkdude | arcatan who not |
| 07:22 | borkdude | arcatan why |
| 07:23 | arcatan | she was like "Whatever you say" all the time |
| 07:47 | bhenry | what is the best java for clojure dev on ubuntu machine? |
| 08:01 | simsalibim | with compojure, how are most people doing RPC calls? |
| 08:01 | simsalibim | and clojurescript |
| 08:02 | ivan | bhenry: openjdk-7-jdk |
| 08:03 | bhenry | ivan: is that objective? |
| 08:06 | ivan | there may be reasons to use the Oracle build, or IBM's JVM, or Azul's JVM, but I bet you do not need them |
| 08:06 | hyPiRion | bhenry: If you don't notice any difference, either openjdk-6-jdk or 7 works fine |
| 08:07 | hyPiRion | I alternate between both, and I haven't noticed any major differences for development purposes |
| 08:07 | bhenry | thanks guys |
| 08:07 | tomoj | use 7 to avoid having to get jsrwhatever to use reducers |
| 08:07 | tomoj | or is it just fold now? |
| 08:08 | hyPiRion | tomoj: oh right, if you need core.reducers, then 7 is smart to have |
| 08:08 | hyPiRion | I think it falls back to the normal reduce |
| 08:36 | sandbags | does anyone here use LightTable and know if there's ever any activity in #lighttable? I'm not sure if I've just been unlucky so far |
| 08:52 | si14 | how do you "unzip" a sequence in Clojure, preferably in one pass? |
| 08:52 | si14 | I mean getting 2+ seqs from each element of one seq |
| 08:55 | bhenry | si14: partition and partition-all might be good starts |
| 08:55 | hyPiRion | bhenry: I think that does the opposite of what he wants |
| 08:55 | hyPiRion | ,(partition 2 [1 2 3 4]) |
| 08:55 | clojurebot | ((1 2) (3 4)) |
| 08:55 | bhenry | i guess i need to see a sample in and desired out |
| 08:56 | hyPiRion | has [[1 2] [3 4]], want [1 3] [2 4] |
| 08:56 | si14 | [[1 2] [3 4] [5 6]] -> [[1 3 5] [2 4 6]] |
| 08:56 | si14 | hyPiRion: yeah, thanks :) |
| 08:56 | hyPiRion | ,(apply map vector [[1 2] [3 4] [5 6]]) |
| 08:56 | clojurebot | ([1 3 5] [2 4 6]) |
| 08:57 | hyPiRion | I'm not entirely sure of performance on that one though. If you're in dire need of it, you may want to make something yourself |
| 08:57 | si14 | it's kinda works, but not in general case. |
| 08:58 | si14 | I have something like [[a1 b1 [c1 d1]] [a2 b2 [c2 d2]] ...] and need to get 2 maps like {[a1 b1]: c1, [a2 b2]: c2} and {d1: c1, d2: c2} |
| 08:59 | si14 | it's can be done with reduce, but I wonder if there is an idiomatic approach. |
| 09:00 | bhenry | si14: i think whatever you're doing is not idiomatic. |
| 09:00 | si14 | bhenry: why is it so? |
| 09:00 | hyPiRion | Well, that's not covered by the normal funcs at least |
| 09:02 | si14 | ok, I need to compute 2 different metrics on one seq simultaneously. how would you do this? my current solution is r/map of fun that returns vectors of values for each element. |
| 09:05 | si14 | and, btw, am I wrong or clojure.core has a typo in a released version https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L321? |
| 09:06 | hyPiRion | si14: that may well be |
| 09:07 | hyPiRion | $google jira clojure monoid |
| 09:07 | lazybot | [Overview - Clojure v1.6 API documentation] http://clojure.github.com/clojure/branch-master/ |
| 09:07 | hyPiRion | damn you, google. |
| 09:07 | tomoj | hmm, I think you need a postreduce step to do that nicely |
| 09:08 | si14 | tomoj: what do you mean? |
| 09:08 | tomoj | which reminds me of cgrand's suggested change to fold |
| 09:09 | tomoj | well, see http://squing.blogspot.com/2008/11/beautiful-folding.html |
| 09:09 | tomoj | I haven't tried to make sense of it in clojure yet, but I suspect reducers as is is not very well suited |
| 09:10 | tomoj | data Fold b c = forall a. F (a -> b -> a) a (a -> c) |
| 09:10 | tomoj | the (a -> c) seems to be missing? |
| 09:14 | tomoj | (= [10 24] (r/reduce (__ + *) [1 2 3 4])) |
| 09:16 | si14 | https://gist.github.com/si14/df5b9afe28835f8cc154 well, here is a pair of functions in questions |
| 09:16 | si14 | lines 10-15 are there only for rearranging the data. personally I don't like it. |
| 09:18 | tomoj | oh, I missed everything before "I need to compute 2 different metrics on one seq simultaneously" |
| 09:18 | tomoj | I'm going to try to solve my problem instead of yours :) |
| 09:19 | si14 | tomoj: :) |
| 09:19 | si14 | I would really appreciate any comments/suggestions on that snippet. |
| 09:19 | tomoj | hmm https://www.refheap.com/paste/44fb973a86835a8bc4d7ce9b5 |
| 09:19 | tomoj | that was too easy |
| 09:22 | si14 | tomoj: yeah, that works for simple monoids like + or *. but for the general case it doesn't |
| 09:24 | tomoj | what is the problem for the general case? |
| 09:24 | tomoj | I mean the combinef/reducef split in r/fold seems tricky |
| 09:25 | tomoj | are there more problems? |
| 09:28 | si14 | tomoj: no, that's the problem :) |
| 09:29 | tomoj | makes me kind of want one thing that can represent both the combine and reduce |
| 09:31 | tomoj | https://www.refheap.com/paste/224956f9814740700a3e7f377 ? :( |
| 09:32 | tomoj | (defprotocol IMonoid (-empty [this]) (-combine [this ret ret']) (-reduce [this ret v])) |
| 09:32 | tomoj | ? |
| 09:33 | tomoj | yeah, bad name.. |
| 09:33 | tomoj | I'd say 'IFolder' but.. |
| 09:37 | tomoj | (defprotocol ICombine (-empty [this]) (-combine [this cret cret']) (-reduce [this ret v]) (-postreduce [this ret])) |
| 09:38 | tomoj | (extend-type Fn ICombine (-empty [this] (this)) (-combine [this cret cret'] (this cret cret')) (-reduce [this ret v] (this ret v)) (-postreduce [this ret] ret)) ? |
| 09:40 | tomoj | would allow cgrand's idea without breaking existing monoids |
| 09:44 | jcromartie | what *exactly* is print-dup |
| 09:44 | jcromartie | it's undocumented and not self explanator |
| 09:44 | jcromartie | y |
| 09:44 | jcromartie | but it pops up in various examples and discussions |
| 09:44 | tomoj | ,(doc *print-dup*) |
| 09:45 | clojurebot | "; When set to logical true, objects will be printed in a way that preserves their type when read in later. Defaults to false." |
| 09:46 | jcromartie | it specifically seems to rely on read eval |
| 09:46 | jcromartie | ,(print-dup {} *out*) |
| 09:46 | clojurebot | #=(clojure.lang.PersistentArrayMap/create {}) |
| 09:46 | hyPiRion | ,(pr-str (doto (ArrayList.) (.add 1) (.add 2) (.add 3))) |
| 09:46 | clojurebot | "[1 2 3]" |
| 09:47 | hyPiRion | ,(binding [*print-dup* true] (pr-str (doto (ArrayList.) (.add 1) (.add 2) (.add 3)))) |
| 09:47 | clojurebot | "#=(java.util.ArrayList. [1 2 3])" |
| 09:48 | hyPiRion | jcromartie: do you get its use now? |
| 09:48 | jcromartie | more or less |
| 09:48 | jcromartie | I don't quite understand why people advocate using the print-dup function directly in certain cases |
| 09:49 | jcromartie | it might just be the specific example I was looking at |
| 09:49 | bhenry | where can i find a walkthrough on the current best practice of a .emacs that works great for clj dev? |
| 09:50 | bhenry | i have the standard emacs from apt-get install emacs |
| 09:50 | hyPiRion | bhenry: Bodil has a great .emacs.d at https://github.com/bodil/emacs.d, which you may want to look at |
| 09:51 | hyPiRion | I have stolen that design for mine (https://github.com/hyPiRion/emacs.d) |
| 09:51 | hyPiRion | Though they are more extensive than just Clojure though, so if you're new to emacs they are probably a bit overwhelming. |
| 09:51 | rkneufeld | For something a bit smaller you might try bit.ly/clj-ready. |
| 09:52 | stuartsierra | jcromartie: I don't think print-dup is meant to be called directly. |
| 09:52 | jcromartie | I didn't think so |
| 09:52 | hyPiRion | (inc rkneufeld) |
| 09:52 | lazybot | ⇒ 1 |
| 09:53 | hyPiRion | That's a way better introduction for someone completely new. :) |
| 09:56 | rkneufeld | Once the Clojure/west videos are up you'll also be able to see my presentation on editing Clojure in Emacs. Until then there are my animated slides: https://www.dropbox.com/s/rwjer7p9mirbwfw/Editing%20Clojure%20with%20Emacs.mov |
| 10:24 | otfrom | afternoon all |
| 10:35 | borkdude | http://clochure.org/ |
| 10:43 | gfrederi1ks | borkdude: wat |
| 10:44 | gfrederi1ks | this must be date-related |
| 10:46 | nDuff | *snerk* |
| 10:48 | tbaldrid_ | "A better Clojure" https://github.com/videlalvaro/clochure/ |
| 10:51 | snowylike | at first I thought this was an April Fools joke |
| 10:51 | snowylike | but then... |
| 10:51 | borkdude | tbaldrid_ clojure for the masses |
| 10:52 | hyPiRion | Has to be. |
| 10:52 | snowylike | quote: "So one the eve of April 1st we sat down in a brainstorm session with a team of PLT experts. Ideas starting flying around:" |
| 10:52 | snowylike | with "April 1st" in bold |
| 10:56 | hyPiRion | Obvious is obvious |
| 10:58 | hyPiRion | clochure.core looks rather blocky |
| 11:01 | gfredericks | great logo |
| 11:02 | otfrom | lovely |
| 11:02 | borkdude | untyped Haskell would be an alternative worth exploring |
| 11:02 | hyPiRion | gfredericks: We need one of those for Swearjure! |
| 11:03 | jcromartie | ooh, a new clojure project to poke at https://github.com/oakes/Nightweb/tree/master/server |
| 11:04 | jcromartie | wait a minute |
| 11:04 | hyPiRion | Well, it certainly is new. |
| 11:05 | jcromartie | here's the interesting stuff https://github.com/oakes/Nightweb/tree/master/common/clojure |
| 11:06 | jcromartie | pretty neat idea though |
| 11:06 | otfrom | Is there something in clojure core that lets you restructure a map based on the parameters to a function? |
| 11:06 | otfrom | I found this: http://stackoverflow.com/questions/8999794/map-restructuring |
| 11:06 | otfrom | but I'm wondering if I'm missing something core |
| 11:07 | gfredericks | hyPiRion: I'm terrible at logos |
| 11:07 | hyPiRion | gfredericks: Not you, we. |
| 11:08 | gfredericks | otfrom: not sure what you're asking. the top answer says "it's not provided" which is accurate. did you want something slightly different? |
| 11:09 | jcromartie | restructuring, huh, interesting idea |
| 11:10 | jcromartie | basically printf for data structures |
| 11:10 | bbloom | otfrom: not really workable with maps because the reader initializes them as real data structures |
| 11:11 | bbloom | if you wanted to d something like obj = {a, b, c}, then you'd have an odd number of keys |
| 11:11 | bbloom | you'd need to do something like {:keys [a b c]} |
| 11:11 | jcromartie | just like destructuring |
| 11:11 | bbloom | but then you have no way of differentiating between assignment and restructuring, you'd need some kind of marker |
| 11:12 | bbloom | jcromartie: right, i'm just saying that it couldn't be baked into the syntax w/o creating ambiguity, you'd need to specifically request restructuring |
| 11:12 | otfrom | What I'd like to be able to do is (defn foo [bar baz] ...) call (foo 1 3) and have {:bar 1 :baz 3} available in the defn |
| 11:12 | gfredericks | that's defnk ain't it? |
| 11:13 | gfredericks | no wait |
| 11:13 | gfredericks | nevermind |
| 11:13 | gfredericks | otfrom: so you want a special extra local that has the arguments |
| 11:14 | otfrom | I'm not sure I *want* it, but if it existed, then I'd want to use it |
| 11:14 | otfrom | and it seems like it doesn't exist |
| 11:14 | jcromartie | otfrom: it seems easy enough to make |
| 11:14 | clojurebot | Huh? |
| 11:14 | otfrom | and it is always so difficult to proves something doesn't exist ;-) |
| 11:14 | otfrom | jcromartie: it does look simple to make, which is partly why I thought there might be something in core already |
| 11:15 | otfrom | and I'd just feel silly for re-implementing it |
| 11:15 | gfredericks | (defmacro defn' [name arglist & body] `(defn ~name ~arglist (let [&args {~@(mapcat (juxt keyword identity) arglist)}] ~@body))) |
| 11:15 | gfredericks | ^ that has a 14% chance of working |
| 11:15 | otfrom | lol |
| 11:15 | gfredericks | wait no 0 |
| 11:15 | hyPiRion | 14%? That's specific. |
| 11:15 | gfredericks | the splicing won't work |
| 11:15 | hyPiRion | ,(rationalize 0.14) |
| 11:15 | clojurebot | 7/50 |
| 11:15 | hyPiRion | Works 7 out of 50 times, every time. |
| 11:16 | gfredericks | (defmacro defn' [name arglist & body] `(defn ~name ~arglist (let [&args ~(into {} (map (juxt keyword identity) arglist))] ~@body))) |
| 11:16 | hyPiRion | yeah, you need a ~@[] before the mapcat |
| 11:16 | hyPiRion | boo |
| 11:17 | otfrom | I just hate re-implementing clojure.core badly. ;-) But at least it looks like I won't be doing that this time |
| 11:17 | loliveira | is there some way to implement "private" variables inside a defrecord? |
| 11:17 | jcromartie | (defmacro ?map [& names] `(into {} ~(mapv #(vector (keyword %) %) names))) |
| 11:17 | gfredericks | oh one more issue the fully qualified &args |
| 11:17 | jcromartie | I have no idea what to call it |
| 11:17 | gfredericks | (defmacro defn' [name arglist & body] `(defn ~name ~arglist (let [~'&args ~(into {} (map (juxt keyword identity) arglist))] ~@body))) |
| 11:17 | gfredericks | otfrom: ^ that seems to work in my repl |
| 11:18 | bbloom | loliveira: to what end? |
| 11:20 | hugod | I just found then when generating type hints on let bindings with a macro, you have to use class symbols, rather than classes themselves, or the type hints are silently ignored :( |
| 11:20 | jcromartie | loliveira: deftype's fields are public, deftype's fields are private |
| 11:21 | bbloom | jcromartie: huh? |
| 11:21 | jcromartie | bbloom? |
| 11:21 | clojurebot | bbloom: readability is not binary |
| 11:21 | bbloom | jcromartie: i assume you mean defrecord and deftype specifically |
| 11:21 | bbloom | er respectively* |
| 11:21 | jcromartie | oops |
| 11:21 | jcromartie | yea |
| 11:21 | loliveira | bbloom: I have a record that holds database credentials. (defrecord DB [spec] …) spec is a map, it holds user, pass, driver, etc.. I'd like to store a pool into the record, but I think it should be private. |
| 11:22 | jcromartie | loliveira: why combine the DB spec and the pool? |
| 11:22 | bbloom | loliveira: why do you need a record at all? |
| 11:22 | jcromartie | ^^ that too |
| 11:22 | bbloom | records are an advanced feature |
| 11:22 | bbloom | they are mostly a performance tool for when you need type dispatch |
| 11:23 | loliveira | bbloom: I need to work with 2 databases. it shoud |
| 11:23 | bbloom | so make two maps of credentials |
| 11:23 | bbloom | and stick them in a vector or something |
| 11:23 | bbloom | and stick that in a map with the pool |
| 11:24 | tjgillies | why do people use two semicolons for comments when one is fine? seems sort of redundant |
| 11:24 | bbloom | {:pool POOL :connections [{:username "foo" :url "xyz://..."} {:connection-string "asdfasdf"}]} |
| 11:24 | bbloom | tjgillies: common-lisp-ism. one semicolon is a line comment for stuff to the left of the ; |
| 11:24 | jcromartie | tjgillies: https://github.com/bbatsov/clojure-style-guide#comments |
| 11:25 | jcromartie | tjgillies: think of it like headline levels |
| 11:25 | bbloom | yeah, what jcromartie said |
| 11:25 | loliveira | bbloom: thank ypu |
| 11:25 | loliveira | i ll try. |
| 11:25 | tjgillies | ... |
| 11:25 | tjgillies | that websites just says "do this because i say so" |
| 11:25 | tjgillies | heh |
| 11:25 | AimHere | Well isn't that what all style guides are for |
| 11:26 | bbloom | i dunno anything about that particular styleguide |
| 11:26 | tjgillies | thats kinda my point |
| 11:26 | tjgillies | ;) |
| 11:26 | bbloom | but it's very common in lisps to have ; line comment, ;; block comment ;;; region comment ;;;; file comment |
| 11:26 | technomancy | riastradh' style guide says "do it this way because parens on their own line get lonely" which is pretty great |
| 11:26 | AimHere | Most of the content in most coding styles are arbitrary; but it's still good practice to follow one of them |
| 11:27 | hyPiRion | bbloom: there should be another one in project.clj, which has ;;;;; for project comments |
| 11:27 | technomancy | "do it this way because you'll sound funny if you don't" is basically the cornerstone of all human language though |
| 11:27 | hyPiRion | and then obviously ;;;;;; for system/application comments |
| 11:28 | enquora | anyone have experience with pedestal yet? |
| 11:28 | bbloom | hyPiRion: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; line separators == "comment on the universe below this point" |
| 11:28 | tjgillies | technomancy: yet here we are programming with parenthesis and such ;) |
| 11:29 | technomancy | tjgillies: all those crazy languages with curly brackets and semicolons just sound like gibberish to me |
| 11:29 | tjgillies | lol |
| 11:30 | technomancy | http://achewood.com/index.php?date=02212002 |
| 11:30 | bbloom | i can't ever remember associativity rules anyway |
| 11:30 | tjgillies | i just realized putting a semicolon on the end of each line is valid clojure |
| 11:30 | hyPiRion | I suspect John McCarthy invented the emoticon and just wanted to be able to insert ;) at any place within his source code. |
| 11:30 | technomancy | heh |
| 11:31 | egghead | achewood rules |
| 11:31 | tjgillies | omg thats messed up if not funny |
| 11:31 | hyPiRion | tjgillies: Putting a semicolon at the start of each line is also valid Clojure |
| 11:32 | tjgillies | hyPiRion: it tends to make my programs less buggy as well |
| 11:32 | hyPiRion | yeh |
| 11:34 | stuartsierra | tjgillies: Emacs will automatically indent ; at right margin, ;; at current code indent level, and ;;; at left margin |
| 11:35 | tjgillies | (inc stuartsierra) |
| 11:35 | lazybot | ⇒ 3 |
| 11:35 | ucb | stuartsierra: I rather enjoyed your post on scope |
| 11:35 | stuartsierra | ucb: Thank you. |
| 11:35 | ucb | no, thank you. |
| 11:36 | stuartsierra | You're welcome. :) |
| 11:37 | ucb | stuartsierra: sorry if this is a silly question, but I got to your blog via planet clojure and I couldn't find an RSS link on your blog. Is this by design? |
| 11:38 | stuartsierra | no |
| 11:38 | stuartsierra | It uses feedburner. |
| 11:38 | bbloom | which is surely going to be killed soon. |
| 11:38 | ucb | hmm |
| 11:38 | ucb | heh |
| 11:38 | stuartsierra | I changed the theme recently: maybe the link is broken. |
| 11:39 | borkdude | what advantage has defhtml in hiccup over a normal function with html form? |
| 11:39 | ucb | I couldn't even find the link :) |
| 11:40 | stuartsierra | ucb: Yeah, I should fix that. |
| 11:40 | ucb | good to confirm it's not my tired eyes then |
| 11:41 | stuartsierra | Thanks for the heads-up. I'll try to fix that. |
| 11:42 | stuartsierra | ucb: The link, by the way, is http://stuartsierra.com/feed |
| 11:43 | borkdude | ANN: Untyped Strictly Evaluated S-Expression Haskell for the JVM http://t.co/kQoxHEcmeM |
| 11:46 | bbloom | borkdude: lol. |
| 11:46 | tjgillies | today is gonna suck |
| 11:46 | tjgillies | :) |
| 11:49 | stuartsierra | There, RSS links added. |
| 11:49 | TimMc | I've seen a defn+opts |
| 11:50 | TimMc | whoops, I was in the scrollback |
| 12:00 | estebann | ls |
| 12:00 | lazybot | bin lib opt proc root sys |
| 12:03 | estebann | i'm trying to get an internal maven repo setup and I'm having a bit of trouble with leiningen |
| 12:04 | estebann | deploying works fine but the Authentication string is not sent when trying to download artifacts from the local mirror of central |
| 12:04 | estebann | has anybody setup leiningen to use mirrors with basic http authentication? |
| 12:06 | technomancy | estebann: are you able to pull from it if you treat it like a regular repo instead of a mirror? |
| 12:07 | estebann | technomancy: i have been testing against an artifact available in central and it seems to try central first if I don't setup a mirror |
| 12:07 | estebann | I could be wrong about that, let me check |
| 12:10 | technomancy | you can do :repositories ^:replace [["myrepo" {...}]] |
| 12:10 | technomancy | to disable central/clojars |
| 12:10 | lyra77 | http://xteensx.info/young-amateur-czech-couple-very-hot-sex-scene/ |
| 12:11 | technomancy | ~guards |
| 12:11 | clojurebot | SEIZE HIM! |
| 12:11 | estebann | technomancy: cool, I didn't know that |
| 12:13 | hyPiRion | ~gourds |
| 12:13 | clojurebot | SQUEEZE HIM! |
| 12:13 | technomancy | clojurebot: botsnack |
| 12:13 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 12:15 | estebann | technomancy: yeah, that works |
| 12:15 | hyPiRion | Ah, that's another plugin idea for lazybot/clojurebot: Say something whenever suspicious links appear here |
| 12:15 | estebann | i can pull the artifact from the proxy |
| 12:16 | jcromartie | bleh… mixing mutable thread-unsafe Java objects and Clojure concurrency |
| 12:16 | technomancy | estebann: so the problem there is that it might allow for transitive dependencies to skip the proxy |
| 12:16 | jcromartie | instant pain! |
| 12:16 | technomancy | I haven't really looked into it, but I think the advantage of :mirrors is that *all* references to central go through your repo instead |
| 12:17 | technomancy | whereas with :repositories you can still have other repos sneak in through declarations of using central inside a dependency pom |
| 12:17 | estebann | ah, gotcha |
| 12:17 | technomancy | I was mostly asking that to see if lein could authenticate at all |
| 12:18 | technomancy | that is, whether the auth issues were specific to the mirror functionality |
| 12:18 | estebann | makes sense |
| 12:18 | technomancy | unfortunately I've never actually used mirrors myself =\ |
| 12:18 | borkdude | clojars april fools joke that didn't make it: for each jar you download, you have to contribute one library :P |
| 12:19 | wting | Hey guys, I'm trying to compile a hello world example via lein repl, but ('compile clojure.examples.hello) gives me a file not found in classpath. What the directory structure I should be using? |
| 12:19 | estebann | technomancy: should mirrors work like I am expecting them to? or have I misunderstood their capabilities |
| 12:20 | hyPiRion | wting: (compile 'clojure.examples.hello) instead, I suppose :) |
| 12:20 | wting | hyPiRion: oops, that's what I meant. :p |
| 12:20 | technomancy | estebann: I'm not quite sure what your expectations are, but you haven't said anything obviously incorrect yet =) |
| 12:20 | borkdude | wting probably don't want to name your namespaces starting with clojure |
| 12:20 | hyPiRion | wting: but are you using Leiningen, or just pure Clojure? |
| 12:20 | technomancy | TBH the mirrors stuff is kind of hand-wavy from my perspective; I just hand off to Aether and it does the rest |
| 12:21 | estebann | technomancy: ok, I guess I'll look into what's going on in aether, thanks for the help |
| 12:22 | wting | hyPiRion: Well I'm not using lein new to create the project, I'm just trying to compile it via `lein repl`. I just want to get a hello world compiled example working. |
| 12:22 | technomancy | estebann: how are you configuring mirror auth? |
| 12:22 | technomancy | it might be that Leiningen just isn't honoring auth settings or something |
| 12:22 | estebann | :creds :gpg like everything else |
| 12:22 | technomancy | yeah, that could just be an oversight of Leiningen that it doesn't check there maybe? |
| 12:23 | technomancy | if you put the creds inline does it work? |
| 12:23 | estebann | i'll check |
| 12:25 | hyPiRion | wting: Well, the docstring says "The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath." |
| 12:26 | estebann | technomancy: yeah, that worked. should I submit a bug report? |
| 12:26 | hyPiRion | wting: So if have /some/dir in your classpath, then the file should be /some/dir/clojure/examples/hello.clj |
| 12:26 | technomancy | estebann: yeah, go for it |
| 12:26 | estebann | technomancy: thanks again |
| 12:26 | technomancy | no problem |
| 12:33 | augustl | are there any asset pipeline (name borrowed from Rails) systems around for Ring apps? For stuff like compiling non-JS to JS, only serving one minified file in production (from memory, probably), etc |
| 12:37 | scottj | augustl: maybe dieter, see pdf in clojurewest slides Biggar-cljv8_dieter_asset_pipeline.pdf |
| 12:37 | wting | hyPiRion: So I have a file in /tmp/hello/src/hello.clj with (ns hello (:gen-class)). In /tmp/hello I run `java -cp /usr/share/clojure/clojure.jar clojure.main` |
| 12:38 | wting | However (compile 'hello) still fails. Should namespace be src.hello in hello.clj? |
| 12:38 | hyPiRion | wting: ugh, let me just find out what Leiningen does in a project :p |
| 12:39 | wting | I have lein installed if that's quicker |
| 12:39 | augustl | scottj: looking it up, thanks |
| 12:40 | hyPiRion | well, it's easier to make a project (`lein new app projectname`) and just use lein repl, then all classpaths and so forth are fixed for you |
| 12:41 | wting | hyPiRion: ahh ok, I see. I managed to compile the classes just fine, now I gotta figure out how to run them. :p |
| 12:42 | hyPiRion | I think that's the general consensus in the Clojuresphere. |
| 12:42 | hyPiRion | wting: Leiningen can take care of that too :) `lein run` runs the project, `lein uberjar` creates a standalone jar |
| 12:43 | hyPiRion | with uberjaring, the jar file lies within target/name-of-project-0.1.0-standalone.jar by default |
| 12:43 | hyPiRion | (run by `java -jar name-of-jar`) |
| 12:46 | jaley | making extensive use of the closure library from clojurescript is just asking for typos |
| 12:51 | pl6306 | I am processing a seq of strings. Is there something like a take while? So I can create maps after the first instance of say "--------------------------"? |
| 12:53 | hyPiRion | ,(take-while #(not= "---" %) ["a" "b" "hey" "---" "Not" "used"]) ; ? |
| 12:53 | clojurebot | ("a" "b" "hey") |
| 12:54 | pl6306 | How about if only want the tail of the seq? |
| 12:54 | jaley | pl6306: drop-while? |
| 12:54 | pl6306 | thanks |
| 12:54 | hyPiRion | yeah, (rest (drop-while instead |
| 12:55 | bbloom | ibdknox: i see you forked fipp. anything interesting in mind? (also, if you're using it, you should update as there was a major bug fix thanks to octagon) |
| 13:05 | wting | hyPiRion: managed to compile and run the jar, thanks! |
| 13:05 | tieTYT | http://stackoverflow.com/questions/15747774/whats-the-point-of-defining-something-as-dynamic-when-you-dont-need-to-define |
| 13:08 | hyPiRion | wting: you're welcome, enjoy :) |
| 13:10 | gfredericks | tieTYT: binding is thread-local, and with-redefs is not; thus the latter is not generally thread-safe |
| 13:11 | tieTYT | does that mean that with-redefs will have an affect outside of its scope if another thread tries to run the function? |
| 13:12 | finishingmove | hey guys, how would i do something like (int 2.6) but to get 3 instead of 2 ? (round up) |
| 13:14 | hyPiRion | ,(int (Math/round 2.6)) |
| 13:14 | clojurebot | 3 |
| 13:14 | joegallo | tieTYT: yes, it's a global thing, often useful for tests, probably not useful for normal code |
| 13:15 | joegallo | ,(int (Math/round 2.1)) ;; though |
| 13:15 | clojurebot | 2 |
| 13:15 | finishingmove | thanks guys |
| 13:15 | joegallo | ,(int (Math/ceil 2.1)) ;; perhaps you want this |
| 13:15 | clojurebot | 3 |
| 13:15 | finishingmove | hm |
| 13:16 | finishingmove | so i guess there's a Math/floor too :) |
| 13:16 | joegallo | aye |
| 13:16 | tieTYT | ok but if you're single threaded, then the redef only occurs in the lexical scope of the with-redefs, right? |
| 13:16 | hyPiRion | yup |
| 13:16 | tieTYT | ok |
| 13:16 | joegallo | tieTYT: sure... |
| 13:16 | technomancy | tieTYT: no, with-redefs has dynamic extent |
| 13:16 | finishingmove | newbie question, but can i somehow add a 'use' statement somewhere and not have to write "Math/ ..." explicitly? |
| 13:17 | tieTYT | technomancy: i understand it redefines in a dynamic way |
| 13:17 | tieTYT | but once the scope of the with-redefs exits, the function goes back the way it was defined, right? |
| 13:17 | technomancy | yes |
| 13:18 | technomancy | (which is not how lexical scope works) |
| 13:18 | tieTYT | right |
| 13:18 | hyPiRion | tieTYT: I think you flipped dynamic and lexical |
| 13:19 | tieTYT | what I was saying is that if the with-redefs is nested, its redef only takes effect under its scope and not outside of it |
| 13:19 | tieTYT | just like how if you nest a let, those symbols only have those values under the let's scope |
| 13:20 | technomancy | no, let is different |
| 13:20 | technomancy | it doesn't extend inside the calls in the let body |
| 13:20 | tieTYT | i understand |
| 13:20 | tieTYT | i'm not talking about the functionality, i'm talking about the scope of their effect |
| 13:20 | hyPiRion | finishingmove: I don't think there is, actually. |
| 13:20 | tieTYT | anyway I think I get it :) |
| 13:21 | finishingmove | hyPiRion hm... maybe some 3rd party support? |
| 13:22 | hyPiRion | finishingmove: there was this thing called import-static, but I don't think it has been updated since Clojure 1.2 |
| 13:24 | hyPiRion | you could always try it out though |
| 13:27 | TimMc | finishingmove: May I offer a compromise? (.importClass *ns* 'M Math) then (M/abs -3) |
| 13:27 | finishingmove | TimMc yes that looks neat |
| 13:30 | Raynes | Sigh. |
| 13:30 | Raynes | Looks like Charles Nutter is trying to 'fix' Lisp syntax as well. |
| 13:31 | technomancy | Raynes: I loled until I saw the "not an april fools joke" message at the top =\ |
| 13:31 | Raynes | technomancy: Yeah, I'm arguing with him and he is being very trollish. |
| 13:32 | tomoj | where's this? |
| 13:32 | technomancy | he should know better, but yeah... nothing to be done |
| 13:32 | Raynes | Twitter, tomoj. |
| 13:34 | technomancy | Raynes: I linked to his gist on the lein-xml announcement though =D |
| 13:34 | callenbot | Raynes: dude implements a slow Ruby implementation (original, yes?) and now he has something to teach everybody :P |
| 13:35 | technomancy | "a slow Ruby implementation" is there another kind? |
| 13:35 | technomancy | JRuby's fast for a ruby though |
| 13:35 | callenbot | kinda-sorta-not-really. |
| 13:36 | callenbot | technomancy: MacRuby and Rubinius are neat. |
| 13:36 | bbloom | technomancy: yes, but they aren't really rubies so much as they are ruby look alikes :-P |
| 13:36 | bbloom | MacRuby is just objective C with ruby syntax & statically resolved metaprogramming, which, to be fair, is a huge step up from no meta programming |
| 13:37 | callenbot | well I like Elixir too. |
| 13:37 | Raynes | technomancy: I just hate it when I respect people and then they do things like that and it smells so much like trolling that I'm baited in and I have to make them hate me with logic. |
| 13:38 | callenbot | Raynes: can you link what he's doing? |
| 13:38 | tomoj | https://gist.github.com/headius/5285216 |
| 13:39 | callenbot | sigh. |
| 13:39 | amalloy | wait, Raynes, if it smells like trolling that should do the opposite of bait you in |
| 13:40 | callenbot | nobody that actually writes Lisp, cares. |
| 13:40 | callenbot | this is a stupid gist. |
| 13:40 | tomoj | doesn't his "Immutable data structure example" call the data structures with no arguments? |
| 13:41 | tomoj | I guess he thinks functions are these special things and you always know whether a symbol resolves to a function |
| 13:41 | bbloom | tomoj: yeah, that's the main problem with these indentation based approaches. they assume static type knowledge |
| 13:41 | Raynes | callenbot: https://twitter.com/headius/status/318780382348726272 |
| 13:42 | Raynes | This is part oft he thread. |
| 13:42 | Raynes | But there is a lot more spread out. |
| 13:42 | Raynes | Look at my or his twitter stream for more bitching. |
| 13:42 | callenbot | okay, so I admire Erlang |
| 13:42 | callenbot | but I don't swoop into their community claiming to be able to solve what I think are their "problems" |
| 13:42 | callenbot | why is he doing that to us? |
| 13:43 | Raynes | Because he can. |
| 13:43 | Raynes | And he really thinks he is right. |
| 13:44 | callenbot | Raynes: must not work with macros on the regular. |
| 13:44 | Raynes | I'm more concerned that 5 people have told him he is utterly wrong and he just keeps repeating the same pointless things. |
| 13:44 | Raynes | Make that 6. |
| 13:44 | Raynes | People are still hopping in to tell him he is wrong. |
| 13:44 | callenbot | my mental bucket that says, "Ruby programmers are shallow" just had a few pebbles chucked into it. |
| 13:44 | callenbot | technomancy: sorry! |
| 13:44 | true_droid | hey guys. I'm not very proficient with Clojure, but I'd like to find out how exactly existing Clojure collections reduce themselves with a given reducer |
| 13:45 | true_droid | could someone point out places in Clojure source where to look? |
| 13:45 | Raynes | I don't think it has anything to do with what community he is from. It's more that he just hasn't even used Clojure and has decided it is broken and he is the messiah who can fix it. |
| 13:45 | bbloom | true_droid: grep for coll-reduce |
| 13:45 | technomancy | callenbot: more like "being good at compilers doesn't mean you won't suck at issues of crossing community divides" maybe? |
| 13:46 | true_droid | bbloom: thanks |
| 13:46 | callenbot | technomancy: I'll go with that, but usually people that have tackled seriously large projects are more humble. |
| 13:46 | technomancy | callenbot: I'm a bit sympathetic because the enormous amounts of shit he gets from ruby people who are like "eww yuck java" when they read about jruby |
| 13:47 | bbloom | i'm once again struck by how forcefully cond resists being formatted cleanly in ANY syntax/notation |
| 13:47 | callenbot | technomancy: if you need jruby's concurrency mechanisms, then you shouldn't be using Ruby anyway :P |
| 13:48 | amalloy | bbloom: i have a cute trick for that, if you like |
| 13:48 | technomancy | callenbot: not always an option. but anyway, this gist is stupid; no argument. |
| 13:48 | bbloom | amalloy: oh? |
| 13:48 | technomancy | and yeah, cond is super annoying |
| 13:48 | amalloy | the biggest problem is when the conditions are long enough that you need to wrap the then-clauses onto the next line, right? |
| 13:49 | bbloom | *shrug* when that happens i tend to just indent all of the then-clauses |
| 13:49 | amalloy | so you indent the then-clause with two commas, and emacs doesn't know it can delete them to "fix" your indentation |
| 13:49 | bbloom | amalloy: hmm interesting heh |
| 13:49 | bbloom | i don't use emacs, so i don't fight with the indenter nearly as much |
| 13:50 | hyPiRion | Well, that's a limitation to clojure-mode though. I wouldn't be surprised if that can be fixed. |
| 13:50 | jcromartie | I didn't know people were so hung up on parens |
| 13:50 | jcromartie | on both sides |
| 13:50 | bbloom | jcromartie: it's just alien to people |
| 13:50 | amalloy | hyPiRion: it probably can, but nobody will. the indenter is hard to understand, and if it special-cases cond then your enhanced-cond macro will still be just as bad |
| 13:52 | hyPiRion | I'm not surprised. |
| 13:52 | technomancy | every time I have to write a cond where the body clauses need their own line it just makes me think I should be using core.match |
| 13:52 | bbloom | technomancy: but matching has a similar problem. the issue is more generally: 2D structures are hard to work with in text |
| 13:52 | TimMc | technomancy: core.match is still woefully undercooked. |
| 13:53 | bbloom | pattern matching adds some extra brackets and syntax that aleivates the problem :-P |
| 13:53 | bbloom | alleviates* sheesh i can't spell and or type |
| 13:53 | technomancy | TimMc: yeah, we played with it at seajure and came to that conclusion |
| 13:53 | technomancy | kind of bums me out that it's not under active development any more |
| 13:54 | bbloom | technomancy: on a totally random side note. have you ever seen jonathan edwards schematic tables? |
| 13:54 | bbloom | super cool. |
| 13:54 | technomancy | bbloom: I think I saw some of that at his emerginglangs talk? |
| 13:54 | technomancy | that was like 2009 though so I'm a bit fuzzy |
| 13:54 | bbloom | technomancy: http://subtextual.org/subtext2.html |
| 13:55 | bbloom | technomancy: it's obviously just research/experimentation, but damn it's a cool demo |
| 13:55 | technomancy | flash =( |
| 13:56 | bbloom | *shrug* you have no way to view flash at all? |
| 13:56 | technomancy | I could get my wife's computer I guess? |
| 13:56 | bbloom | lol |
| 13:56 | bbloom | ok, well if you ever get 40ish minutes to watch it, i recommend it |
| 13:56 | bbloom | it's a really cool demo |
| 13:57 | technomancy | IIRC his emerginglangs talk was pretty FRP-heavy? |
| 13:57 | bbloom | didn't see it |
| 13:57 | bbloom | this is an older demo about his idea of a GUI for visualizing decision trees & data flow |
| 13:57 | callenbot | Stuff like FRP makes functional programming look bad to the muggles, IMHO. |
| 13:57 | technomancy | I get the feeling if I try to find it I'll find a bunch of fire-and-brimstone 18th-century sermons |
| 13:58 | ztellman | callenbot: how so? |
| 13:58 | callenbot | ztellman: making things they thought they already understood more complicated. |
| 13:58 | amalloy | callenbot: doesn't all of FP do that? |
| 13:58 | callenbot | ztellman: speaking from what I saw of it in Haskell, anyway. |
| 13:59 | amalloy | "gosh dang, i already understand loops, why is this reduce stuff so friggin complicated" |
| 13:59 | technomancy | the FRP presentations I've seen aren't like that at all |
| 13:59 | callenbot | the lengths one had to go to to simply make a game was obscene. |
| 13:59 | technomancy | elm and Edwards' stuff |
| 13:59 | ztellman | callenbot: it's basically just the same conversation as callbacks vs promises, maybe you've just seen needlessly opaque presentations |
| 13:59 | bbloom | part of the problem with functional programming is that it makes complexity more apparent |
| 14:00 | bbloom | it seems harder b/c it IS harder than it seemed before :-P |
| 14:00 | bbloom | however, it's just as hard both ways lol |
| 14:00 | callenbot | ztellman: I don't really have a problem with it |
| 14:00 | seancorfield | that sounds like a positive, not a problem, bbloom |
| 14:00 | callenbot | ztellman: I have a problem with the impression it makes. |
| 14:00 | bbloom | seancorfield: you're right. let me qualify: the ADOPTION problem |
| 14:00 | ztellman | callenbot: write a letter to your haskell congressman, I dunno |
| 14:01 | callenbot | ztellman: I don't think anybody had serious trouble understanding promises |
| 14:01 | callenbot | and promises offer a simplification of code that I think most can grasp. |
| 14:01 | callenbot | I'm not sure the same is the case with FRP unless you've been deep down in the tarpit. |
| 14:01 | ztellman | callenbot: honestly, promises are only a hop, skip, and a jump away from FRP |
| 14:02 | bbloom | callenbot: 90% of the time, people just want to immediately resolve a promise, but lack of lightweight threads makes that a problem |
| 14:02 | ztellman | not in terms of complexity, I mean, but in terms of actual underlying concept |
| 14:03 | callenbot | ztellman: well if you put up a talk demonstrating as much, you'll probably solve some of the marketing problems. |
| 14:03 | callenbot | ztellman: again, this might be a Haskell thing, but writing games with FRP was, "lets write a thesis!", not, "lets write a game!" |
| 14:04 | ztellman | callenbot: oh, in academia FRP is a big wanky black hole |
| 14:04 | bbloom | ztellman: you can say that again. |
| 14:04 | hyPiRion | callenbot: It's all the formal words, I think |
| 14:05 | hyPiRion | monoid? catamorphism? zygohistomorphic prepromorphism? |
| 14:05 | hyPiRion | It frightens people. |
| 14:05 | callenbot | I was speaking of the code. |
| 14:06 | callenbot | I don't pay any attention to category theory. |
| 14:06 | bbloom | hyPiRion: i think it's different than frightening people. i think it's actually a cognitive burden to have such big words |
| 14:06 | gfredericks | monoid is six characters |
| 14:06 | gfredericks | monad is even shorter |
| 14:07 | bbloom | monoids are quite easy to understand :-P monads have a different problem |
| 14:07 | gfredericks | maybe we should rename monads something longer and scarier so people will stop being improperly interested |
| 14:07 | bbloom | lol |
| 14:08 | gfredericks | endofunctorial-monoid maybe |
| 14:08 | gfredericks | (EFM) |
| 14:08 | bbloom | it's like the word "blog" |
| 14:09 | bbloom | there were news sites and personal home pages with regular updates long before the word "blog" |
| 14:09 | hyPiRion | Maybe we should just enterprisify it |
| 14:09 | bbloom | if you had called it a "automatic personal news publishing home page" it would have never caught on lol |
| 14:09 | hyPiRion | ConnectionListenerMonoid |
| 14:09 | hyPiRion | There we go, now we can ship it. |
| 14:10 | ztellman | btw, since some people here have been down the FRP rabbit hole |
| 14:10 | ztellman | anyone aware of something that deals with how FRP interacts with TCP backpressure? |
| 14:10 | ztellman | I've searched in vain |
| 14:11 | bbloom | ztellman: huh? |
| 14:11 | ztellman | bbloom: FRP in a server context |
| 14:11 | amalloy | ztellman: the connection between those is hard to see, even knowing that you must mean in aleph/lamina. what's a more specific part of the problem? |
| 14:12 | ztellman | so I was looking at all the various versions of Rx |
| 14:13 | ztellman | it's not clear to me if there's a story for when you can't reach the end of the FRP chain synchronously |
| 14:13 | ztellman | i.e. there's a queue, or pending write over the network, etc. |
| 14:14 | ztellman | the main problem here is that I'm not even sure what the right terminology here is, as maybe evidenced by my question |
| 14:14 | ztellman | bbloom, amalloy does that make any more sense? |
| 14:14 | bbloom | ztellman: i know of many of the words & technologies you're talking about, but i have no clue what you're asking.... |
| 14:14 | bbloom | ztellman: rewind and simplify |
| 14:15 | bbloom | ztellman: or maybe provide a concrete example |
| 14:16 | amalloy | i think so, but i'm definitely not qualified to answer it myself |
| 14:16 | ztellman | sure, trying to figure out the best way to unwind this |
| 14:16 | ztellman | ok, simplest example: |
| 14:16 | ztellman | you're a proxy between two different computers |
| 14:16 | ztellman | you're taking messages from one, doing some sort of transformation, and forwarding it to the other |
| 14:17 | ztellman | in general, these messages can be considered in isolation |
| 14:18 | ztellman | but if the bandwidth of the producer outstrips the consumer, you start to run out of memory as the messages back up |
| 14:18 | callenbot | ztellman: wouldn't backpressure throttling mean the promises block longer? |
| 14:18 | bbloom | ztellman: aaah ok, i now think i get what you're asking |
| 14:18 | ztellman | callenbot: promises representing what, exactly? |
| 14:19 | callenbot | deliverable result of some sort. |
| 14:19 | ztellman | bbloom: my reading of FRP is that each value propagation is calculated in isolation |
| 14:19 | augustl | hmm, is it true that the routing module is what adds a "href" attribute to all "a" tags? |
| 14:19 | augustl | err, wrong channel |
| 14:19 | bbloom | ztellman: so FRP is a totally overloaded and completely useless acronym |
| 14:19 | ztellman | haha, ok |
| 14:19 | bbloom | ztellman: in this case, you're talking about Push Streams |
| 14:19 | bbloom | push sequences |
| 14:19 | bbloom | microsoft's Rx |
| 14:19 | bbloom | etc |
| 14:19 | ztellman | correct |
| 14:20 | bbloom | what FRP originally meant and is most commonly discussed in the literature as is for dataflow systems basically |
| 14:20 | ztellman | so to greatly simplify my question: what happens with push streams when there's no more room to push? |
| 14:20 | bbloom | let's ignore ALL that and talk about push sequences |
| 14:21 | bbloom | ztellman: so yeah, this is a distributed systems problem |
| 14:21 | bbloom | you have to choose a policy |
| 14:21 | bbloom | block the sender (how?), drop messages (which?), etc |
| 14:21 | bbloom | push sequences are fundamentally no different than sockets in their design space |
| 14:22 | ztellman | sockets in the generic sense? |
| 14:22 | bbloom | yeah, like unix sockets, but more similar to zeromq sockets or message passing sockets |
| 14:22 | bbloom | one problem IMO with Rx is that the pipeline is opaque |
| 14:22 | ztellman | yes, agreed |
| 14:23 | bbloom | you can't look inside each phase of the transformation & modify it |
| 14:23 | bbloom | which is a problem w/ functions too, but it's not as big a problem cus functions rarely have internal state |
| 14:23 | bbloom | if you add an atom to cache stuff in your function, then suddenly your function is harder to work with, debug, etc |
| 14:24 | bbloom | push sequences inherently have some state/context and you can't see that easily |
| 14:24 | bbloom | one school of thought is that you don't NEED to see it |
| 14:24 | bbloom | that's the zeromq way |
| 14:24 | bbloom | i highly recommend reading http://zguide.zeromq.org/page:all |
| 14:25 | bbloom | it's long, but it has some reeeaaaally good explanations about common patterns for robust distributed communication designs |
| 14:25 | ztellman | I read it a ways back |
| 14:25 | ztellman | but i'll take another look, thanks |
| 14:25 | borkdude | just checkin, this should be safe? db.config just contains a map with some settings (clojure.edn/read-string (slurp "resources/db.config")) |
| 14:26 | ztellman | specifically w.r.t. the policies you mentioned above, though |
| 14:26 | ztellman | is there a first-class representation of that in Rx? |
| 14:26 | amalloy | borkdude: yes, that cannot execute any code as far as i know |
| 14:26 | bbloom | i dunno |
| 14:26 | bbloom | zero mq has different types of sockets & the pairing of sockets dictates policy for things |
| 14:27 | ztellman | ok, cool |
| 14:27 | ztellman | I'm looking for prior art in that space, I think I glossed over that part of it before |
| 14:27 | ztellman | in zmq, that is |
| 14:27 | bbloom | in theory, you could create Rx components that essentially map to the buffering and blocking policies of zeromq |
| 14:28 | bbloom | the tables on this page summarize: http://api.zeromq.org/3-2:zmq-socket |
| 14:29 | ztellman | perfect, thank you |
| 14:30 | ztellman | on a tangential note, could you characterize the difference between push sequences and standard dataflow? |
| 14:30 | ztellman | I think I've gotten them conflated in my head |
| 14:31 | bbloom | push sequences have a linear notion of time, dataflow as an instantaneous notion |
| 14:31 | jcromartie | any reason to use (Double. x) over (Double/parseDouble x) ? |
| 14:31 | technomancy | jcromartie: I think the former accepts things that are already doubles? |
| 14:31 | technomancy | at least for Integer that's how it works |
| 14:32 | bbloom | ztellman: FRP dataflow systems tend to have concepts like signals, behaviors, etc. push sequences basically have subscribe/unsubscribe/push |
| 14:32 | bbloom | ztellman: it's sorta like comparing lazy seqs to lazy evaluation |
| 14:32 | bbloom | only it's push seqs to push evaluation |
| 14:33 | ztellman | bbloom: ok, so behaviors vs streams |
| 14:33 | bbloom | i guess so |
| 14:33 | bbloom | like i said, FRP is an overloaded and muddled term |
| 14:33 | ztellman | and I've read a small subset of the literature, so I'm just trying to line things up to terminology I've already heard |
| 14:33 | TimMc | ~frp |
| 14:33 | clojurebot | FRP is Functional Reactive Programming, or maybe fiberglass reinforced plastic (and sometimes Functional *Relational* Programming, just to be confusing) |
| 14:33 | tomoj | a coworker decided he needed to make sure the internet (which was working) was going to work, so decided to fuck with the router. during an FRP discussion :( |
| 14:34 | ztellman | bbloom: anyway, thanks |
| 14:34 | TimMc | tomoj: We solved the whole thing. Sorry you missed it! |
| 14:34 | tomoj | the jonathan edwards stuff was "coherent reaction"? |
| 14:35 | true_droid | can one add fields to a record in runtime? |
| 14:35 | bbloom | ztellman: yeah, my pleasure. i hadn't made the zeromq analogy explicit in my head yet, so that was helpful to me too |
| 14:36 | TimMc | true_droid: Basis fields? Probably not. |
| 14:36 | true_droid | (assoc rec :newfield value) |
| 14:36 | tomoj | subscribe/unsubscribe/push seems like an unsound basis for push seqs to me |
| 14:36 | jcromartie | is there anything that does (f m {:foo g}) => {:foo (g (get m :foo))} |
| 14:36 | bbloom | tomoj: sure, i was far oversimplifying |
| 14:37 | bbloom | tomoj: also, i really dislike the suscribe/unsubscribe thing in general, since it introduces a resource management concern |
| 14:37 | hyPiRion | jcromartie: update-in |
| 14:37 | ztellman | bbloom: what's the alternative? |
| 14:37 | hyPiRion | ,(update-in {:foo 1} [:foo] inc) |
| 14:37 | clojurebot | {:foo 2} |
| 14:37 | TimMc | true_droid: Sure. Try it. |
| 14:38 | bbloom | ztellman: i don't have a good one honestly. but it would look a lot more like the -> macro :-P |
| 14:38 | bbloom | ztellman: so check out this file https://github.com/brandonbloom/fipp/blob/master/src/bbloom/fipp/transduce.clj |
| 14:38 | true_droid | TimMc: I'm curious how it works. If a record definition generates a Java class. Does associating new field creates a new subclass for it? |
| 14:38 | bbloom | ztellman: i'm basically leveraging the eagerness of reducers to emulate push sequences |
| 14:39 | ztellman | bbloom: transduce can't actually be a real verb, can it? |
| 14:39 | bbloom | map-state and mapcat-state enable reducers to have state |
| 14:39 | jcromartie | hyPiRion: no, I mean more like, {:foo 1 :bar "2"} {:foo str :bar #(Integer/parseInt %)} => {:foo "1" :bar 2} |
| 14:39 | bbloom | $define transduce |
| 14:39 | amalloy | $dict transduce |
| 14:39 | lazybot | amalloy: verb-transitive: To convert (energy) from one form to another. |
| 14:39 | bbloom | eh, lol |
| 14:39 | bbloom | anyway |
| 14:39 | bbloom | ztellman: the interesting bit is the state |
| 14:40 | bbloom | it's encapsulated in that atom |
| 14:40 | bbloom | but there isn't really an easy way to peek at it, which is problematic |
| 14:40 | TimMc | true_droid: It handles the basis keys specially and stores all the other key-val pairs in a regular map. |
| 14:40 | bbloom | ztellman: but look here: https://github.com/brandonbloom/fipp/blob/master/src/bbloom/fipp/printer.clj#L203-L208 you'll see how i stitch together the pipeline |
| 14:40 | true_droid | TimMc: I see, thanks! |
| 14:40 | hyPiRion | jcromartie: oh |
| 14:40 | bbloom | ztellman: it's brain dead simple lazyness, but the t/each sucks out of the pull sequence & then starts pushing into the reducers |
| 14:41 | bbloom | ztellman: this is a dramatically simplified example b/c the push source is actually a pull source |
| 14:41 | bbloom | i'm pushing to the console, but i'm pulling lazily from a document |
| 14:41 | ztellman | bbloom: right |
| 14:41 | bbloom | when you have a real push source, things get messy. |
| 14:41 | amalloy | jcromartie: if you're interested in a little type theory, then that's the basic operation of an applicative functor |
| 14:41 | hyPiRion | ,(merge-with #(%2 %) {:foo 1 :bar "2"} {:foo str :bar #(Integer/parseInt %)}) |
| 14:41 | clojurebot | {:foo "1", :bar 2} |
| 14:42 | hyPiRion | But that's not exactly what you want, really. |
| 14:42 | ztellman | bbloom: my domain here is (broadly) network programming |
| 14:42 | amalloy | hyPiRion: it sure is clever, though |
| 14:42 | bbloom | ztellman: yeah, so i guess the idea that strikes me is that you don't have a resource management problem until you hook up your Rx chain to the source |
| 14:42 | ztellman | which means that data sources and sinks appear and disappear all the time |
| 14:43 | bbloom | if you define a chain inductively, you have to attach to the source immediately |
| 14:43 | jcromartie | amalloy: interesting |
| 14:43 | ztellman | bbloom: that assumes the chain's topology is not dependent on the messages themselves |
| 14:43 | hyPiRion | jcromartie: You could probably use reduce-kv here actually |
| 14:43 | jcromartie | hyPiRion: yeah, that's closer, I am just not sure if it already exists :P yeah |
| 14:43 | ztellman | or on other resources which you don't have control over, like client connections |
| 14:44 | ztellman | I think that trying to avoid the resource management problem narrows the useful domain pretty drastically |
| 14:44 | tieTYT | oh man: (-> req :params :length) |
| 14:44 | bbloom | ztellman: if i were to take a design crack at this, i'd ban state inside each stage of the push sequence, but give those states an ID |
| 14:44 | tieTYT | I like that better than get-in |
| 14:44 | bbloom | ztellman: i'd also ban connecting to a source or sink until the end |
| 14:44 | bbloom | and then the sources, sinks, and state would live OUTSIDE the chain |
| 14:44 | hyPiRion | ,(reduce-kv (fn [m k v] (if (m k) (update-in m [k] v) m)) {:foo 1 :bar "2"} {:foo str :bar #(Integer/parseInt %)}) ; jcromartie |
| 14:44 | clojurebot | {:foo "1", :bar 2} |
| 14:44 | tieTYT | i remember when I learned get-in, I didn't know what -> was, but nwo that I do, I think using it is easier to read |
| 14:45 | hyPiRion | It was way prettier when I thought it out in my head though. |
| 14:45 | jcromartie | :) |
| 14:45 | jcromartie | I'd say that's pretty close, technically I want to throw out keys missing from the key-fn map |
| 14:45 | bbloom | ztellman: i'll be back in a bit |
| 14:45 | ztellman | bbloom: ok, I've got a question relating to that design |
| 14:46 | ztellman | but it can wait |
| 14:46 | hyPiRion | jcromartie: so a select-keys before or after |
| 14:46 | hyPiRion | do* |
| 14:49 | borkdude | in a clojure project, a .clj is not loaded until needed… right? |
| 14:49 | technomancy | borkdude: user.clj is the only thing loaded implicitly |
| 14:50 | borkdude | I mean, is it safe to put a lobos script somewhere, without the risk it being run, when no other namespaces refers it? |
| 14:50 | technomancy | borkdude: `lein compile :all` could trigger it |
| 14:50 | technomancy | don't put side-effects in the top-level |
| 14:51 | gfredericks | &foo should be a naming convention for anaphoric macros |
| 14:51 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: foo in this context |
| 14:51 | borkdude | technomancy if I define some actions as functions, that would save me then |
| 14:51 | gfredericks | or for the locals they introduce rather |
| 14:51 | technomancy | borkdude: right |
| 14:51 | amalloy | gfredericks: that's an interesting proposal. i'm surprised to find i don't immediately hate it |
| 14:51 | gfredericks | amalloy: lol |
| 14:52 | technomancy | if lobos doesn't already tell you to put your changes in defns then that's worrisome |
| 14:52 | gfredericks | it came to me earlier when the fellah wanted an arguments map |
| 14:52 | Raynes | amalloy: April fools. |
| 14:52 | hyPiRion | Raynes: I was about to write that too |
| 14:52 | technomancy | gfredericks: I saw some anaphoric elisp macros that I totally didn't hate, but I think that was because elisp's lambdas are more verbose |
| 14:53 | gfredericks | someone told me elisp doesn't have closures |
| 14:53 | hyPiRion | technomancy: lambda-as-lambdas? |
| 14:53 | technomancy | gfredericks: it didn't until like two years ago? |
| 14:53 | amalloy | technomancy: has it really been two years? |
| 14:53 | borkdude | gfredericks there is a setting that you must have at the top of an elisp file to turn lexical closures on |
| 14:53 | gfredericks | technomancy: at least it beat java? |
| 14:54 | technomancy | amalloy: not sure; I've been running trunk for so long |
| 14:54 | technomancy | gfredericks: ziiiiiiing! |
| 14:54 | hyPiRion | gfredericks: What are you saying, you have Clojure |
| 14:54 | hyPiRion | JVM got it, that's enough for me |
| 14:54 | borkdude | technomancy it tells me to do that, but to activate the changes, I want to have some reference script for when I need to execute the db creation in the future or with other dbs |
| 14:57 | hyPiRion | borkdude: it's probably safer to leave it out of your clj and java source paths |
| 15:04 | bbloom | ztellman: i haven't thought deeply about that design, so i offer nothing more than a willingness to think through it with you :-P |
| 15:05 | ztellman | bbloom: understood |
| 15:05 | ztellman | it's interesting, though, that your design is actually pretty 1:1 with how riemann is implemented, as I understand it |
| 15:05 | bbloom | haven't seen riemann. googled it. by aphyr on github? |
| 15:06 | ztellman | correct |
| 15:06 | ztellman | http://riemann.io/ |
| 15:06 | bbloom | looking at it now |
| 15:06 | ztellman | he's a coworker, we've had a few design discussions along these lines |
| 15:07 | bbloom | the interesting thing is that once you hook up to a source, you've got a resource management problem |
| 15:07 | ztellman | in this case, everything flows through the same topology, so it's just a question of how many sources are feeding into the same thing |
| 15:07 | ztellman | it's a constrained use-case, so I'm not sure what works there would work elsewhere |
| 15:08 | ztellman | the question I wanted to ask had to do with something I have in lamina, though |
| 15:08 | ztellman | basically, it does split-apply-combine on streams of data |
| 15:09 | ztellman | so every time a message comes in with a new facet, a whole new chain of transforms is built on the spot |
| 15:10 | ztellman | I've spent a lot of effort on making the topology dynamic, thread-safe, able to do its own resource management, etc. |
| 15:10 | ztellman | a question I sometimes explore is whether that was strictly necessary |
| 15:10 | bbloom | ztellman: does the topology itself really need to be dynamic? or can there be a static node w/ a dynamic subtopology? |
| 15:10 | ztellman | bbloom: in this case, the latter would probably suffice |
| 15:10 | bbloom | ie can i have source->transform->sink and then transform has some state which is a subtransform |
| 15:11 | bbloom | yeah, i'd probably go with that :-P |
| 15:11 | ztellman | fair enough |
| 15:11 | bbloom | your state then just gets stored in a tree & you have a transform node that acts as a state machine which switches the underlying topology |
| 15:12 | bbloom | analogous in some way to defunctionalization :-) |
| 15:12 | bbloom | you have a higher order transform & you can realize it as a non-higher order one by inlining |
| 15:14 | ztellman | yeah, predefined chains of transforms can be useful |
| 15:14 | ztellman | I've got some stuff which will split apart chains into distributable and non-distributable pieces, so you can process streams across multiple processes |
| 15:14 | bbloom | in theory, you can just make the root transform always be such a dynamic transform |
| 15:15 | bbloom | so then you just always store the topology itself in the state atom |
| 15:16 | bbloom | which i guess is what is happening with function composition. you're storing the topology in the Fn objects |
| 15:16 | ztellman | bbloom: yeah, but that's not introspectable in any sane way |
| 15:16 | bbloom | agreed |
| 15:16 | ztellman | have a first-class representation of the topology is really useful |
| 15:16 | bbloom | sure, and by the same token, i really wish i could introspect functions lol |
| 15:17 | ztellman | I wish I could introspect on how lazy-seqs are consumed, so I can tell if someone's holding onto the head |
| 15:17 | bbloom | the nice thing about function composition is that you get an evaluator for "free" |
| 15:18 | ztellman | I guess you could do something with weak refs, there, but I'm not masochistic enough to try |
| 15:18 | borkdude | argh, why does lobos want me to have the migrations in a namespace called lobos.migrations |
| 15:19 | tomoj | but do you want to say (i'm-consuming! some-lazy-seq) or whatever? |
| 15:19 | ztellman | tomoj: no, but if you have a topology representing where data's going, you don't need to |
| 15:19 | tomoj | but then you can't just do (first coll), right? |
| 15:19 | tomoj | or can you have it both ways |
| 15:20 | bbloom | ztellman: even the haskell folks have no idea what to do about space leaks: http://www.haskell.org/haskellwiki/Memory_leak#Detection_of_memory_leaks |
| 15:20 | ztellman | tomoj: not with immutable data structures, as far as I can tell |
| 15:21 | ztellman | if you forced each consumer to have its own queue, which it consumed at its own rate, you could tell how much data is "in flight" |
| 15:22 | tomoj | why is having a first-class topology representation valuable? not disagreeing, just curious about the details |
| 15:22 | tomoj | obviously those beautiful dot graphs are great |
| 15:22 | ztellman | tomoj: I just like pretty pictures :) |
| 15:22 | bbloom | tomoj: two things |
| 15:23 | ztellman | tomoj: one is that the code isn't necessarily a direct representation of what's happening to the data |
| 15:23 | bbloom | it gives you somewhere to extract local state to |
| 15:23 | bbloom | 2) it enables debugging, etc |
| 15:23 | bbloom | the topology EXISTS somewhere |
| 15:24 | bbloom | it has to be reified in some way at some level |
| 15:24 | bbloom | generally tho that level is just inside the functions as compiled |
| 15:24 | ztellman | bbloom: I defy you to infer the data topology of lazy-seqs via the object graph |
| 15:24 | bbloom | it's impossible |
| 15:24 | bbloom | lol |
| 15:24 | bbloom | but it exists |
| 15:24 | ztellman | oh, sure |
| 15:24 | bbloom | ok not impossible |
| 15:24 | tomoj | I was thinking the debugging benefit is primarily for operational issues |
| 15:24 | tomoj | like lazy seq realization |
| 15:24 | bbloom | but you'd have to decompile bytecode lol |
| 15:25 | bdesham | I have a web app running with ring and jetty. what's the best way to run the server as a background process (so that I can log out of my shell with it still running)? |
| 15:25 | ztellman | tomoj: one is that it lets you understand what your code actually describes |
| 15:25 | tomoj | but you wouldn't need a topology graph for code working with only, say, vectors? |
| 15:25 | ztellman | function composition over lazy seqs can happen all over the place |
| 15:25 | bbloom | if i had my way, everything would be introspectable at all times :-P |
| 15:25 | ztellman | the net effect of that composition is very difficult to infer |
| 15:25 | tomoj | or maybe it'd still be helpful |
| 15:26 | ztellman | tomoj, if there's only a small number of transforms, and one source, and one destination, it's maybe not all that useful |
| 15:26 | ztellman | because that can be described by a (->> s …) form |
| 15:26 | ztellman | but there are some issues there, too |
| 15:26 | tomoj | transform/source/destination seems to imply some operational trickiness |
| 15:27 | ztellman | tomoj: don't pay too much attention to my terminology |
| 15:27 | tomoj | ah, right, if source is a vector, destination is a vector, and transforms are just functions. still could be nice to get a graph I suppose.. |
| 15:28 | ztellman | tomoj: basically in the simple case it doesn't harm anything |
| 15:28 | ztellman | in the complex case, it's invaluable |
| 15:28 | bbloom | aside: Rx has this concept of schedulers that is worth studying too |
| 15:29 | ztellman | it also lets you solve the resource management problem bbloom was mentioning, to an extent |
| 15:29 | bbloom | in theory, some intermediate step in the sequence can autonomously decide to emit an event w/o input from an upstream source |
| 15:29 | ztellman | since you know whether there are any remaining consumers for any given subset |
| 15:29 | bbloom | but in deeper theory, that's just getting an event from another source: a timer |
| 15:30 | ztellman | bbloom: yeah, in lamina all nodes can emit messages at any time |
| 15:30 | ztellman | using pretty much the same mechanism you describe |
| 15:32 | ztellman | anyway, tomoj, in general adding introspection capability is something you should design for |
| 15:33 | bbloom | ztellman: note however that introspection often (not always) incurs substantial runtime costs |
| 15:33 | mabes | speaking of Rx... has anyone here played around with netflix's RxJava (https://github.com/Netflix/RxJava)? |
| 15:33 | bbloom | however it is much much much harder to design OPTIONAL introspection :-) |
| 15:33 | true_droid | anyone knows of alternative clojure implementations in the works? I've heard of pyclojure |
| 15:34 | true_droid | curious to know if there's anything else that fwould ree clojure from jvm |
| 15:34 | Raynes | Whoa |
| 15:34 | ztellman | bbloom: I think this particular domain is really friendly to introspection |
| 15:34 | Raynes | That f really ran off on you didn't it true_droid |
| 15:34 | true_droid | yeah |
| 15:34 | bbloom | ztellman: assuming you're writing server software & are likely IO bound, then yeah, for sure |
| 15:35 | ztellman | bbloom: I dunno, I've made a thread-safe dynamic topology that had to acquire locks, etc. and it take about 40ns per node |
| 15:35 | ztellman | when propagating |
| 15:35 | bbloom | how many nodes do you typically have? |
| 15:35 | ztellman | well, depends on the application |
| 15:36 | bbloom | 10, 100, 1000, 10000? |
| 15:36 | ztellman | the server I was describing at clojure/west had about 500k, but not every node gets every message |
| 15:36 | bbloom | that's a shitload of nodes lol |
| 15:36 | bbloom | i'm not even sure how i'd use that many nodes. is that like one per user? |
| 15:36 | ztellman | it's an extreme case, I was partially using it to stress test the mechanism |
| 15:37 | ztellman | nah, it's a streaming analysis of structured data |
| 15:37 | tgoossens | I'm looking at rich hickey's ant demo. https://gist.github.com/spacemanaki/1093917#file-ants-clj-L45 . What is the reasoning behind the following documentation of the "move" function: "moves the ant in the direction it is heading. Must be called in a |
| 15:37 | tgoossens | transaction that has verified the way is clear" |
| 15:37 | ztellman | hierarchical code timings |
| 15:37 | tgoossens | Why not put the transaction in there it if it has to be put in a transaction anyway ? |
| 15:37 | bbloom | oh right i saw your talk |
| 15:38 | bbloom | ztellman: so that's a distributed 500k nodes? or all in one process? or what? |
| 15:38 | nDuff | tgoossens: Because the check has to be inside the same transaction. |
| 15:38 | ztellman | so basically each timing is analyzed about half a dozen different ways, and within each it's getting quantiles, rolling sums, etc |
| 15:38 | ztellman | one server |
| 15:38 | tgoossens | nduff: makes sense! |
| 15:38 | ztellman | it's distributable, but in my use case it's not necessary |
| 15:38 | bbloom | ok got it |
| 15:38 | bbloom | that's a big number :-P |
| 15:38 | ztellman | they're lightweight nodes :) |
| 15:39 | tgoossens | nduff: stupid me. The documentation actually said that:p "Must be called in a |
| 15:39 | tgoossens | transaction that has verified the way is clear"" |
| 15:39 | ztellman | but yeah, I'm looking at a constrained query language that will be distributable via storm, or something |
| 15:39 | bbloom | neat |
| 15:39 | ztellman | it's got promise, I think |
| 15:40 | ztellman | I tried using it to measure a full map/reduce job without client-side sampling, got about 15gb/minute via UDP packets |
| 15:40 | ztellman | which have a maximum size of 64k, btw |
| 15:40 | ztellman | that made it fall over |
| 15:40 | tieTYT | how would you count the number of 0s in a vector? I used this: (reduce #(+ %1 (if (= %2 0) 1 0)) 0 vector) |
| 15:40 | ztellman | so there's definitely a threshold at which you want to distribute this sort of analysis |
| 15:40 | amalloy | (count (filter #{0} v)) |
| 15:41 | tieTYT | ah yeah that's better |
| 15:41 | tomoj | how do you represent a dynamic topology (for e.g. the purpose of rendering to dot)? |
| 15:41 | bbloom | amalloy: tieTYT: might prefer zero? |
| 15:41 | bbloom | (count (filter zero? v)) |
| 15:41 | ztellman | tomoj: check out lamina.walk |
| 15:41 | amalloy | bbloom: doubtful |
| 15:41 | bbloom | heh ok then |
| 15:41 | tieTYT | so there you used a set as a function? |
| 15:42 | ztellman | tomoj: though that's just some sugar on top of the underlying data structure, no mechanism for making sense of a topology of 500k nodes |
| 15:42 | amalloy | &(zero? []) |
| 15:42 | lazybot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number |
| 15:42 | pl6306 | What is an easy way of generating [[year quarter] ...] e.g. [[1993 1] [1993 2] [1993 3] [1993 4] [1994 1] [1994 2] ... ? |
| 15:42 | bbloom | amalloy: oh! wow. that's annoying |
| 15:43 | nDuff | pl6306: lazy? bounded? ...? |
| 15:43 | bbloom | surely the answer to that question is "false" lol |
| 15:43 | true_droid | what does reify return? can't find it mentioned in the reify doc string at all |
| 15:43 | nDuff | pl6306: ...well, if you really want it to be a vector on the outside, it can't be lazy... |
| 15:43 | pl6306 | not lazy bounded just from 1993 to 2013 |
| 15:43 | hyPiRion | ,(for [y (range 1993 2013) q (range 1 4)] [y q]) ;? |
| 15:43 | clojurebot | ([1993 1] [1993 2] [1993 3] [1994 1] [1994 2] ...) |
| 15:44 | amalloy | ,(map vector (mapcat #(repeat 4 %) (range 1993 2014)) (cycle [1 2 3 4])) |
| 15:44 | clojurebot | ([1993 1] [1993 2] [1993 3] [1993 4] [1994 1] ...) |
| 15:44 | amalloy | but hyPiRion's is better |
| 15:44 | pl6306 | Nice thanks! |
| 15:44 | pl6306 | Starting to get the hang of this. |
| 15:44 | tomoj | ztellman: is the 'dynamic' part represented in there? or do you just call node-data at various times to see what the topology looks like at different times? |
| 15:45 | ztellman | tomoj: oh, I see, yeah, you're just sampling it |
| 15:45 | hyPiRion | pl6306: might want to replace 2013 with 2014 in my code, if you meant "up to and including 2013" |
| 15:45 | ztellman | tomoj: you can hook into callbacks for when nodes close, etc. |
| 15:46 | ztellman | tomoj: if you want a fully consistent view you can recursively lock each node in the topology |
| 15:47 | ztellman | but by default you're not getting one, because the topology doesn't change atomically |
| 15:47 | ztellman | at the global level, anyway |
| 15:48 | borkdude | hmm, lobos uses an old version of java.jdbc (1.1) |
| 15:48 | borkdude | (0.1.1) |
| 15:49 | tieTYT | i think one of the hardest things for me to take advantage of from a java/haskell background is that I can use non-booleans in an if statement |
| 15:50 | tomoj | would it be wrong to call that a bit less than first-class? |
| 15:50 | tomoj | not really sure what 'first-class' means in this context |
| 15:50 | borkdude | tieTYT many dynamically typed languages have this, javascript, common lisp, etc |
| 15:50 | tomoj | though if that's less than first-class it may be impossible to do any better :(. damned 'dynamic' |
| 15:50 | ztellman | tomoj: it depends on what you're trying to do |
| 15:51 | tieTYT | borkdude: yeah, I don't usually use that feature though |
| 15:51 | borkdude | I guess C has it too? |
| 15:51 | tgoossens | Why was the name "agent" chosen for well.. clojure agents? |
| 15:51 | ztellman | one way to "sample" the topology is to send a message through it |
| 15:52 | ztellman | the return value of (enqueue ch …) will give you the return value of each endpoint, or an async-result representing the eventual return value |
| 15:52 | ztellman | but the topology may be changing around the message as it propagates |
| 15:52 | ztellman | especially if it's queued anywhere |
| 15:53 | ztellman | which topology matters? the one that was in place when the message was enqueued, or the one that's in place when it arrives at its various destinations? |
| 15:53 | Guest93639 | ok I am confused. I printed out the value of my protocol var, apparently the :impls has a bunch of identical-looking class keys with different values. how does that happen? https://www.refheap.com/paste/13179 |
| 15:53 | ztellman | or the frankenstein combination of the two that the message encountered as it was being propagated? |
| 15:54 | ztellman | though again, if you want some guarantees of atomicity, those are possible if you want to lock down the topology yourself |
| 15:54 | ztellman | I haven't encountered a production situation where that's useful, though |
| 15:55 | tieTYT | where/how can I find the documentation on using a set as a function? |
| 15:55 | tomoj | would be sweet though to make an animation of the topology changing while following a message |
| 15:55 | amalloy | jweiss_: you have redefined a defrecord or deftype multiple times at the repl |
| 15:55 | brehaut | tieTYT: clojure.org probably. (set key) is equivalient to (contains? set key) |
| 15:55 | amalloy | there are now multiple versions of that class, each with a registered implementation of the protocol |
| 15:55 | brehaut | almost equiv |
| 15:56 | jweiss_ | amalloy: strange since there is no way to tell them apart that i can see |
| 15:56 | amalloy | jweiss_: they have different classloaders |
| 15:57 | tieTYT | brehaut: ok |
| 15:57 | brehaut | tieTYT: http://clojure.org/data_structures#Data%20Structures-Sets |
| 15:57 | brehaut | tieTYT: very bottom |
| 15:57 | jweiss_ | amalloy: do you have a recommendation to avoid this and/or fix it? just blow away the protocol var and re-compile? |
| 15:57 | amalloy | jweiss_: i recommend not caring |
| 15:57 | ztellman | tomoj: feel free to mess around with it a bit if you're curious |
| 15:58 | amalloy | it will not cause any problems whatsoever |
| 15:58 | jweiss_ | amalloy: it seems to be causing problems. |
| 15:58 | ztellman | I'm probably going to extract the graphviz stuff into its own library |
| 15:58 | amalloy | jweiss_: really? what problems? |
| 15:58 | jweiss_ | i'm getting an error that one of my records doesn't implement one of the protocol methods. |
| 15:58 | tieTYT | thanks |
| 15:58 | ztellman | maybe you'll build up some opinions on how to best do that |
| 15:58 | jweiss_ | but it does, it's just choosing the wrong class |
| 15:58 | brehaut | tieTYT: contains? returns a bool, where as a set returns the object if its found. sets with nil or false can be funny if you use them for existence tests without using contains? |
| 15:59 | Raynes | brehaut: You. Hi. |
| 15:59 | brehaut | hi Raynes |
| 15:59 | amalloy | jweiss_: that happens if you re-evaluate the defprotocol form |
| 15:59 | tieTYT | i see |
| 15:59 | amalloy | you defined a new protocol with the same name, and the previously-existing records implement the old version, not the new one. if you re-evaluate the records, new classes will be produced that implement the new one |
| 15:59 | jweiss_ | amalloy: yeah, that's why i wanted to know how to avoid/fix - so i guess i shouldn't have recompiled the namespace with that defprotocol? |
| 16:00 | amalloy | jweiss_: make sure to let technomancy know: he enjoys protocol schadenfreude |
| 16:00 | jweiss_ | hm ok the defprotocol and defrecords are in the same ns, so i guess i should not eval forms, just recompile the whole ns. |
| 16:00 | Raynes | The shit. |
| 16:01 | Raynes | amalloy: That's the second time I've heard that word in two days. |
| 16:01 | Raynes | And yesterday was the first time I'd heard it in my life. |
| 16:01 | technomancy | amalloy: it's true |
| 16:01 | jweiss_ | schadenfreude? |
| 16:01 | amalloy | Raynes: http://www.damninteresting.com/the-baader-meinhof-phenomenon/ |
| 16:01 | Raynes | So either you're a callenbot copycat or that's a hell of a coincidence. |
| 16:02 | TimMc | ...or you're a young 'un. |
| 16:02 | amalloy | Raynes: it's a word, man. people using words you don't know is just a sign you're uneducated, not a sign from god |
| 16:03 | Raynes | Thanks guys. |
| 16:03 | TimMc | <3 |
| 16:04 | jweiss_ | oh man this sucks, why didn't anyone warn me about protocols |
| 16:04 | technomancy | I did! |
| 16:04 | amalloy | clojurebot: technomancy is <jweiss> oh man this sucks, why didn't anyone warn me about protocols |
| 16:04 | clojurebot | c'est bon! |
| 16:04 | technomancy | you just weren't listening |
| 16:05 | technomancy | in your defense, you might not have been on IRC at the time |
| 16:05 | jweiss_ | lol |
| 16:05 | jweiss_ | i don't suppose i can save my fellow co-workers by somehow defonce'ing something |
| 16:06 | jweiss_ | so that when they edit something else in this namespace they won't end up chasing their tail |
| 16:06 | TimMc | jweiss_: http://www.mspaintadventures.com/sweetbroandhellajeff/comoc.php?cid=001.jpg |
| 16:06 | pl6306 | Why does (map #(load-sec-quarterly-master-idx (first %1) (last %1)) (vec (for [y (range 1993 2012) q (range 1 4)] [y q]))) in the REPL? But (defn load-historical-master-idx (map #(load-sec-quarterly-master-idx (first %1) (last %1)) (vec (for [y (range 1993 2012) q (range 1 4)] [y q])))) throws an IllegalArgumentException Parameter declaration map |
| 16:06 | pl6306 | should be a vector clojure.core/assert-valid-fdecl? |
| 16:06 | jweiss_ | TimMc: lol |
| 16:07 | amalloy | pl6306: you forgot the args to defn |
| 16:07 | technomancy | TimMc: nice |
| 16:07 | pl6306 | ok so I should put in [] |
| 16:08 | amalloy | TimMc: what on earth |
| 16:08 | jweiss_ | i don't know which one is hella jeff, but probably the one falling down the stairs since my name is also jeff |
| 16:09 | jweiss_ | although the other guy does refer to him as "bro" so maybe not. |
| 16:12 | cdh473__ | i just noticed: ".../comoc.php..." |
| 16:18 | TimMc | amalloy: Intentionally bad webcomic. I think it started as a joke in the MS Paint Adventures forums. |
| 16:21 | jweiss_ | alright I am still baffled. when i recompile a namespace it seems like not everything gets redefined. i still have old versions of records still laying around. |
| 16:27 | TimMc | Yeah, they should have different classloaders. |
| 16:29 | jweiss_ | TimMc: should, or that's why i'm having problems? |
| 16:30 | TimMc | The latter. |
| 16:30 | TimMc | Not "this is a desirable scenario". |
| 16:33 | maacl | Considering a porting the GUI part of ants.clj to Clojurescript/canvas and back it by a Clojure backend. Would fetch (by Chris Granger) be my best choice for syncing the world from the backend to the frontend? |
| 16:35 | jweiss_ | TimMc: the repl seems to be telling me that both the protocol impl key and the new record i just created, have teh same classloader. and the impl also has a definition for the :product method. yet when i try to call it, it doesn't work |
| 16:35 | jweiss_ | https://www.refheap.com/paste/13184 |
| 16:36 | jweiss_ | i wonder if this has anything to do with using keywords as protocol method implementations? |
| 16:36 | jweiss_ | i mean, they are functions, so i figured that should be fine. |
| 16:36 | sandbags | clojure newb here, is there a legitimate reason why (load-file "path/to/file.clj") might hang for minutes at a time? |
| 16:36 | brehaut | (while true) is a toplevel form |
| 16:36 | sandbags | oh, I googled up "load-file" so I could totally be doing this wrong... i'm in a lein reply btw |
| 16:36 | jweiss_ | not legitimate, no |
| 16:37 | sandbags | jweiss_: okay, this perhaps explains why LightTable has stopped working for me |
| 16:37 | sandbags | thanks |
| 16:37 | jweiss_ | last i checked it wasn't compiled in a way that would run on my system |
| 16:37 | sandbags | is there any kind of logging that i can get clojure to do that might let me figure out why |
| 16:38 | sandbags | i note in passing that, until about 7-8 hours ago, i wasn't having a problem |
| 16:38 | technomancy | sandbags: binary search is your best bet |
| 16:38 | sandbags | technomancy: you're thinking it's something about my source file? |
| 16:38 | technomancy | sandbags: if it's happening in lein repl, yeah. if it's in light table it could be something else. |
| 16:38 | jweiss_ | eval forms one at a time in that file :) |
| 16:39 | technomancy | sandbags: also: load-file is very low-level; you should use require |
| 16:39 | sandbags | technomancy: LT was hanging on starting up a repl for the file, CG asked me to try in lein-repl |
| 16:39 | sandbags | lein-repl starts |
| 16:39 | sandbags | but then i figured that probably wasn't testing anything much |
| 16:39 | sandbags | ah, ok |
| 16:41 | scottj | maacl: maybe look at pedestal |
| 16:42 | maacl | scottj: thanks, although looks heavy for just keeping a datastructure in sync |
| 16:44 | sandbags | IIReadC clojure returning 'nil' signifies success, right? |
| 16:44 | sandbags | returning nil from a funciton such as 'require' i mean |
| 16:45 | amalloy | sandbags: more like "no meaningful return value" |
| 16:45 | amalloy | generally it means nothing broke, though. certainly that's true for require and its friends |
| 16:45 | sandbags | thanks |
| 16:49 | Bronsa | sandbags: that's not always true though http://sprunge.us/EQVL |
| 16:49 | TimMc | sandbags: Clojure functions *have* to return something. (Or throw an exception, or call System/exit, I suppose...) If your function doesn't have anything useful to return, nil is the standard thing o use. |
| 16:50 | sandbags | thanks guys |
| 16:55 | sandbags | okay so definitely something in the code hanging the repl, probably i have a bracket misplaced or something |
| 16:55 | sandbags | although... i'd expect some kind of syntax error or something |
| 16:56 | amalloy | sandbags: well, as i think someone suggested earlier, you might have (while true) at the top-level or something like that. or light table could have a bug; it would hardly be the first |
| 16:57 | sandbags | https://gist.github.com/mmower/2fb5f8ba95382084b4e5 |
| 16:57 | sandbags | amalloy: it's not LT, i'm in pure lein repl now |
| 16:57 | sandbags | without the comments, this is hanging my repl |
| 16:58 | nDuff | You're decrementing i, but testing n |
| 16:58 | nDuff | so, yes, no surprise that that's hanging. |
| 16:58 | sandbags | ah, damn |
| 16:58 | amalloy | nDuff: he's not calling that function, allegedly |
| 16:58 | amalloy | oh, but the println is there |
| 16:58 | nDuff | Exactly. |
| 16:58 | sandbags | yeah |
| 16:58 | sandbags | the println |
| 16:58 | sandbags | which is probably what i added that triggered this whole thing |
| 16:59 | amalloy | sandbags: i don't know what LT recommends, but in any other clojure setup it's a bad idea to do anything but define functions at the topmost level |
| 16:59 | sandbags | but is so seemingly innocuous an action that when LT started to ahng |
| 16:59 | sandbags | amalloy: i was really just playing around but, yes, i can see why this is recommended :) |
| 16:59 | nDuff | I _am_ somewhat surprised that LT doesn't have an easy way to interrupt a runaway execution |
| 16:59 | nDuff | (which, for instance, emacs+nrepl will do easily) |
| 17:00 | sandbags | well the thing is in LT it *looked* like it was still starting the repl |
| 17:00 | Glenjamin_ | every time i try LT it seems to hang for an unclear reason |
| 17:00 | sandbags | Glenjamin_: well it is 0.3 :) |
| 17:00 | Glenjamin | yeah, i intend to keep coming back to it |
| 17:01 | sandbags | in this case I am not sure what LT could do, since the nREPL underneath it has hung |
| 17:01 | sandbags | well, been hung |
| 17:01 | jweiss_ | ok i seem to be making headway here, having one protocol function point to another doesn't seem to work |
| 17:02 | jweiss_ | eg (defprotocol MyProto (foo [x]) (bar [x])) (extend My.Class {:foo identity :bar foo}) |
| 17:03 | dsop | hmm sqlkorma doesnt convert types and retursn everything as strings? |
| 17:03 | jweiss_ | (bar (MyClass. "baz")) -> IllegalArgumentException No implementation of method: :foo of protocol: #'MyProto found for class MyClass. |
| 17:04 | jweiss_ | but (foo (MyClass. "baz")) works. |
| 17:05 | luisgabriel | I'm having some issues related to performance on a simple example that I'm writting in clojure. probably I'm doing something very wrong. If someone can help me, here is the code: https://gist.github.com/luisgabriel/5287722 |
| 17:07 | luisgabriel | I'm trying to implement a simple search engine for text files |
| 17:07 | jweiss_ | doh... /me should have referred to the protocol function using the var. (extend My.Class MyProto {:foo identity :bar #'foo}) |
| 17:07 | jweiss_ | that works |
| 17:08 | amalloy | jweiss_: ah, now that sounds like a protocol behavior that i consider a bug. if you capture a protocol function's *value* at the top level (as opposed to its var), then that function doesn't get updated |
| 17:09 | dsop | hmm okay korma doe sconvert the types :) |
| 17:10 | callenbot | I've come to realize that scala and go represent two extremes of design principles. |
| 17:10 | jweiss_ | amalloy: i'm not sure how it should work |
| 17:11 | jweiss_ | in this case, foo is a protocol function and at the time it's being extended there was no implementation for that type. |
| 17:23 | dsop | whats the easierst way if i have two list of intergers to find the disjoint set? |
| 17:24 | TimMc | dsop: Use some clojure.set operations. |
| 17:25 | dsop | TimMc: ah clojure.set/difference, thx |
| 17:52 | inhortte | Does anyone here know how to properly include local jars in a project with leningen2? |
| 17:54 | amalloy | ~repeatability |
| 17:54 | clojurebot | repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability |
| 17:55 | technomancy | inhortte: lein-localrepo or s3-wagon-private depending on whether you're doing real work or just playing around |
| 18:01 | inhortte | technomancy -> I'm just playing around for now. :) |
| 18:02 | technomancy | localrepo is prolly fine |
| 18:02 | inhortte | I'll try lein-localrepo |
| 18:02 | technomancy | but also submit a bug report to whoever is giving you a jar that's not in a repo |
| 18:02 | technomancy | because that's crazy |
| 18:04 | inhortte | technomancy -> it's this: https://github.com/macourtney/clj-crypto ... I wanted to play around with 'masques' (https://github.com/macourtney/masques). |
| 18:04 | technomancy | oh, if it's a clojure project you can just do `lein install` |
| 18:06 | inhortte | technomancy -> I am not going to read a bit of lein documentation. :) |
| 18:06 | antares_ | shipped Money 1.0, a tiny library for dealing with moneyz and currencies http://blog.clojurewerkz.org/blog/2013/04/02/introducing-clojurewerkz-money/ |
| 18:08 | pmonks | Step 1: develop Money 1.0 |
| 18:08 | pmonks | Step 2: ?? |
| 18:08 | lazybot | pmonks: What are you, crazy? Of course not! |
| 18:08 | pmonks | Step 3: PROFIT!!!1 |
| 18:09 | antares_ | pmonks: my last name is Gnome |
| 18:20 | hyPiRion | The leprechaun in action. |
| 18:20 | technomancy | money 1.0? I dunno man; everyone knows it's not a good idea to use floats for currency. =) |
| 18:20 | antares_ | technomancy: there is a BigMoney type :) |
| 18:20 | technomancy | heh; nice |
| 18:22 | hyPiRion | Still doesn't fix the issue, does it? |
| 18:22 | hyPiRion | ,(/ 1M 3M) |
| 18:22 | clojurebot | #<ArithmeticException java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.> |
| 18:23 | technomancy | well, dividing money by money doesn't make sense |
| 18:23 | antares_ | hyPiRion: it's Java at the core and it uses rounding modes for division, if that answers your question |
| 18:23 | hyPiRion | ah |
| 18:23 | antares_ | all potentially lossy operations require you to specify a rounding mode and scale |
| 18:23 | hyPiRion | technomancy: by people, perhaps? |
| 18:23 | technomancy | hyPiRion: surely an integer? |
| 18:25 | hyPiRion | technomancy: sure, but ##(/ 1M 3) would still not be representable |
| 18:25 | lazybot | java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. |
| 18:25 | technomancy | oh, true |
| 18:30 | inhortte | technomancy -> thanks, by the way. it worked fine. |
| 18:32 | technomancy | cool |
| 18:36 | angusiguess | Is there any clear reason this wouldn't be displaying the image I load? It seems to get the dimensions right. https://gist.github.com/angusiguess/26ec9f33eaefcc2d9d8d |
| 18:36 | si14 | what's the meaning of "NullPointerException [trace missing]"? |
| 18:38 | technomancy | si14: I think that's a bug in the JVM's tiered compiler |
| 18:38 | amalloy | si14: that is the clojure runtime letting you know you're going to be sad when you try to debug |
| 18:39 | si14 | https://gist.github.com/si14/6781aa479e696b5690b9 here is the code |
| 18:39 | technomancy | technomancy/leiningen#1025 |
| 18:39 | lazybot | -XX:+TieredCompilation destroys tracebacks -- https://github.com/technomancy/leiningen/issues/1025 is closed |
| 18:40 | si14 | it will be somewhat OK if I'll see that "Hello world" printout |
| 18:40 | si14 | but I do not |
| 18:41 | technomancy | try disabling tiered compilation? |
| 18:47 | si14 | but I still don't get why that printout is missing. |
| 18:48 | technomancy | si14: I guess it's not in the comments there, but someone traced it down to a bug in the JVM |
| 18:49 | si14 | technomancy: "it" = ? |
| 18:50 | technomancy | the lack of a stack trace |
| 18:50 | si14 | technomancy: can you take a look at that snippet please? |
| 18:51 | technomancy | hm; that's very strange |
| 18:51 | si14 | when I uncomment line 38 I get NPE (thanks to your advice it's now somewhat traced), but no printout. |
| 19:41 | si14 | technomancy: thanks for the help, anyway :) |
| 19:47 | Oddman | what's everyone's preferred library for web, when dealing with clojure? |
| 19:47 | Oddman | and fav mysql lib? |
| 19:49 | technomancy | Oddman: I don't know if anyone in here will admit to using mysql by choice =) |
| 19:49 | Oddman | clojure community is too elite for it? |
| 19:50 | Oddman | what's the storage medium of choice here? |
| 19:50 | technomancy | but clojure.java.jdbc in theory connects you to any DB supported by JDBC |
| 19:51 | Oddman | gotcha. And is that an ORM solution, or a preferred solution to an ORM implementation? |
| 19:51 | Oddman | new to java, clojure.etc. so starting from scratch :P |
| 19:51 | technomancy | it's not an ORM, but it's a good starting point |
| 19:52 | Oddman | doesn't need to be an ORM, just curious as to options available |
| 19:52 | Oddman | and for web - what is the preferred framework? |
| 19:52 | Oddman | been looking at compojure, seems quite light |
| 19:52 | technomancy | it's the best |
| 19:53 | Oddman | heh |
| 19:55 | scottj | Oddman: maybe look at korma, clojureql, and pedestal if you want something else. |
| 20:00 | Oddman | having a look at clojureql, this irks me: |
| 20:00 | Oddman | SELECT * FROM (SELECT users.* FROM users ORDER BY users.id asc) ORDER BY users.id desc |
| 20:00 | Oddman | when calling multiple sorts |
| 20:01 | Oddman | =\ |
| 20:13 | callenbot | http://gearon.blogspot.com/2013/03/clojurescript-and-nodejs.html |
| 20:37 | xeqi | Glenjamin: have you found any other bugs with peridot? considering releasing a new version once I merge the two pull requests |
| 21:53 | tomoj | hmm, if reifying vars in cljs (even just :dynamic ones) is unacceptable due to performance reasons, how about just adding a new metadata flag :reified or :var or something? |
| 21:54 | tomoj | then if you want bound-fn to preserve your var you have to ask for it |
| 21:55 | tomoj | guess it would be pretty shitty to have some vars reified and some not |
| 21:56 | brehaut | tomoj: that authentic javascript experience :/ |
| 21:56 | tomoj | but is dnolen ever going to say something other than "can't reify vars, performance cost" or "can't keep binding frames for :dynamic vars, performance cost" |
| 21:56 | tomoj | are those performance problems even solvable? |
| 21:57 | tomoj | only other option I see is some weird hack to get bound-fn working, to which dnolen will probably still say "performance cost" |
| 21:58 | gfredericks | tomoj: when you're running on a crazy-high-level host like JS there's a limit to how much further you can pile abstractions |
| 21:58 | tomoj | are you suggesting we may never get bound-fn? |
| 21:58 | callenbot | maybe clojurescript should be ported to asm JS |
| 21:58 | callenbot | for SPEEEEEEEEEEEEEEEEEEEEEEEEEEEED |
| 21:59 | Oddman | lol |
| 21:59 | tomoj | that seems unacceptable, though apparently dnolen disagrees, and he probably understands better than I.. |
| 21:59 | gfredericks | tomoj: that wouldn't surprise me, but I definitely don't have my head in the relevant issues, nor know enough about JS |
| 21:59 | gfredericks | tomoj: cljs won't even get decent numerics |
| 21:59 | callenbot | there's already an llvm clojure project, just point, aim at emscripten, and fire! |
| 21:59 | brehaut | lets have a pool: how long will it take dnolen to write a fast generational collector in JS |
| 22:00 | callenbot | brehaut: I'll take Never for $1000 Trebek. |
| 22:00 | tomoj | gfredericks: decent numerics? |
| 22:00 | callenbot | tomoj: it's all 754 |
| 22:00 | gfredericks | tomoj: anything besides floats |
| 22:00 | callenbot | technically 32-bit unsigned ints are allowed to fly past |
| 22:01 | callenbot | but anything larger is gonna be a double. |
| 22:01 | tomoj | sure |
| 22:01 | tomoj | but that seems irrelevant :) |
| 22:01 | callenbot | JUS SAYIN |
| 22:01 | gfredericks | tomoj: it's something you'd want in a language but can't get cuz speedz |
| 22:01 | tomoj | I mean, yeah, there are some nice things we will never get |
| 22:02 | tomoj | but is bound-fn one of them? |
| 22:02 | tomoj | if so, |
| 22:02 | tomoj | I dunno. it seems like a big problem |
| 22:02 | gfredericks | Raynes: okay I got codez this time |
| 22:03 | callenbot | tomoj: cljs is just a house of pain built on an indian graveyard called JavaScript. |
| 22:03 | gfredericks | Raynes: https://www.refheap.com/paste/13189 |
| 22:03 | callenbot | tomoj: the bedsheets are okay if you ignore the blood. |
| 22:04 | tomoj | often the only option will be to write manual bound-fns for specific vars of interest |
| 22:04 | gfredericks | tomoj: you do a lot of dynamic vars in cljs? |
| 22:04 | tomoj | not a lot |
| 22:04 | gfredericks | tomoj: also a macro could make that as easy as (bound-fn [*foo* *bar*] ...fn stuff...) |
| 22:05 | tomoj | right, I guess it's not that big of a problem |
| 22:06 | tomoj | cljs.test and any async framework can manually do that for the vars they need |
| 22:06 | tomoj | then the user just gets the pain of dealing with any other vars they need |
| 22:06 | gfredericks | could you do this without reified vars? |
| 22:06 | gfredericks | have binding log what it's doing somewhere? |
| 22:06 | gfredericks | so bound-fn knows what vars are active? |
| 22:07 | gfredericks | sounds like that wouldn't affect normal perf |
| 22:08 | gfredericks | I'm assuming you didn't want some kind of actual thread-local thing |
| 22:08 | tomoj | that's what I've been trying to figure out, I think it should be possible |
| 22:08 | tomoj | but not at no perf cost |
| 22:08 | gfredericks | are there JS runtimes where that's meaningful? |
| 22:08 | tomoj | unless you have a :bindable flag or whatever like I suggested above |
| 22:08 | gfredericks | tomoj: what's the perf cost? |
| 22:09 | tomoj | anyone using :dynamic who doesn't need bound-fn will suffer needlessly |
| 22:09 | gfredericks | Raynes: oh apparently I need to pass the zipper to l/fragment for some reason |
| 22:09 | tomoj | if you do it for all :dynamic (dnolen has already pointed out that this is a concern) |
| 22:10 | gfredericks | tomoj: but only at the time they use binding, right? |
| 22:10 | tomoj | right, or if they set! |
| 22:10 | gfredericks | it just makes binding itself a little slower? |
| 22:10 | gfredericks | oh hm |
| 22:10 | gfredericks | set! is supposed to only affect the local frame isn't it |
| 22:10 | tomoj | theoretically, which is another wrinkle |
| 22:10 | gfredericks | okay screw it all I give up |
| 22:11 | tomoj | since you probably don't want to change cljs so that people set!'ing without binding get broken (though I'd be fine with it..) |
| 22:13 | tomoj | I guess I can accept that users will have to manually handle their own vars |
| 22:14 | technomancy | you guys figure out that stuff before I find myself in the precarious position of needing to run code on a JS runtime, k? |
| 22:14 | tomoj | https://www.refheap.com/paste/1631777863115a2e1e8ea16c9 |
| 22:14 | tomoj | yeah, macro would be nice.. |
| 22:15 | tomoj | maybe you just tell your 'executor' which vars to carry |
| 22:16 | gfredericks | Raynes: I take it back again I have no idea what I'm doing |
| 22:19 | tomoj | actually, that would really suck |
| 22:21 | tomoj | it would force knowledge about dynamic vars to all be complected together in places that shouldn't care at all? |
| 22:23 | tomoj | any place you use bound-fn, you have to know about all the vars you're in the _dynamic extent_ of? |
| 22:28 | tomoj | I'm gonna go for a var flag and no reification |
| 22:29 | howdynihao | whats a good / popular kata? |
| 22:29 | brehaut | 4clojure.org |
| 22:31 | brum | how long would it take one of you to do a problem like this.. http://www.4clojure.com/problem/77 |
| 22:32 | howdynihao | that site is nice, but i was looking for something i could git clone |
| 22:32 | howdynihao | and run the tests and actually edit the code |
| 22:32 | howdynihao | instead of the 'fill in the blank' |
| 22:33 | gfredericks | brum: a few minutes? |
| 22:33 | brehaut | brum: that would probably depend on how familiar you are with the standard lib and the features of for |
| 22:34 | brehaut | actually, you might not even need for for that one |
| 22:34 | howdynihao | https://github.com/gigasquid/yellow_belt_clojure_katas there is this, but its old, and it doesnt run as is, (probably simple to fix) |
| 22:35 | brum | i would take the first word and compare it to every other word, add the word to the array if it had all the same letters |
| 22:35 | brehaut | and gigasquid is a 4clojure contributor now |
| 22:35 | brum | remove the first word from the list and then do the same with the new first word |
| 22:35 | gfredericks | brehaut: brum: got it first try |
| 22:36 | howdynihao | i would like to note, catnip is very cool |
| 22:36 | gfredericks | seven lines |
| 22:36 | brum | let me see |
| 22:36 | gfredericks | https://www.refheap.com/paste/13193 |
| 22:37 | brum | that's some fancy clojure knowledge |
| 22:37 | gfredericks | like brehaut said, familiarity with the standard lib |
| 22:37 | brehaut | my solution was apparently #(set (for [[_ s] (group-by frequencies %) :when (next s)] (set s))) |
| 22:38 | brehaut | which is kinda awkward |
| 22:38 | brum | how long have you been programming for |
| 22:38 | brum | gfredericks: brehaut |
| 22:38 | gfredericks | a decade or so |
| 22:38 | brehaut | i dont know |
| 23:26 | rocco65536 | c-c , in emacs is giving me a compiler error |
| 23:26 | rocco65536 | does anyone know what could be the matter? |
| 23:26 | jack_rabbit | What's the error? |
| 23:27 | rocco65536 | class not found |
| 23:27 | rocco65536 | am I supposed to run test via lein? |
| 23:28 | rocco65536 | I tried adding clojure to classpath but it didn't work |
| 23:28 | rocco65536 | maybe this test mode in emacs is outdated? |
| 23:31 | jhn | rocco65536: does it work from the command line when you do `lein test`? |
| 23:32 | fbernier | what's ->> |
| 23:32 | fbernier | ? |
| 23:32 | rocco65536 | yes lein completes the test |
| 23:33 | rocco65536 | it just doesn't work in emacs |
| 23:33 | rocco65536 | it can't find clojure.test.mode |
| 23:35 | jhn | rocco65536: did you install via marmalade or melpa? |
| 23:36 | rocco65536 | the former |
| 23:36 | technomancy | rocco65536: clojure-test-mode 2.x needs nrepl.el; 1.x uses slime |
| 23:37 | rocco65536 | I am using nrepl |
| 23:37 | technomancy | hm; weird |
| 23:37 | rocco65536 | basically I just followed the tutorial here http://clojure-doc.org/articles/tutorials/emacs.html |
| 23:37 | technomancy | you can do (run-tests) in the repl as a workaround |
| 23:38 | rocco65536 | unable to resolve run-tests |
| 23:39 | rocco65536 | which namespace should I be in to run this |
| 23:39 | technomancy | rocco65536: your repl would need to be in your test namespace |
| 23:40 | rocco65536 | ok now it works |