2014-12-13
| 00:40 | ghadishayban | trying to beat rhickey's performance on clojure.core/range is super hard |
| 00:41 | ghadishayban | had this systems class in university where you were graded according to a giant benchmark scoreboard |
| 00:53 | rritoch | ghadishayban: Are you using doall within your benchmark? Range is lazy so to truly benchmark it you need to ensure all operations are within the timer. |
| 00:57 | rritoch | ghadishayban: Looking at the code, I'd expand out the ararities like C would do with inline functions. I'd also pretest for step 1 and use the inc function instead of + whenever step = 1 which is a common case and inc "should" be faster than + in some cases. |
| 01:01 | ghadishayban | rritoch: yeah I'm on it |
| 01:01 | ghadishayban | rritoch: benchmarks are here if you want to play along http://dev.clojure.org/jira/browse/CLJ-1515 |
| 01:02 | ghadishayban | rritoch: expand arities of what? |
| 01:03 | rritoch | ghadishayban: No, but I've made some of my own efforts regarding benchmarks, ultimatly since bytecode is interpreted it's really difficult to get any real advantages since there's no guaranteed time for bytecode, unlike assembly where most instructions use a set number of clock cycles. |
| 01:04 | rritoch | ghadishayban: The 0,1 and 2 ararity versions just call the 3 ararity version. I'd copy/paste the code in and deal with them separately. |
| 01:05 | TEttinger | ararity? |
| 01:05 | TEttinger | is that different from arity? |
| 01:05 | rritoch | ex. zero ararity automatically uses step 1 so you can use inc and avoid any tests for negative, etc. |
| 01:06 | rritoch | TEttinger: yes, that is what I mean |
| 01:06 | TEttinger | heh, I wasn't sure if ararity was a new term for array arity or something |
| 01:07 | rritoch | nope, just a mild case of ADD I guess |
| 01:08 | rritoch | (attention deficit....) |
| 01:11 | ghadishayban | rritoch: range is a subtle problem with many different cases. We're trying to improve it to take advantage of IReduceInit for transducers in 1.7 |
| 01:15 | rritoch | ghadishayban: Ok, well there are a lot of ways of doing it. I'm just going off the code I see. I don't remember if it's python or ruby, but another option is to create a range class which implements a lazy sequence, that would probably be the fastest |
| 01:16 | rritoch | ghadishayban: I believe it's python that does that |
| 01:18 | rritoch | ghadishayban: You could even still optimize the arities by having a static constructor that produces different child clases based on arity. |
| 01:18 | rritoch | ghadishayban: ie. Range/create ... |
| 01:18 | arrdem | ghadishayban: the abstraction of a transducer over (range) is still just a foldr, right? |
| 01:20 | rritoch | ghadishayban: I suppose it's not called a static constructor, maybe a static factory method? |
| 01:20 | rritoch | ghadishayban: terminology aside, it's still faster |
| 01:22 | rhg135 | rritoch: doesn't clojure have RangeSeq? |
| 01:23 | cfleming | ghadishayban: What's the state of invokedynamic on JDK 7? |
| 01:23 | ghadishayban | arrdem: the Range knows not of the transducer, just the fact that it is being reduced over |
| 01:24 | cfleming | ghadishayban: I had a feeling I'd read in a few places that it wasn't really ready for production use until JDK 8 - performance problems and bugs IIRC |
| 01:24 | ghadishayban | rritoch: see the patch clj-1515-9 for a Range.java class |
| 01:24 | rritoch | ghadishayban: I'm actually looking at the class now, I never noticed it |
| 01:25 | rhg135 | ,(class (range)) |
| 01:25 | clojurebot | clojure.lang.LazySeq |
| 01:25 | rhg135 | Nvm |
| 01:26 | ghadishayban | the current range class in core is old and unused |
| 01:26 | rhg135 | Ah |
| 01:26 | rhg135 | I'm not crazy yet |
| 01:26 | ghadishayban | cfleming: apparently jdk <7u45 is not so good |
| 01:27 | cfleming | ghadishayban: Ok, but recent versions should be ok? |
| 01:27 | ghadishayban | cfleming: even 8 has issues. 99% of them fixed in 8u40, the fixes just landed in the last 10 days |
| 01:27 | ghadishayban | 8u25 is pretty good |
| 01:27 | ghadishayban | for clojure purposes good enough, for JRuby or Nashorn, they need more =) |
| 01:28 | cfleming | ghadishayban: There was some discussion on the ML of dropping support for JDK6, presumably to investigate invokedynamic - that's inconvenient for me personally, but if JDK 7 is sufficient then it's probably worth it. |
| 01:28 | ghadishayban | yeah I saw |
| 01:28 | rritoch | ghadishayban: Well, that looks like the way to go, but it looks like it would need some improvements since it doesn't implement all the interfaces that LazySeq does. |
| 01:28 | ghadishayban | it's unfortunate for JetBrains case |
| 01:28 | cfleming | ghadishayban: Just wanted to make sure I wasn't totally ignorant in my arguments :) |
| 01:29 | cfleming | ghadishayban: Yeah, no doubt. I'm going to get a hold of them to see what their homegrown JDK plans are. |
| 01:29 | ghadishayban | yeah I mean it's not really fair for jetbrains to mandate a jdk that has been EOLed for years on users |
| 01:29 | ghadishayban | then again it's mandated because of pesky issues, UI or crashes, that are still open |
| 01:29 | cfleming | ghadishayban: They don't so much mandate it as inform users that the recent ones don't work. |
| 01:30 | ghadishayban | yeah I ran it on both 7 and 8 no issues besides the graphics switching |
| 01:30 | cfleming | ghadishayban: Yeah, that one's pretty bad for me personally unfortunately, I do all my work on a laptop |
| 01:30 | ghadishayban | jetbrains is probably in a similar rock<->hard place as rich or clojure would be |
| 01:30 | ghadishayban | me too |
| 01:31 | ghadishayban | rritoch: which interfaces are missing...i feel like you are shooting from the hip |
| 01:33 | Jaood | cfleming: don't you get tired more rapidly working all the time on the laptop? |
| 01:33 | rritoch | ghadishayban: Wow, your going to insult me for trying to help you? You can lookup that answer yourself!!! |
| 01:34 | cfleming | Jaood: Well, I work about half time at a coworking, and there I plug in an external kb/mouse/screen |
| 01:34 | cfleming | Jaood: But it's still the laptop driving it |
| 01:35 | ghadishayban | rritoch: please simmer down. people working on Range have spent upwards of a month on it, i only respectfully ask that you consider the problems (which are manifold) before prescribing a quick solution |
| 01:37 | ghadishayban | cfleming: also noticed a two finger scroll regression |
| 01:37 | ghadishayban | cfleming: fortunately 0 crashes though |
| 01:37 | cfleming | ghadishayban: yeah, there are other issues - alt no longer works as a modifier, I believe |
| 01:38 | cfleming | ghadishayban: Yeah, I've had 10+ users report crashes, and I don't have that many users |
| 01:38 | rritoch | ghadishayban: I have 30 years programming experience, so yes, I can answer some issues instantly where it takes your team months of deliberation to come up with solutions that are often not even optimal. |
| 01:38 | rritoch | ghadishayban: This is exactly why I've forked clojure |
| 01:39 | andyf | rritoch: With respect, the people spending a month working on optimizing the code are not new to programming, either. |
| 01:39 | cfleming | ghadishayban: The crashes are also selected from the pool of people on OSX using JDK 7+, so the proportion must be pretty high |
| 01:39 | rritoch | ghadishayban: There are very few issues you can run into that I haven't run into dozens of times already |
| 01:39 | arrdem | I'm gonna get beer. this is gonna be good |
| 01:39 | cfleming | arrdem: Pass the popcorn, please |
| 01:39 | andyf | My dancing isn't that good, guys :) |
| 01:40 | rritoch | andyf: Spending months optimizing code, or even years, isn't unusual at all, but these are cases I've already dealt with. |
| 01:41 | rritoch | andyf: When I started programming, computers were VERY slow. Optimization wasn't a luxary back then, it was a necessity. |
| 01:42 | rritoch | andyf: It is the reason I took up assembly language |
| 01:42 | andyf | I would suggest that ghadi saying "it feels like you are shooting from the hip", that was not intended as an insult, but a request to be more specific about your meaning. It would be surprising if they missed some interfaces being implemented from simple lack of looking. Don't take offense too easily, and please try not to give any. |
| 01:43 | rritoch | andyf: who is really shooting from the hip now? |
| 01:43 | andyf | I'm not sure we are assigning the same meaning to that phrase. |
| 01:44 | rritoch | andyf: Either way, this is my mistake. If anyone had actually looked you would have seem my mistake quickly. I didn't notice it implements ASeq which is where the missing interfaces came from. |
| 01:45 | rritoch | andyf: Err, extends |
| 01:46 | andyf | I feel like people are actually sitting around eating and drinking. |
| 01:46 | rhg135 | Party at #clojure!! |
| 01:46 | clojurebot | No entiendo |
| 01:46 | arrdem | cfleming: one thing I like about texas. these people will put spiced cheese on anything. |
| 01:47 | rritoch | andyf: Technically though, I'm not completely wrong as IPending isn't implemented, though I'm not sure what IPending is really used for |
| 01:48 | cfleming | arrdem: That does sound good. |
| 01:48 | cfleming | arrdem: What about spicy wings? Do they have those? |
| 01:49 | cfleming | andyf: I actually did just eat a bunch of guacamole, but sadly I have no beer |
| 01:49 | andyf | cfleming: Would gladly pass you a Newcastle Brown Ale if it weren't so far. |
| 01:49 | arrdem | cfleming: we have pluckers, it's pretty good |
| 01:50 | Jaood | If Range.java is not used anymore, why is it still in the codebase? |
| 01:50 | cfleming | andyf: Nice selection, thanks! |
| 01:50 | arrdem | Jaood: good question. why do we still have clojure.parallel? |
| 01:51 | andyf | rritoch: I don't know if there is a way to say this that sounds respectful, but it is meant that way. I do respect experience in any field, including programming. However, when one brings up their years of experience to a discussion too often, it can sound like an appear to authority. |
| 01:51 | andyf | s/appear/appeal/ |
| 01:51 | Jaood | arrdem: no idea, why? |
| 01:52 | cfleming | arrdem: I see that the pluckers website says "If you don't like our wings, we'll give you the bird". Why would I want the bird if I didn't like it? |
| 01:52 | arrdem | Jaood: wish I knew. just making the point that there's trash that never got taken out around. |
| 01:52 | ghadishayban | Jaood: yeah there's a handful of old things in the codebase. not tooo much, but some |
| 01:52 | arrdem | cfleming: thatsthejoke.jpg |
| 01:53 | rritoch | andyf: If anyone had actually looked, instead of doing exactly what they accused me of, they would have noticed that IPending wasn't implemented. |
| 01:53 | andyf | I mean, honestly, if you were discussing a programming problem with someone, and you disagreed, and they had 40 years of experience, would you stop looking for reasoned arguments? |
| 01:53 | rritoch | andyf: Though I did miss a few interfaces from ASeq, which no one would have known if I hadn't stated it myself. |
| 01:54 | rritoch | andyf: Nope, I'd go back to the code first before making myself look ignorant. |
| 01:56 | rritoch | andyf: I have met a few people that can outcode me in ways that make anyone here look like newbies. People who can program assembly directly in hex for example, people who can construct valid TCP/IP packets by hand (in hex), etc. |
| 01:56 | rritoch | andyf: The only authority in programming is the hardware |
| 01:56 | arrdem | rritoch: dude. have you read anything about how the clojure contributing process works. |
| 01:56 | cfleming | When I started programming it were uphill both ways |
| 01:57 | andyf | Impressive feats, for sure. I can't honestly say I know that anyone here would look like a newbie by comparison, because I don't know their abilities in detail. That takes time. |
| 01:57 | arrdem | cfleming: from the bottom of a gravitational singularity? |
| 01:57 | cfleming | arrdem: Ha, that would have been too easy |
| 01:58 | arrdem | cfleming: TIL other Clojurians are capable of infinite time feats. clearly I need to up my game. |
| 01:58 | rritoch | andyf: It takes more than time. I tried, memorizing even the x86 instruction set is insanely difficult. I couldn't do it. I also had no drive to memorize the TCP/IP structure, though I suppose that is very useful when writing servers. |
| 02:00 | rritoch | arrdem: Yes, I learned the process from clojure-dev after submitting some features for review. |
| 02:00 | ghadishayban | is the T in TDD for testosterone |
| 02:00 | arrdem | (inc ghadishayban) |
| 02:00 | lazybot | ⇒ 1 |
| 02:01 | andyf | testosterone driven desire |
| 02:01 | arrdem | ghadishayban: dude how are you that low karma |
| 02:01 | arrdem | (identity arrdem) |
| 02:01 | lazybot | arrdem has karma 39. |
| 02:01 | rritoch | arrdem: But I also see that clojure only accepts 1% of the features, which is why forking clojure is a better option than dealing with the bureaucracy. |
| 02:01 | arrdem | ghadishayban: clearly you need to lurk harder |
| 02:01 | ghadishayban | arrdem: i'm trying. came here to talk actually |
| 02:02 | seancorfield | (inc ghadishayban) |
| 02:02 | lazybot | ⇒ 2 |
| 02:02 | arrdem | rritoch: I will refer you as politely as I can to the latest entry on my blog which explains in great detail how aquainted I am with these frustrations. |
| 02:02 | seancorfield | link or it didn't happen! :) |
| 02:03 | andyf | seancorfield! |
| 02:03 | arrdem | http://arrdem.com/2014/12/11/oxcart_going_forwards/ |
| 02:03 | arrdem | seancorfield: ohai there |
| 02:03 | seancorfield | Thank you |
| 02:03 | arrdem | seancorfield: <3 |
| 02:03 | rritoch | arrdem: Well, when I can come up with a trademark-safe name for this fork I intend to allow anyone to add features to it. Making it a melting pot if you will, of proof of concept projects. |
| 02:03 | andyf | You might like a new feature in Eastwood's next release -- configuration that overrides the :arglists of functions, so Eastwood uses them for wrong-arity checking rather than the :arglists metadata. Makes most of the java.jdbc arity warnings disappear. |
| 02:04 | arrdem | rritoch: I'm good. Got two forks of my own. Already opted out of running a "community clojure" edition twice. |
| 02:04 | rritoch | arrdem: This should help clojure in their decisions to accept projects since developers will be able to use this to prove and discover any issues with proposed features. |
| 02:05 | cfleming | arrdem: I actually once ported a non-trivial action space shooter game from ARM assembly code to x86. True story. |
| 02:05 | cfleming | arrdem: I had a lot more time when I was younger, but even then it was stupid. |
| 02:06 | andyf | cfleming: Wait, who wrote it in ARM to begin with, and why? |
| 02:06 | cfleming | andyf: I did, I wrote it on an Acorn Archimedes |
| 02:06 | cfleming | andyf: As for why, I was young and stupid |
| 02:06 | andyf | Huh, didn't know ARM went back that far. |
| 02:07 | arrdem | I'd make back in my day jokes but I'm the second youngest person her |
| 02:07 | arrdem | *here |
| 02:07 | arrdem | Raynes: HAHA STILL OLDER THAN YOU |
| 02:07 | rritoch | Does anyone know if the name clojure is actually a trademark? |
| 02:07 | andyf | It is. |
| 02:07 | cfleming | rritoch: Yes it is. |
| 02:08 | rritoch | I figured it was, but it isn't noted as such |
| 02:08 | pdk | clojit |
| 02:08 | rritoch | So yeah, I still need a trademark safe name, I was going with clojureplus but there's no way I can defend that name so I'm stuck until I can find a decent name for it. |
| 02:09 | ghadishayban | i'm pretty sure incremental change under constraints is the real engineering challenge |
| 02:09 | rritoch | My current plan is to have this build using the latest release of clojure to ensure a measure of compatiblility. |
| 02:09 | rritoch | Similar to how C++ was originally programmed in C |
| 02:10 | ghadishayban | that being said -- arrdem you thought of a tracing JIT? |
| 02:10 | rritoch | But this name issue is always a bother. |
| 02:10 | arrdem | ghadishayban: for Clojure? |
| 02:10 | ghadishayban | some bastard hybrid of the Truffle approach with a tracing approach |
| 02:10 | rritoch | Maybe I should just generate a UUID and use that as a name, lol |
| 02:10 | ghadishayban | would need concurrently-safe tracing |
| 02:10 | arrdem | ghadishayban: your talk is the first I've heard of InvokeDynamic |
| 02:11 | arrdem | rritoch: it's been done before. check the logs. |
| 02:11 | seancorfield | andyf: good to know but I have a ticket open on java.jdbc to fix the arg lists. |
| 02:11 | ghadishayban | invokedynamic is very cool and necessary in bytecode land |
| 02:12 | ghadishayban | but something more radical-er could make an interesting thesis |
| 02:12 | arrdem | hehe |
| 02:12 | seancorfield | arrdem: there's a new way to officially load clojure into a host app - does it still suffer the same overhead as RT? |
| 02:12 | ghadishayban | and maybe finally motivate me to use refs/dosync to keep track of code |
| 02:12 | arrdem | seancorfield: what's this? first I've heard of it.. |
| 02:13 | rritoch | arrdem: But do the other versions build with leiningen? https://github.com/rritoch/clojureplus/blob/master/project.clj |
| 02:13 | ghadishayban | arrdem: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/java/api/Clojure.java#L50 |
| 02:13 | rritoch | arrdem: Anyhow, I still have a long list of problems, including the tests aren't running from leiningen. |
| 02:13 | seancorfield | We use RT right now but it's not official / supported. |
| 02:14 | arrdem | rritoch: dude what part of "my own fork" don't you get. |
| 02:14 | rritoch | arrdem: Well, you never provided a link so how could I know in detail what you've done? |
| 02:15 | rritoch | arrdem: If you did use leiningen, did you solve the unit test issue? |
| 02:15 | seancorfield | I tried to rewrite cfmljure from RT to the new java.api but couldn't get it working reliably. I'll take another run at it at some point. Class loader issues. |
| 02:15 | arrdem | ghadishayban: seancorfield: I'll do some digging but I'm pretty sure RT is in the reach set of the "new" API |
| 02:16 | seancorfield | arrdem: thanks. I hadn't dug far. I just wanted to update my library to an official api. |
| 02:16 | seancorfield | Right now RT is a critical part of our infrastructure. |
| 02:17 | arrdem | hoboy. you are literally my worst nightmare :P |
| 02:17 | dagda1_ | if I am using clojure.string/replace then this works (clojure.string/replace "fade.in" #".?\bin\b" "") but how do I build up the expression with a var? I've tried..... |
| 02:17 | seancorfield | Hi gigasquid ! |
| 02:17 | dagda1_ | (clojure.string/replace "fade.in" #(str ".?\b" "in" "\b") "") but it errors |
| 02:18 | arrdem | seancorfield: https://github.com/arrdem/clojure/tree/arrdem <- fork that moves a bunch of stuff out of RT to Util, adds RT.init back. that's what I'm playing with. |
| 02:18 | seancorfield | dagda1_: (re-pattern (str ...)) I think. |
| 02:19 | arrdem | seancorfield: dagda1_: yep re-pattern |
| 02:19 | andyf | dagda1_: Also realize that any single backslash inside of #"" needs to be a double backslash in "" |
| 02:19 | arrdem | $grim clojure.core/re-pattern |
| 02:19 | lazybot | http://grimoire.arrdem.com/1.6.0/clojure.core/re-pattern |
| 02:19 | dagda1_ | seancorfield: k, that works |
| 02:28 | rritoch | arrdem: Anyhow, if you can come up with a trademark safe name for a community edition, I wouldn't mind maintaining it, but all the names I can think of are used, jlisp, xlisp |
| 02:29 | andyf | andylisp. Definitely call it andylisp. |
| 02:30 | rhg135 | ,(str ”clk-" (java.util.UUID/randomUUID)) |
| 02:30 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 02:30 | arrdem | (rand-nth (for [w (line-seq (io/file "/usr/share/badwords"))] (str w "lisp"))) |
| 02:30 | rritoch | andyf: Hmm, that is an awesome name |
| 02:31 | ghadishayban | arrdem: lol the rand-nth on a for comprehension is an evil twist |
| 02:31 | arrdem | ghadishayban: <3 |
| 02:31 | rritoch | andyf: Are you assigning that to the public domain so I can use it? |
| 02:31 | rritoch | andyf: It implies "And why lisp?" |
| 02:32 | rritoch | andyf: considering this is meant to adopt the features the community wants, the name has symmetry |
| 02:32 | andyf | I don't have it trademarked, I know that. I won't stop you from using it. |
| 02:33 | rritoch | andyf: Cool :) |
| 02:34 | rritoch | andyf: We're good, I checked with my VP, and her only condition is that I don't rename it again tommorow. |
| 02:35 | rritoch | andyf: There isn't really a big budget for this project, but we'll see what we can do. |
| 02:37 | andyf | If it had a budget, I think that would be a first for a fork of Clojure, or indeed nearly any programming language implementation |
| 02:38 | rritoch | andyf: I own vnetpublishing, it is a community of freelance developers. We're very far from a corporate structure, my VP is my wife :) |
| 02:38 | andyf | My wife promoted herself to president. |
| 02:39 | rritoch | andyf: We're trying to get away from freelance development and produce a product, to do that we need a platform capable of web 5.0 |
| 02:39 | rritoch | andyf: lol |
| 02:39 | cfleming | seancorfield: When you mention a new way of embedding Clojure do you mean API.java? |
| 02:39 | arrdem | andyf: good on her |
| 02:40 | andyf | these comments are making me thirsty |
| 02:41 | ghadishayban | (inc andyf) |
| 02:41 | lazybot | ⇒ 13 |
| 02:43 | arrdem | andyf: out of beer. have some karma instead. |
| 02:43 | arrdem | (inc andyf) |
| 02:43 | lazybot | ⇒ 14 |
| 02:45 | andyf | Looks like you can have both at the same time: http://averybrewing.com/our-ales/karma/ |
| 02:45 | cfleming | Belgian pale ale, yum |
| 02:45 | arrdem | $google full sale black lager |
| 02:45 | lazybot | [Session Black Lager | Full Sail Brewing Company] http://www.fullsailbrewing.com/session-black.cfm |
| 02:45 | arrdem | ^ I need to find somewhere local that sells this stuff |
| 02:47 | andyf | age verification for a *web site* about beer. I sure hope that is a joke, and not some legal restriction. |
| 02:48 | rritoch | andyf: Anyhow, thanks for the idea. andylisp.org is registered so I just need to move and delete clojureplus |
| 02:48 | andyf | wow. That was fast. |
| 02:49 | rritoch | andyf: I've been working on a web 5.0 platform for 3 years, this is a serious project |
| 02:49 | rritoch | andyf: I can't be held up for months and years just because clojure wants to go through a process of rejection |
| 02:51 | rritoch | andyf: The project started in PHP, but PHP doesn't provide any persistence so it was useless past web 3.0 |
| 02:51 | andyf | rritoch: Anyone can fork any open source project subject to the license, and every open source project has decision makers deciding what changes are made, and what doesn't. I'm not ecstatic about the rate of change in Clojure, but I like it enough to keep using it. |
| 02:53 | rritoch | andyf: This is meant to be a community version. We hope to provide a more democratic solution. Such as putting features on their own branches and allowing the community to vote on what gets included. |
| 02:53 | rritoch | andyf: This isn't really meant to replace clojure. Just as a temporary solution until clojure has the features we need. |
| 02:54 | arrdem | "we" |
| 02:54 | arrdem | rritoch: so um... what are you doing about feature expressions? |
| 02:54 | rritoch | ardem: We = the community |
| 02:59 | rritoch | arrdem: For now, nothing. I'm still working on core features of clojure that I need for specific purposes. CLR is proprietary so I have no intention of supporting it. |
| 02:59 | rritoch | arrdem: ClojureScript is another issue that can be dealt with |
| 03:00 | arrdem | so.... the "fork to add the features we need" is going to ignore the #1 reported pain point of Clojure users. Yep. 5/5 will be contributing. |
| 03:00 | rritoch | arrdem: But if people want it than AndyLispScript and AndyLispCLR can be created, but they'll still fall under andylisp.org |
| 03:01 | rritoch | arrdem: No, if people want to add features they can, but I won't necissarily be contributing to the branches I have no interest in, like the CLR branch. |
| 03:03 | rritoch | arrdem: Andyf put the name andylisp into the public domain, and I secured it from potential registered trademarks by registering andylisp.org |
| 03:03 | rritoch | arrdem: The community is now free to do what they want with the name andylisp |
| 03:05 | andyf | I must say that 'naming a new Lisp variant' was not on my list of things to do this morning. :) |
| 03:07 | arrdem | I'll make sure that andylisp.core makes it into Grimoire 0.4.0. |
| 03:07 | amalloy | is CLR still proprietary? i thought they open sourced that a little while ago |
| 03:07 | cfleming | Yeah, it's all OSS now |
| 03:08 | cfleming | IIRC they're going to officially support on other platforms too. |
| 03:10 | rhg135 | cfleming: when they do I'll stop calling evil |
| 03:12 | rritoch | andyf: Technincally I'd say your parents played a big role in it, lol |
| 03:13 | rritoch | Either way, freedom isn't really free, In this case it only cost about $25 which is a small price for the greater good. |
| 03:18 | sveri | Hi, what is the most idiomatic way to provide a default value for a function argument if the given argument is empty? All I can think of is the :or syntax in a map destructuring, but I dont want to pass a map extra for that |
| 03:19 | rritoch | Anyhow know the proper way to label the clojure trademark? I'm using Clojure (TM. Rich Hickey) but since it's not registered I'm not sure what the convention is. |
| 03:19 | rritoch | Err, anyone. |
| 03:20 | andyf | sveri: Defining multiple arities for a function, where a 2-arity version calls the 3-arity version of itself with the extra default value, is pretty common. |
| 03:21 | sveri | of course -.- How could I forget about that |
| 03:21 | sveri | andyf: thank you |
| 03:24 | arrdem | that's the one thing I'm getting progressively less impressed with about our multiple arity functions... we really only use the low arities for partial applications of the "full" arity. |
| 03:25 | andyf | I think you are safe simply saying "The name Clojure is trademarked by Rich Hickey." in a footnote, and putting TM after uses of the word Clojure, but I'm no intellectual property lawyer. Lots of people use Clojure all over the place without putting a (TM) after it. |
| 03:28 | rritoch | Ok, I deleted clojureplus in prefrence of andylisp https://github.com/rritoch/andylisp so that deals with any trademark issue, licencing won't be changed but I would prefer that contributions come under the MIT license. |
| 03:30 | rritoch | MIT should be compatible with eclipse public license |
| 03:44 | andyf | Still not an intellectual property lawyer, but I wonder whether it is kosher to leave all of the "clojure" occurrences in namespaces. It seems likely that it should not be distributed as a jar with clojure anywhere in the name. |
| 03:46 | rritoch | andyf: The clojure namespaces are copyrighted, you can't just rename them and have them magically become yours. The eclipse license allows the code to be used in other applications. |
| 03:47 | rritoch | andyf: Some changes will be needed so andylisp.core becomes an automatic namespace but that's about it. |
| 03:48 | rritoch | andyf: Though I should add a disclaimer that this version is "Use at your own risk" since this isn't meant to be used for production environments. |
| 03:48 | andyf | I'd recommend not using clojure as any part of a name of a JAR file, or Maven dependency artficact/group id, or whatever those things are called. |
| 03:50 | rritoch | andyf: Well that will take time, but I see your point. Clojure should remain a dependency, and this should truly extend it. |
| 03:52 | rritoch | andyf: But that may make integrating these proof of concept projects into clojure.core more difficult in the long run. |
| 03:52 | rritoch | andyf: As I said, I have no intention of replacing clojure. This is for proof of concept projects. |
| 03:53 | rritoch | andyf: To prove that new features are viable, efficient, and maintainable. |
| 03:53 | TEttinger | sounds good, rritoch. |
| 03:53 | TEttinger | sorta a bleeding edge testbed |
| 03:54 | rritoch | TEttinger: Exactly :) |
| 03:55 | TEttinger | flowjure might also be a good name |
| 03:55 | TEttinger | since the idea is for it to be upstream |
| 03:55 | rritoch | TEttinger: Heh, the ruling was that I'm not allowed to change the name, so this is what I'm stuck with. |
| 03:55 | andyf | I don't have answers to all the questions, but for example, if someone wants to use it in, say, a Leiningen project, they will have to put a dependency in that is something different than [org.clojure/clojure "1.7.0"] |
| 03:56 | rritoch | I really like the name, because the first question everyone asks about it, is why it should be used compared to others. |
| 03:56 | TEttinger | will it even look on clojars? |
| 04:02 | rritoch | TEttinger: Yes, this isn't a new language. It is still clojure. As of now I haven't even verified that this fork is viable. The only hosting company I know of that would finance this is unreliable so for now it doesn't have it's own repository. |
| 04:02 | TEttinger | finance? |
| 04:02 | TEttinger | is github not an option? |
| 04:03 | rritoch | It is on github, but github doesn't provide a maven repository, does it? |
| 04:03 | TEttinger | ahhhh |
| 04:03 | TEttinger | maven repo, gotcha |
| 04:15 | rritoch | andyf: this version of clojure is compiled using leiningen |
| 04:15 | rritoch | andyf: So you can simply use :excludes to change the clojure version |
| 04:15 | rritoch | andyf: eventually |
| 04:17 | rritoch | andyf: I just need to create a runtime in the org.andylisp namespace, with it's own main entrypoint, to make this possible. And then I can remove all clojure sources from it. |
| 04:19 | rritoch | andyf: clojure uses a lot of finals so this will probably need to wrap the clojure runtime. |
| 04:20 | rritoch | andyf: As I said, no proof that this is viable yet |
| 04:21 | rritoch | andyf: But if it speeds up the development of clojure, than it could be useful. |
| 04:21 | rhg135 | Clojure withdrawal: it's a thing |
| 04:46 | SagiCZ1 | rhg135: it is |
| 04:52 | rhg135 | SagiCZ1: that just means it's good stuff |
| 04:57 | bitcrusher | hmm got a firefox path error when using clj-webdriver, anyone know how to solve it? |
| 05:13 | dysfun | is this a bit naughty? https://github.com/korma/Korma/blob/master/src/korma/core.clj#L521 will clojure just ignore the type hint? |
| 05:16 | bitcrusher | man i hate those auto play videos that hide on the side |
| 05:17 | dysfun | flashblock? |
| 05:21 | SagiCZ1 | dysfun: well design websites? |
| 05:23 | rhg135 | dysfun: clojure uses: tag for hints |
| 05:24 | m1dnight1 | guys, is there an idiomatic way to "wait" on an atom? |
| 05:25 | m1dnight1 | I want to write a function that when it is called it blocks. each time the atom changes (i.e., some sort of watcher) I want to do some check, and if not okay, wait for the next change |
| 05:25 | m1dnight1 | any ideas? |
| 05:25 | rhg135 | m1dnight1: don't use atoms is my idea |
| 05:25 | m1dnight1 | .. :p |
| 05:26 | rhg135 | Sounds like manifold can do this |
| 05:28 | rhg135 | I'm sorry I read promise |
| 05:29 | rhg135 | add-watch |
| 05:29 | m1dnight_ | yeah, the addwatch, but I want to surround it with a blocking operation |
| 05:29 | m1dnight_ | i'm not sure how to go about it |
| 05:30 | m1dnight_ | I would add an add-watch (fn [] (if-something-true just fall through)) otherwise wait on the next change of the atom |
| 05:30 | rhg135 | Any particular reason? |
| 05:30 | m1dnight_ | Yes, I'm implementing STM/actors for my thesis |
| 05:30 | rhg135 | Ah |
| 05:31 | m1dnight_ | and an actor that has been invoked from an actor within a transaction has to monitor that trasnaction |
| 05:31 | m1dnight_ | (to make sure he does not commit before his parent does) |
| 05:31 | rhg135 | AFAIK watches are run sync |
| 05:32 | rhg135 | $grimoire add-watch |
| 05:33 | justin_smith | (inc ghadishayban) ; Testosterone Driven Development, lol |
| 05:33 | lazybot | ⇒ 3 |
| 05:33 | rhg135 | $grim add-watch |
| 05:33 | rhg135 | Meh |
| 05:34 | justin_smith | $grim clojure.core/add-watch |
| 05:34 | lazybot | http://grimoire.arrdem.com/1.6.0/clojure.core/add-watch |
| 05:34 | rhg135 | thx |
| 05:34 | justin_smith | it would be nice if that plugin automatically tried clojure.core |
| 05:34 | rhg135 | m1dnight_: ^ |
| 05:37 | rhg135 | Im in no hurry to try S(leep) D(eprivation) D(riven) D(evelopment) so gn * |
| 05:37 | m1dnight_ | cool, i'll check it out |
| 05:37 | m1dnight_ | thanks guys |
| 05:51 | dysfun | rhg135: ah, so :type is actually just an arbitrary metadata key? |
| 05:52 | justin_smith | ,(type (with-meta {:a 0} {:type "foo"})) |
| 05:52 | clojurebot | "foo" |
| 05:52 | dysfun | that was my next question :) |
| 05:52 | justin_smith | ,(type {:a 0}) |
| 05:52 | clojurebot | clojure.lang.PersistentArrayMap |
| 05:54 | dysfun | so presumably it's to allow you to fake the type without changing the type hint? |
| 05:54 | justin_smith | it's for hacks related to things that dispatch on type |
| 05:54 | dysfun | *nod* |
| 05:54 | justin_smith | comes up with multimethods |
| 05:55 | dysfun | aha |
| 05:55 | dysfun | ty |
| 06:59 | whodidthis | peoples, if i have an om component how do i listen for keyboard events in it |
| 07:04 | whodidthis | well, i guess addeventlistener but problem is i only want to listen to dem events while using the component |
| 07:16 | mikos | anyone know how to parse arrays in POST data? such as {"user[name]" "John Doe"}, i'm using compojure |
| 07:16 | mikos | is there a way to parse that data so there's a nested 'user' map in the params? |
| 07:17 | triss | hey all. is there anything special needs to be done when adding dependencies to a chestnut project? |
| 07:18 | triss | I'm trying to use hum (https://github.com/mathias/hum) in a project |
| 07:18 | triss | I've added in to project.clj and am requiring it in one of my libraries |
| 07:19 | triss | but im told Uncaught Error: Undefined nameToPath for hum.core |
| 07:19 | triss | when I connect to set up with a browser |
| 07:27 | whodidthis | whoops wrong channel |
| 07:34 | mikos | ah, looks like i may need wrap-nested-params =) |
| 07:35 | triss | oh a lein clean fixed everything! |
| 07:39 | triss | ok.... I'm about to extend hum from https://github.com/mathias/hum. Would anyone care to comment on how idiomatic this library looks? |
| 07:39 | triss | is there anything that sticks out as not clojure like? |
| 08:03 | bitcrusher | how do i update my libraries, i am using lein ancient but it is still using the older selenium drivers 2_39, I want to use 2_42 |
| 09:18 | stephenmac7 | Is clojure statically typed? |
| 09:19 | dnolen_ | stephenmac7: it is a dynamically typed language, however core.typed allows you to write typed Clojure |
| 09:19 | stephenmac7 | dnolen_: Is it a compiler plugin or something of the sort, or is it just a library? |
| 09:19 | dnolen_ | stephenmac7: just a library |
| 09:20 | stephenmac7 | Hm. I'll take a look. |
| 09:20 | stephenmac7 | I come from a background of discovering the greatness of static typing late |
| 09:20 | stephenmac7 | dnolen_: It causes runtime errors or compilation errors? |
| 09:21 | dnolen_ | stephenmac7: static typing means compilation errors |
| 09:22 | stephenmac7 | dnolen_: Just making sure. Other similar libraries I've used cause runtime errors, which doesn't really qualify |
| 09:22 | stephenmac7 | Thank you |
| 09:53 | ajmccluskey | Is there a clear preference between defining private helper fns at the top level and defining them in let bindings of the function that uses them? Assuming only one top level fn uses them. |
| 10:08 | gigasquid | Hi seancorfield! |
| 10:20 | apricity | i'm using a cider nREPL in emacs and I evaluated a form using C-x C-e. I know the evaluation is taking a while because my laptop fans kicked in highspeed. Other than the fans running how can I know if the form is still evaluating? |
| 10:22 | dnolen_ | apricity: you can't evaluate anything else |
| 10:22 | apricity | if i try to eval something else will it queue it up to be evaled next? |
| 10:22 | dnolen_ | apricity: once evaluated you should see the result immediately - you probably evaluated an infinite sequence - it will never return |
| 10:23 | dnolen_ | apricity: it should normally far as I know |
| 10:23 | apricity | it's not an infinite loop; I just kept increasing the input size slowly to try and get a feel for the asymptotic time complexity |
| 10:25 | apricity | i am just new to clojure and emacs and was wondering how to tell if it's still running, how to tell it to stop, and if there is any debuggin features like breakpoints that i could use |
| 10:30 | apricity | I found that C-c C-b interupts any pending evaluations |
| 10:39 | stephenmac7 | Okay, so I'm trying to solve a problem on 4clojure but it says: |
| 10:39 | stephenmac7 | "You tripped the alarm! nth is bad!" |
| 10:39 | stephenmac7 | Any idea how to fix that? |
| 10:40 | SagiCZ1 | stephenmac7: dont use nth in your solution |
| 10:40 | stephenmac7 | SagiCZ1: My solution is: |
| 10:40 | stephenmac7 | (fn disgusting-name-because-4clojure-has-issues [[x & xs] cnt] (if (= cnt 0) x (disgusting-name-because-4clojure-has-issues xs (- cnt 1)))) |
| 10:41 | SagiCZ1 | ok i dont see any nth in there |
| 10:41 | stephenmac7 | (Originally it was called my-nth |
| 10:41 | stephenmac7 | ) |
| 10:41 | SagiCZ1 | you dont need to name the function in 4clojure btw.. (fn [args] ... ) is fine |
| 10:41 | stephenmac7 | SagiCZ1: Yes, but then I can't call myself |
| 10:42 | stephenmac7 | Unless I do something stupid like use the y-combinator |
| 10:42 | dnolen_ | stephenmac7: destructuring vector syntax macroexpands into calls to nth |
| 10:42 | SagiCZ1 | i think you can do that using recur |
| 10:42 | dnolen_ | stephenmac7: recur |
| 10:42 | stephenmac7 | What is this recur? |
| 10:42 | stephenmac7 | (Sorry, I'm new to clojure, not fp) |
| 10:42 | SagiCZ1 | you can use it instead of the function name |
| 10:43 | dnolen_ | stephenmac7: self recursion |
| 10:43 | SagiCZ1 | if you want to use recursion.. which you do here |
| 10:43 | stephenmac7 | Oh, got it |
| 10:43 | dnolen_ | stephenmac7: w/o consuming stack |
| 10:43 | SagiCZ1 | but note, that if recur is in a 'loop' block, it will recur to the begining of the 'loop'.. not to the function |
| 10:43 | stephenmac7 | So, is that better than using the real name? |
| 10:43 | stephenmac7 | Unless I'm in a loop? |
| 10:44 | SagiCZ1 | stephenmac7: it may be less readible but uses no memory, so you can recur any number of times without stack explosion |
| 10:44 | stephenmac7 | dnolen_: So, how would I go about getting the head without using destructuring? |
| 10:44 | SagiCZ1 | stephenmac7: use (first..) |
| 10:44 | SagiCZ1 | ,(first [42 5 6 3]) |
| 10:44 | stephenmac7 | Ah, it's called first not head |
| 10:44 | clojurebot | 42 |
| 10:44 | stephenmac7 | Why can't they just check the code instead of the expansion? |
| 10:45 | SagiCZ1 | stephenmac7: they dont check the code at all.. they just subsitute your function for the ___ and run the code |
| 10:45 | stephenmac7 | If they don't check, how would they know it expands to nth? |
| 10:45 | stephenmac7 | Do they just check if nth itself is called? |
| 10:45 | SagiCZ1 | i guess they expand it first and then check the blacklisted symbols |
| 10:46 | stephenmac7 | Hm. |
| 10:46 | stephenmac7 | How would I get the tail? |
| 10:46 | SagiCZ1 | stephenmac7: last |
| 10:47 | SagiCZ1 | ,(last [1 2 3 42]) |
| 10:47 | clojurebot | 42 |
| 10:47 | stephenmac7 | That's the last element, not the tail |
| 10:47 | SagiCZ1 | ,(next [1 2 3 42]) |
| 10:47 | clojurebot | (2 3 42) |
| 10:47 | SagiCZ1 | ,(rest [1 2 3 42]) |
| 10:47 | stephenmac7 | ,(let [[x & xs] [1 2 3 42]]) xs) |
| 10:47 | clojurebot | nil |
| 10:47 | clojurebot | (2 3 42) |
| 10:47 | stephenmac7 | So, next and rest |
| 10:47 | SagiCZ1 | yes, they are the same but differ in their behavior when the collection is empty |
| 10:47 | SagiCZ1 | ,(rest []) |
| 10:47 | clojurebot | () |
| 10:48 | SagiCZ1 | ,(next []) |
| 10:48 | clojurebot | nil |
| 10:48 | stephenmac7 | So (fn [xs cnt] (if (= cnt 0) (first xs) (recur (next xs) (- cnt 1)))) |
| 10:48 | stephenmac7 | I see |
| 10:48 | stephenmac7 | Rest looks nicer though |
| 10:48 | stephenmac7 | Actually, nevermind |
| 10:48 | stephenmac7 | ,(rest [1]) |
| 10:48 | clojurebot | () |
| 10:48 | stephenmac7 | ,(rest []) |
| 10:48 | clojurebot | () |
| 10:48 | stephenmac7 | ^ I don't like that |
| 10:49 | SagiCZ1 | yeah so maybe you would like next |
| 10:49 | stephenmac7 | ,(next [1]) |
| 10:49 | clojurebot | nil |
| 10:49 | stephenmac7 | , |
| 10:49 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 10:49 | stephenmac7 | ,(next []) |
| 10:49 | clojurebot | nil |
| 10:49 | stephenmac7 | Just as bad |
| 10:49 | stephenmac7 | Why can't next give me an empty list for [1]? |
| 10:50 | stephenmac7 | If [1] is somewhat like (cons 1 '()) or whatever cons is in cljoure |
| 10:50 | stephenmac7 | *clojure |
| 10:50 | SagiCZ1 | i dont think clojure vectors are the same as lisp's lists |
| 10:51 | stephenmac7 | Fine |
| 10:51 | stephenmac7 | ,(next '(1)) |
| 10:51 | clojurebot | nil |
| 10:51 | stephenmac7 | I think those are like lisp's lists |
| 10:51 | SagiCZ1 | i guess |
| 10:52 | stephenmac7 | Well, guess I'll just have to deal |
| 10:55 | dnolen_ | stephenmac7: vectors are not like lists, random access |
| 10:55 | dnolen_ | [] is not an empty list, it's an empty vectro |
| 10:55 | dnolen_ | () is an empty list |
| 11:29 | justin_smith | stephenmac7: () is an empty list, linked list like in common lisp or scheme. [] is a vector, which has efficient random access and efficient append, and is implemented as a tree |
| 11:35 | zand | Noob question for you all: is it possible to return multiple vales NOT in a collection? |
| 11:35 | justin_smith | no |
| 11:35 | SagiCZ1 | zand: no |
| 11:35 | zand | ah ok |
| 11:35 | SagiCZ1 | zand: clojure returns always just one value |
| 11:36 | zand | so if I want to pass args (to apply for example) how would you do that? |
| 11:36 | justin_smith | with a collection. A collection is just one value. |
| 11:36 | zand | e.g I want to be able to do (apply [+ '(1 2 3)]) |
| 11:36 | AimHere | ,(apply + 1 2 3) |
| 11:36 | SagiCZ1 | ,(apply + '(1 2 3)) |
| 11:36 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 11:36 | clojurebot | 6 |
| 11:37 | mmg | Justin_smith |
| 11:37 | mmg | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentList.java#L100 |
| 11:37 | mmg | looks like a linked list |
| 11:38 | justin_smith | mmg: that's what I said |
| 11:38 | SagiCZ1 | mmg: which is what lisp list is |
| 11:38 | justin_smith | ,(type []) |
| 11:38 | clojurebot | clojure.lang.PersistentVector |
| 11:38 | justin_smith | ,(type (list 1 2 3)) |
| 11:38 | clojurebot | clojure.lang.PersistentList |
| 11:38 | mmg | oh whoops, misread your reply thought it was a question >.> |
| 11:57 | stephenmac7 | justin_smith: Thanks for the info |
| 11:58 | stephenmac7 | But why on earth can [] hold values of different types? |
| 11:58 | SagiCZ1 | clojure is dynamic languag |
| 11:59 | SagiCZ1 | it has no type checking before runtime |
| 12:00 | justin_smith | SagiCZ1: that's not strictly true. Some things are checked. but vectors are only defined to hold Object. |
| 12:00 | justin_smith | for example (nil x) is caught at compile time |
| 12:00 | justin_smith | &(if true 'x (nil 'x)) |
| 12:00 | lazybot | java.lang.IllegalArgumentException: Can't call nil |
| 12:01 | justin_smith | clearly a compile time error, see? |
| 12:01 | SagiCZ1 | ok.. so IFn is checked |
| 12:01 | justin_smith | not quite |
| 12:01 | justin_smith | &(if true 'x ("hello" 'x)) |
| 12:01 | lazybot | ⇒ x |
| 12:01 | justin_smith | no compile time check for IFn, just for calling nil |
| 12:02 | justin_smith | ,(into-array String ["hello" "world"]) ; other things are checked too |
| 12:02 | clojurebot | #<String[] [Ljava.lang.String;@5b20be> |
| 12:02 | justin_smith | ,(into-array String ["hello" |
| 12:02 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 12:02 | justin_smith | ,(into-array String ["hello" 42]) |
| 12:02 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: array element type mismatch> |
| 12:03 | justin_smith | wait, never mind, that is not a compile time check, it's a run time check |
| 12:30 | leandro | hi. i want to read a map which key is a (read-line). how to do that? (get mymap :(read-line)) :( |
| 12:31 | justin_smith | leandro: what do you think : does? |
| 12:31 | SagiCZ1 | the key is the function read-line? |
| 12:33 | leandro | i want to give the key via read-line |
| 12:33 | justin_smith | leandro: :foo is read by the clojure reader as "the keyword foo" - this can be convenient for maps, but you don't need keywords |
| 12:33 | justin_smith | ,(get {"hello |
| 12:33 | lxsameer | hey guys, my lein freeze without any output , how can I debug this |
| 12:33 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 12:33 | justin_smith | err |
| 12:33 | justin_smith | ,(get {"hello" 1} "hello") |
| 12:33 | clojurebot | 1 |
| 12:33 | justin_smith | slippy fingers today |
| 12:34 | leandro | hmm ok |
| 12:35 | justin_smith | &(get {"hello" 1} (binding [*in* (java.io.BufferedReader. (java.io.StringReader. "hello\n"))] (read-line))) |
| 12:35 | lazybot | java.lang.SecurityException: You tripped the alarm! push-thread-bindings is bad! |
| 12:35 | justin_smith | blurg |
| 12:35 | justin_smith | anyway, that also returns 1 |
| 12:36 | justin_smith | lxsameer: you can use jstack, which comes with the jdk, to see what the jvm is doing |
| 12:36 | justin_smith | lxsameer: or jvisualvm, if you want a full on visual tool that also includes that info |
| 12:37 | lxsameer | justin_smith: cool, thanks |
| 12:37 | leandro | justin_smith: with a string instead of a keyword works fine, but i'm still curious about how interpolate a value for a keyword |
| 12:38 | justin_smith | ,(get {:hello 1} (keyword "hello")) |
| 12:38 | clojurebot | 1 |
| 12:38 | justin_smith | but really you don't need keywords as often as many clojure programmers think you do |
| 12:38 | justin_smith | use keywords for literals, outside input can stay strings |
| 12:38 | SagiCZ1 | ,(keyword "string") |
| 12:38 | clojurebot | :string |
| 12:39 | justin_smith | ,(name :keyword) :P |
| 12:39 | clojurebot | "keyword" |
| 12:39 | leandro | amazing, thanks |
| 12:40 | justin_smith | name / keyword / symbol are universal converters between any two of those types |
| 12:40 | justin_smith | well actually not quite ##(symbol (name :key)) |
| 12:40 | lazybot | ⇒ key |
| 12:40 | justin_smith | you need name in the middle sometimes |
| 13:00 | stephenmac7 | Is there a foldl for clojure? |
| 13:03 | justin_smith | it's easy to write one for vectors, but no |
| 13:04 | stephenmac7 | justin_smith: Okay, thanks. Also is there something like conj but with flipped args? |
| 13:04 | justin_smith | cons for lists, but nothing for vectors |
| 13:04 | stephenmac7 | Finally, a real lisp function in clojure |
| 13:04 | stephenmac7 | cons actually exists |
| 13:05 | stephenmac7 | ,(cons 1 '(2 3 4)) |
| 13:05 | clojurebot | (1 2 3 4) |
| 13:05 | justin_smith | expecting clojure to be just like lisp will make you miss most of the best things about clojure |
| 13:05 | justin_smith | I was a common lisp user before I came to clojure myself |
| 13:06 | stephenmac7 | justin_smith: Actually, the only experience I have with lisp is reading the little schemer and the beginning of the land of lisp |
| 13:06 | stephenmac7 | I'm a Haskell user myself, but decided it would be nice to know a JVM language |
| 13:06 | justin_smith | stephenmac7: my vector-specific foldl https://www.refheap.com/94848 |
| 13:06 | stephenmac7 | So, adding to the front of a list feels natural |
| 13:07 | justin_smith | ,(conj '(1 2 3) 0) |
| 13:07 | clojurebot | (0 1 2 3) |
| 13:07 | justin_smith | conj adds wherever adding would be most efficient |
| 13:07 | justin_smith | most efficient is specific to the data structure |
| 13:07 | stephenmac7 | ,(conj [1 2 3] 4) |
| 13:07 | clojurebot | [1 2 3 4] |
| 13:07 | justin_smith | right |
| 13:07 | stephenmac7 | That's weird |
| 13:07 | justin_smith | no, it's efficient |
| 13:08 | stephenmac7 | Why not just have two functions? |
| 13:08 | justin_smith | like most things in clojure, conj is not specific to a datatype or class, it is aimed at an interface |
| 13:08 | justin_smith | the interface being that for persistent collections |
| 13:08 | justin_smith | ,(conj {:a 0} [:b 1]) |
| 13:08 | clojurebot | {:b 1, :a 0} |
| 13:09 | justin_smith | ,(conj {1 2 3 4 5} 6 7) |
| 13:09 | clojurebot | #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms> |
| 13:09 | justin_smith | oops |
| 13:09 | justin_smith | ,(conj #{1 2 3 4 5} 6 7) |
| 13:09 | clojurebot | #{7 1 4 6 3 ...} |
| 13:09 | justin_smith | ,(conj () :a :b :c) |
| 13:09 | clojurebot | (:c :b :a) |
| 13:10 | ctford | Personally, I think it would be nice if conj was paired with an unconj - it's not much of a contract if you have to be aware of the concrete type whenever you use it. |
| 13:10 | stephenmac7 | Hm. Haven't worked with a language with polymorphic functions for a while, except when it replated to typeclasses. |
| 13:10 | stephenmac7 | Feels weird |
| 13:10 | stephenmac7 | *relates |
| 13:11 | justin_smith | ctford: you only have to be aware if you care about where insertions happen. And if you care about where you are inserting, you should be conscious of your collection type whether you use conj or not. |
| 13:12 | ctford | justin_smith, you always care about where the insertion happens sooner or later, don't you? Otherwise, conj could be noop and you wouldn't notice. |
| 13:12 | justin_smith | ctford: the thing conj always does is ensure the result contains the argument added to the collection provided |
| 13:12 | ctford | the only way you could not have to care is if there were a read function on the interface, and a contract on how they interact. |
| 13:13 | justin_smith | that's a contract |
| 13:13 | ctford | justin_smith, true. |
| 13:13 | stephenmac7 | So, if I wanted to reverse a list or array, it would probably not be the best idea to use conj without checking the type |
| 13:13 | justin_smith | checking or forcing it yeah |
| 13:13 | ctford | justin_smith: I guess I rarely get by with simply knowing the entry is somewhere in the collection. :-) |
| 13:14 | justin_smith | stephenmac7: vec and seq and set are your friends |
| 13:14 | justin_smith | ,(seq [1 2 3]) |
| 13:14 | clojurebot | (1 2 3) |
| 13:14 | justin_smith | ,(set [1 2 3]) |
| 13:14 | clojurebot | #{1 3 2} |
| 13:14 | justin_smith | ,(vec [1 2 3]) |
| 13:14 | clojurebot | [1 2 3] |
| 13:14 | stephenmac7 | What if I'm trying to preserve the type? |
| 13:15 | ctford | justin_smith: I guess you could say that seq shares a contract with conj - if you conj it in, it will be somewhere in the resulting seq. |
| 13:15 | justin_smith | ,(map (fn [x] (into (empty x) (conj (seq x) :a))) [[:b :c :d] '(:b :c :d) #{:b :c :d}]) |
| 13:15 | clojurebot | ([:a :b :c :d] (:d :c :b :a) #{:c :b :d :a}) |
| 13:16 | stephenmac7 | So, (= (reverse [1 2 3]) [3 2 1]) and (= (reverse '(1 2 3)) '(3 2 1)) |
| 13:16 | stephenmac7 | ,(reverse [1 2 3]) |
| 13:16 | clojurebot | (3 2 1) |
| 13:16 | justin_smith | stephenmac7: probably best to start with seq |
| 13:16 | stephenmac7 | ,(vec (reverse [1 2 3])) |
| 13:16 | clojurebot | [3 2 1] |
| 13:16 | justin_smith | seq is cheap on every input type |
| 13:17 | justin_smith | then you can use into |
| 13:17 | justin_smith | into / empty to preserve type |
| 13:17 | stephenmac7 | ,(doc into) |
| 13:17 | clojurebot | "([to from] [to xform from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined. A transducer may be supplied." |
| 13:19 | m1dnight_ | Does anyone know any better way to do: map a function over a sequence, if i find a particular element, replace it, if not, add something in the end of sequence |
| 13:19 | m1dnight_ | what I'll do now is iterate to check if the particular element is there and then do a map in the consequent branch and an insert in the alternative |
| 13:19 | stephenmac7 | Hm. justin_smith: Seems I don't need to preserve type |
| 13:19 | jeff___ | Have any of you guys that work at java shops been able to convince management to let you use clojure on the job? |
| 13:19 | stephenmac7 | = doesn't seem to check types |
| 13:19 | m1dnight_ | jeff___: I believe gfredericks did so |
| 13:20 | justin_smith | stephenmac7: no, it does not ##(= [1 2 3] '(1 2 3)) |
| 13:20 | lazybot | ⇒ true |
| 13:20 | stephenmac7 | In that case, I can just use seq |
| 13:20 | Fare | hi |
| 13:21 | Fare | does a type hint ^T say that nil is accepted as part of T, or excluded? |
| 13:21 | jeff___ | gfredericks: are you around? |
| 13:21 | Fare | is there a way to distinguish nullable and not-nullable? |
| 13:21 | stephenmac7 | Don't even need seq |
| 13:21 | justin_smith | Fare: all classes are nullable on the jvm |
| 13:21 | stephenmac7 | ,((partial reduce conj '()) [1 2 3]) |
| 13:21 | clojurebot | (3 2 1) |
| 13:22 | stephenmac7 | ,((partial reduce conj '()) {1 2 3}) |
| 13:22 | clojurebot | #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms> |
| 13:22 | stephenmac7 | ,((partial reduce conj '()) #{1 2 3}) |
| 13:22 | clojurebot | (2 3 1) |
| 13:22 | justin_smith | ,(#(into () %) [1 2 3]) |
| 13:22 | clojurebot | (3 2 1) |
| 13:22 | stephenmac7 | ,(seq #{1 2 3}) |
| 13:22 | clojurebot | (1 3 2) |
| 13:22 | justin_smith | stephenmac7: ##(= '() ()) |
| 13:22 | lazybot | ⇒ true |
| 13:23 | stephenmac7 | Why doesn't it have to be quoted? |
| 13:23 | justin_smith | it's unambiguous - it couldn't be a function call |
| 13:23 | Fare | so it's OK to declare ^String x and bind x to nil. |
| 13:23 | stephenmac7 | But we can't do |
| 13:24 | stephenmac7 | ,(= (hotdogs) '(hotdogs)) |
| 13:24 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: hotdogs in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 13:24 | stephenmac7 | ,(= (:hotdogs) '(:hotdogs)) |
| 13:24 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :hotdogs> |
| 13:24 | stephenmac7 | Got it |
| 13:24 | justin_smith | stephenmac7: it's special cased for the empty list |
| 13:24 | stephenmac7 | ,((partial into ()) [1 2 3]) |
| 13:24 | clojurebot | (3 2 1) |
| 13:25 | justin_smith | if you know how many args you are getting, partial is wasteful |
| 13:25 | stephenmac7 | What do you mean? |
| 13:25 | justin_smith | it creates a varargs function, and puts the args into a list |
| 13:25 | stephenmac7 | Oh. |
| 13:25 | justin_smith | you don't need to do any of that if you know how many args you are getting |
| 13:26 | justin_smith | also #(foo %) is more concise than (partial foo) |
| 13:26 | stephenmac7 | ,((fn [xs] (into () xs)) [1 2 3]) |
| 13:26 | clojurebot | (3 2 1) |
| 13:26 | justin_smith | you don't like #() syntax? |
| 13:26 | stephenmac7 | What's this #()? |
| 13:26 | justin_smith | ,'#(+ % %) |
| 13:26 | clojurebot | (fn* [p1__51#] (+ p1__51# p1__51#)) |
| 13:26 | justin_smith | it's a reader shorthand for anonymous functions |
| 13:27 | stephenmac7 | Nice |
| 13:27 | stephenmac7 | I don't like the % sign though |
| 13:27 | stephenmac7 | Is there an alternative? |
| 13:27 | justin_smith | no |
| 13:28 | stephenmac7 | Hm. |
| 13:28 | stephenmac7 | ,(#(into () %) [1 2 3]) |
| 13:28 | clojurebot | (3 2 1) |
| 13:28 | stephenmac7 | Interesting |
| 13:29 | justin_smith | (fn [x] (into () x)) is the same thing, just more verbose, so I guess that is an alternative of sorts |
| 13:29 | stephenmac7 | No, this is a little better still |
| 13:29 | stephenmac7 | at least for code golf, if anything :) |
| 13:29 | justin_smith | it took me a long time to accept #(), precisely because # and % are so clumsy to read |
| 13:30 | stephenmac7 | Then again... |
| 13:30 | stephenmac7 | ,(into () [1 2 3]) |
| 13:30 | clojurebot | (3 2 1) |
| 13:30 | stephenmac7 | Guess I didn't really have to make a function at all |
| 13:31 | justin_smith | even better, if you can get away with it |
| 13:31 | stephenmac7 | It's just 4clojure |
| 13:31 | stephenmac7 | TBH, I don't like the way they do this. It would be nice if you had to write an actual function |
| 13:32 | stephenmac7 | that isn't in the scope of the actual problem |
| 13:32 | justin_smith | I use an fn for every answer on there myself |
| 13:34 | stephenmac7 | I'm kind of liking clojure, but this lack of types makes me feel insecure :P |
| 13:35 | justin_smith | stephenmac7: I like prismatic/schema for type data structure declarations that are strictly opt in, and runtime checks that I can turn on if I choose. But it's not the same as static checks, of course. |
| 13:36 | stephenmac7 | I looked that up and saw something called clojurescript |
| 13:36 | stephenmac7 | What is that? |
| 13:37 | justin_smith | it is clojure, compiled to javascript |
| 13:37 | stephenmac7 | Interesting. |
| 13:37 | justin_smith | largely but not completely compatible with jvm clojure |
| 13:37 | justin_smith | you still need jvm clojure to compile clojurescript |
| 13:38 | justin_smith | there is also clojureclr for the .net runtime, which does not need the jvm clojure to compile |
| 13:39 | stephenmac7 | Hm. Haven't really looked into these things) |
| 13:39 | stephenmac7 | *. |
| 13:39 | stephenmac7 | The parenthesis are taking over my keyboard |
| 13:39 | justin_smith | in fact targetting clr is almost as old as targetting the jvm |
| 13:40 | stephenmac7 | (write '(might as well) '(in lispy style)) |
| 13:40 | stephenmac7 | justin_smith: Anyway, thanks for your help and time |
| 13:41 | justin_smith | np |
| 13:41 | stephenmac7 | Obviously, I'm missing a bit of info about clojure |
| 13:41 | stephenmac7 | Leraning the language, not the background or ecosystem, probably isn't the best |
| 13:41 | justin_smith | stephenmac7: did you see this recent post? http://getprismatic.com/story/1418367480649?share=MTg0Mjc4.MTQxODM2NzQ4MDY0OQ.Z5zi6GfaVZ8NuO8Ma-09w0f6USI |
| 13:42 | justin_smith | some great resources there (some of which you already know) |
| 13:42 | stephenmac7 | Yes, I'm reading "Clojure for the Brave and True" |
| 13:42 | stephenmac7 | But the rest looks interesting |
| 13:43 | stephenmac7 | Never had a list like that for Haskell, it was "read LYAH then read haddock" |
| 13:43 | justin_smith | bitemyapp has a good set of intro resources. He used to hang out here until he decided he hated clojure. |
| 13:44 | justin_smith | ~haskell |
| 13:44 | clojurebot | haskell is pharaonic mass slave labour |
| 13:44 | justin_smith | ?wat |
| 13:44 | justin_smith | ~haskell |
| 13:44 | clojurebot | haskell is pharaonic mass slave labour |
| 13:44 | justin_smith | there was an old factoid "you can only talk about haskell after 9 pm PST" or something like that, specifically targetted at bitemyapp when he hung out here |
| 13:45 | stephenmac7 | pharonic mass slave labor? |
| 13:45 | stephenmac7 | ~ruby |
| 13:45 | clojurebot | Chunky bacon! |
| 13:45 | awkorama | ~ada |
| 13:45 | stephenmac7 | Interesting |
| 13:45 | clojurebot | It's greek to me. |
| 13:45 | stephenmac7 | ~clojure |
| 13:45 | clojurebot | clojure is music |
| 13:45 | stephenmac7 | Ofc |
| 13:45 | stephenmac7 | ~assembly |
| 13:45 | clojurebot | Cool story bro. |
| 13:45 | arrdem | o/ |
| 13:45 | stephenmac7 | ~fun-with-the-bot |
| 13:45 | clojurebot | Gabh mo leithscéal? |
| 13:46 | chef__ | ~scheme |
| 13:46 | clojurebot | scheme is Scheme is like a ball of snow. You can add any amount of snow to it and it still looks like snow. Moreover, snow is cleaner than mud. |
| 13:46 | stephenmac7 | ~clisp |
| 13:46 | clojurebot | I don't understand. |
| 13:46 | stephenmac7 | Doesn't like that |
| 13:46 | stephenmac7 | ~python |
| 13:46 | stephenmac7 | Really doesn't like that |
| 13:46 | stephenmac7 | Anyway, thanks |
| 13:47 | justin_smith | it does rate limiting |
| 13:48 | stephenmac7 | Hm. |
| 13:48 | stephenmac7 | ~python |
| 13:48 | stephenmac7 | Still too much for it |
| 14:05 | m1dnight_ | Okay, i'm having the (list?) issue when it's a Cons |
| 14:05 | m1dnight_ | is there a higher level check I can use? |
| 14:06 | m1dnight_ | Or do I have to find out where I cons'd instead of conj'd? |
| 14:06 | justin_smith | m1dnight_: list? is never what you want |
| 14:06 | m1dnight_ | :( |
| 14:06 | m1dnight_ | i'm sorry sensei, but what do I do then? |
| 14:06 | justin_smith | ,(list? (list 1 2 3)) |
| 14:06 | clojurebot | true |
| 14:06 | m1dnight_ | ,(list? (cons 1 (cons 1 nil))) |
| 14:06 | clojurebot | false |
| 14:06 | m1dnight_ | it's of type Cons |
| 14:06 | justin_smith | ,(seq? (cons 1 (cons 2 nil))) |
| 14:06 | clojurebot | true |
| 14:07 | m1dnight_ | ooooh :) |
| 14:07 | m1dnight_ | that's what I needed |
| 14:07 | justin_smith | ,(seq? [1 2 3]) |
| 14:07 | clojurebot | false |
| 14:07 | m1dnight_ | thanks a bunch justin smith |
| 14:07 | justin_smith | np |
| 14:07 | m1dnight_ | (inc justin_smith) |
| 14:07 | lazybot | ⇒ 159 |
| 14:08 | justin_smith | (identity rritoch) |
| 14:08 | lazybot | rritoch has karma 1. |
| 14:08 | m1dnight_ | (identity m1dnight_) |
| 14:08 | lazybot | m1dnight_ has karma 1. |
| 14:08 | m1dnight_ | what, I have one? |
| 14:09 | m1dnight_ | cool \o/ |
| 14:09 | arrdem | justin_smith: WE DO NOT SPEAK ITS NAME |
| 14:09 | justin_smith | (identity m1dnight) |
| 14:09 | lazybot | m1dnight has karma 1. |
| 14:09 | justin_smith | (identity identity) |
| 14:09 | lazybot | identity has karma 0. |
| 14:30 | munderwo | Hey all. How have people best dealt with callback hell in javascript interop. I’ve seen some people use core.async but im having issues getting that work and nice and clean. |
| 14:31 | munderwo | I have a javascript lib that requires three levels of callbacks to get what I want. which is ya know a little frustrating. |
| 14:31 | SagiCZ1 | channels should help you though |
| 14:31 | SagiCZ1 | they were designed to make callbacks more straightforward |
| 14:32 | justin_smith | munderwo: even if you must provide a callback, the callback can just be a function that puts a value on a channel, the logic can all be in a go block if you do it right |
| 14:32 | munderwo | thats what I thought. So I guess one way is to pass c channel all the way to the bottom? |
| 14:33 | munderwo | and the last function puts a value on it? Then in a go block I just do a <! to get that value off and continue? |
| 14:34 | justin_smith | right, you could even do a series of <! calls in the go block, for the various stages of nested callback |
| 14:35 | SagiCZ1 | on other note, could someone explain to me the naming convenctions for core.async? if is in clojure.core why do i have to manually require it? so its not in the core? is it 3rd party? |
| 14:35 | justin_smith | SagiCZ1: core.* means blessed by rhickey |
| 14:35 | munderwo | yeah, I got the first way working. and Im just trying to get the second to work, by having each seperate function return a channel in one big let block. |
| 14:35 | justin_smith | core.typed, core.match, core.async |
| 14:35 | SagiCZ1 | blessed but not actually part of the core |
| 14:35 | justin_smith | right |
| 14:35 | SagiCZ1 | thanks for clarification |
| 14:36 | justin_smith | org.clojure/core.* |
| 14:37 | munderwo | this is what I have at the moment for version 2. |
| 14:37 | munderwo | https://www.refheap.com/94852 |
| 14:37 | munderwo | But I seem to be getting a channel from it rather than the file blob that I want. |
| 14:38 | munderwo | Im wondering if in all the functions I should just be returning the chan instead of doing the (go (<! c)) |
| 14:38 | justin_smith | I think that would simplify things - only need the (go (<! c)) for test |
| 14:38 | justin_smith | the rest can just pass chans |
| 14:43 | munderwo | right. |
| 14:44 | munderwo | I think I might be starting to understand core.async in clojurescript. Its actually quite different to the clojure version |
| 14:45 | munderwo | what I ended up with |
| 14:45 | munderwo | https://www.refheap.com/94853 |
| 14:45 | munderwo | It would be nice to be able to remove the <! from the test function… buuutt I dont think thats gonna happen |
| 14:46 | munderwo | It is one of the interesting things about using core.async in clojurescript, It kinda infects the codebase. |
| 14:48 | justin_smith | it does that in general (but more so in cljs) |
| 14:48 | justin_smith | which is part of why there are ztellman/manifold and prismatic/graph which do similar things in different ways (and infect codebases less) |
| 14:48 | justin_smith | ztellman's talk at the last conj is a nice comparison between the three |
| 14:51 | brucehauman | man I am having a heck of a time with clojure namespace resolution in a leinigen plugin |
| 14:56 | brucehauman | figured it out :) |
| 15:30 | lxsameer | hey guys, My lein freeze with no output. I get the traceback by jstack and here it is http://dpaste.com/0360P3M what's the problem how can i fix it ? |
| 15:45 | gfredericks | lxsameer: looks like it's waiting on some sort of maven io thing |
| 15:46 | gfredericks | not sure about the how to fix it part |
| 15:46 | lxsameer | gfredericks: hmmm, very weird |
| 15:52 | martinklepsch | Is there some time I should expect clojars to need until it can verify my pgp key via a keyserver? |
| 15:59 | arrdem | If you've pushed to MIT or any of the usual PGP keyservers it should be pretty much instintaneous. |
| 16:11 | martinklepsch | so what other reasons can there be for 401, ReasonPhrase:Unauthorized when deploying to clojars? |
| 16:12 | martinklepsch | I think I got the gpgthing right, checked my ssh public key on clojars and if I have the private key in ~/.ssh |
| 16:12 | arrdem | are you trying to upload over https? |
| 16:13 | arrdem | because IIRC that's off right now |
| 16:18 | martinklepsch | arrdem: that could be the reason |
| 16:24 | martinklepsch | arrdem: over https I got the error above, http gives me 405, ReasonPhrase:Not Allowed |
| 16:25 | arrdem | martinklepsch: yeah I think that's expected. try uploading over ssh |
| 17:05 | stbg | hey there I am wondering if someone can provide some light into a NullPointer exception I am having |
| 17:08 | andyf | stbg: If you put some details in a paste and explain some context of how it occurs, and perhaps a stack trace, someone might be able to help. |
| 17:08 | arrdem | ~anyone applies but I can't activate it because reasons |
| 17:10 | stbg | @andyf yap I have it right here http://pastebin.com/JyJ73NaY |
| 17:11 | stbg | The code actually does what it needs to but I think when the recursion unwinds a null pointer exception gets thrown out of n owhere |
| 17:11 | andyf | Which is line 53 in your source? |
| 17:12 | stbg | (insert-triad (assoc-in triad (conj letters letter) {}) (conj letters letter) (inc pos) word) |
| 17:12 | stbg | or 14 in the pastebin |
| 17:13 | dagda1 | what do tansducers give us that are not already possible with functional composition or the threading macro? |
| 17:16 | stbg | andyf: line 8 in the pastebin should actually be uncommented |
| 17:17 | SagiCZ1 | dagda1: from my understanding, they are one more level of abstraction |
| 17:17 | SagiCZ1 | you could ask what clojure gives us that is not already possible with language x |
| 17:17 | SagiCZ1 | probably nothing |
| 17:18 | dagda1 | SagiCZ1: I'm just trying to find out why they came about or what problem they solve |
| 17:18 | SagiCZ1 | dagda1: they abstract data transformations |
| 17:19 | dagda1 | SagiCZ1: a trasform being a functional composition |
| 17:20 | tbaldridge | dagda1: if you go and write map or filter from scratch, only using cons, you'll notice that inside map is a call to cons. Transducers abstract away cons (or actually conj) so that the creation of the resulting datastructure is decoupled from the map/filter logic |
| 17:21 | dagda1 | tbaldridge: so I could replace conj with some other function? |
| 17:21 | tbaldridge | right, like conj! or put! into a core.async buffer, or something else |
| 17:22 | tbaldridge | but it's all abstracted, so you can create a transform once, and use it with multiple creation functions (known as reducing functions). |
| 17:22 | tbaldridge | examples of reducing functions are conj, conj!, +, etc. |
| 17:23 | sveri | Hi, is there some documentation for luminus on how to respond with bytecode for a route? |
| 17:24 | dagda1 | tbaldridge: do you know why xform is often used as an argument name in the transducer examples? |
| 17:25 | andyf | stbg: You have an extra set of parentheses around the arguments of the "do". Thus the return value of the recursive call is attempted to be invoked as a function. |
| 17:26 | andyf | And that pastebin site you used makes my browser CPU spike. Maybe ads. |
| 17:27 | stbg | andyf: Thanks I see it, that's what I get for working late at night, sorry about pastebin, which one do you use? |
| 17:27 | andyf | gist.github.com, but there are a bunch of them. The CPU spike isn't the end of the world -- just kinda weird. |
| 17:28 | tbaldridge | dagda1: xform is a transducer (aka a transform), when you're ready to use a xform transduce will call (xform rf) to create the final reducing function |
| 17:28 | tbaldridge | dagda1: have you watched Rich Hickey's strangeloop talk? |
| 17:28 | tbaldridge | He goes over this sort of stuff |
| 17:28 | dagda1 | tbaldridge: I have not, I must do this. Thanks |
| 18:06 | oskarth | ,(remove (or #(= % 'a) #(= % 'b)) ['a 'b 'c]) |
| 18:06 | clojurebot | (b c) |
| 18:07 | oskarth | what am I missing? how do I compose multiple predicates? |
| 18:07 | tbaldridge | ,(doc everyp) |
| 18:07 | clojurebot | Cool story bro. |
| 18:07 | tbaldridge | ehh...whats that fn called again... |
| 18:07 | oskarth | ,(doc every-pred) |
| 18:07 | clojurebot | "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns true if all of its composing predicates return a logical true value against all of its arguments, else it returns false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical false result against the original predicates." |
| 18:08 | tbaldridge | but you want or, |
| 18:08 | Frozenlock | ,(remove #(or (= % 'a) (= % 'b)) ['a 'b 'c]) |
| 18:08 | clojurebot | (c) |
| 18:08 | Frozenlock | your 'or' returned the first function |
| 18:08 | oskarth | oh |
| 18:09 | oskarth | I see, thanks both :) |
| 18:09 | andyf | oskarth: some-fn is the "or" analog of every-pred |
| 18:10 | oskarth | ,(doc some-fn) |
| 18:10 | clojurebot | "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical true result against the original predicates." |
| 18:10 | andyf | The Clojure cheatsheet lists them next to each other: http://jafingerhut.github.io |
| 18:10 | oskarth | ah yeah |
| 18:10 | andyf | which only helps much if you remember the name of at least one of them :) |
| 18:11 | oskarth | in this case #(or ...) seems like the simplest solution |
| 18:11 | andyf | ,(remove '{#a b} '[a b c]) |
| 18:11 | clojurebot | #<RuntimeException java.lang.RuntimeException: No reader function for tag a> |
| 18:11 | andyf | ,(remove '#{a b} '[a b c]) |
| 18:11 | clojurebot | (c) |
| 18:11 | arrdem | if I fork Clojure, first thing imma do is rename some to any? |
| 18:12 | oskarth | oh, that's even nicer |
| 18:12 | andyf | be careful with nil/false there |
| 18:13 | andyf | but ok if those are not possibilities. |
| 18:13 | Frozenlock | ,(remove '#{a b nil} '[a b c nil]) |
| 18:13 | clojurebot | (c nil) |
| 18:13 | Frozenlock | nice gotcha |
| 18:14 | oskarth | hm yeah |
| 18:14 | andyf | ,(remove #(contains? '#{a b nil} %) '[a b c nil]) |
| 18:14 | clojurebot | (c) |
| 18:15 | arrdem | andyf: (partial contains ..) |
| 18:15 | andyf | some day I may have partial ingrained in my habits, but not yet |
| 18:15 | arrdem | I mean... partial does exactly the same thing since we don't actually have currying :C |
| 18:16 | andyf | ,(remove #(contains? '#{a b nil Double/NaN} '[a b c nil Double/NaN]) |
| 18:16 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 18:17 | andyf | ,(remove #(contains? '#{a b nil Double/NaN} %) '[a b c nil Double/NaN]) |
| 18:17 | clojurebot | (c) |
| 18:17 | andyf | Hmm. I thought that would not remove the Double/NaN, since it isn't even equal to itself. |
| 18:19 | andyf | ,(remove #(contains? '#{a b nil Double/NaN} %) ['a 'b 'c nil Double/NaN]) |
| 18:19 | clojurebot | (c NaN) |
| 18:20 | mikos | https://gist.github.com/anonymous/f6f51ca04658cc34174a |
| 18:20 | mikos | is there a better way to do this? |
| 18:20 | andyf | There. In my first example with Double/NaN, the ' outside the [] quoted it and made it a symbol. |
| 18:20 | mikos | the ifs in the let feel weird to me :) |
| 18:20 | andyf | anyway, deep dark corner case. Avoid Double/NaN if you can. |
| 18:21 | Frozenlock | mikos: why? |
| 18:21 | mikos | no idea, Frozenlock! just wondering if it's the best way :) |
| 18:22 | arrdem | mikos: the ifs are fine, just throw some newlines in there. |
| 18:22 | mikos | thanks, arrdem! |
| 18:22 | gfredericks | I'm trying to figure out how unicode works on the jvm and feel like I have a theory; does anybody know enough about it to sanity-check? |
| 18:22 | gfredericks | in particular I'm trying to figure out what regexes do |
| 18:23 | arrdem | mikos: if you really want to yack shave |
| 18:24 | mikos | yak shave, that's a new one for me! |
| 18:24 | mikos | i think i know what it means :) |
| 18:24 | arrdem | mikos: (as-> (:label crumb) v (cond-> (:active crumb) [:strong v])) |
| 18:24 | TEttinger | gfredericks, maybe I do? |
| 18:25 | arrdem | http://www.catb.org/jargon/html/Y/yak-shaving.html |
| 18:25 | arrdem | mikos: for this I'd keep the if, but the cond-> update pattern scales really really nicely to what would otherwise be a shitload of nested ifs doing updates. |
| 18:26 | arrdem | https://github.com/arrdem/spitfire/blob/master/src/spitfire/whac.clj#L510 |
| 18:26 | arrdem | case in point |
| 18:26 | andyf | mikos: left a comment of a modified version using :keys that shortens things a bit |
| 18:26 | mikos | thanks arrdem, andyf! |
| 18:27 | andyf | gfredericks: I know a little bit about it, but maybe not enough to check your theory. |
| 18:28 | gfredericks | TEttinger: andyf: okay here I go |
| 18:28 | gfredericks | so normal people use UTF-8 and the jvm uses UTF-16, which puts it at a disadvantage wrt the larger characters |
| 18:28 | TEttinger | non-BMP ones, yeah |
| 18:28 | gfredericks | so it's okay for \uFFFF and under |
| 18:29 | andyf | a disadvantage in that non-BMP are sorta rare, but different encoding lengths are common with UTF-8? |
| 18:29 | gfredericks | disadvantage only in being incomplete and/or difficult to describe |
| 18:29 | TEttinger | also java uses UCS-16 I think, not sure the difference |
| 18:30 | gfredericks | everything over \uFFFF is represented as a pair, with the high half \uD800-\UDBFF and the low half \UDC00-\UDFFF |
| 18:30 | gfredericks | which presumably means that a \uD800-\UDBFF character in isolation is some weird degenerate thing |
| 18:31 | andyf | TEttinger: According to UTF-16 wikipedia page, UCS-2 is "everything is 2 bytes long" and thus I think ignores everything not in the BMP, by not being able to encode it. |
| 18:31 | TEttinger | err, UCS-2 yeah |
| 18:31 | andyf | gfredericks: Yes, surrogate pairs in isolation are a sign of a bug somewhere, most likely |
| 18:31 | andyf | or bad data from elsewhere |
| 18:31 | gfredericks | ,(re-matches #"." "\ud800") |
| 18:31 | clojurebot | "?" |
| 18:31 | gfredericks | ,(re-matches #"." "\ud800\udc00") |
| 18:31 | clojurebot | "𐀀" |
| 18:31 | gfredericks | ,(re-matches #"." "\ud800\udb00") |
| 18:31 | clojurebot | nil |
| 18:32 | gfredericks | ^ these are some behaviors I have noted |
| 18:32 | gfredericks | ,(re-matches #".." "\ud800\udb00") |
| 18:32 | clojurebot | "??" |
| 18:32 | andyf | your 2nd example is matching the pair of Java chars? |
| 18:32 | gfredericks | it's one unicode char but two java chars |
| 18:32 | andyf | got it |
| 18:32 | gfredericks | so the regex intelligently recognizes it as one char |
| 18:32 | andyf | and 3rd example is invalid pair? |
| 18:32 | gfredericks | right |
| 18:32 | gfredericks | which DOES match as two chars |
| 18:33 | andyf | but strangely, not as one |
| 18:33 | gfredericks | kinda makes sense to me |
| 18:33 | gfredericks | you only get "two as one" for valid pairs |
| 18:33 | andyf | in an "I can guess how the implementation might have gone this way, given Java's history" |
| 18:33 | gfredericks | so I'm wondering if this is a decent summary of the edge cases |
| 18:33 | gfredericks | or is there a lot I'm missing somewhere |
| 18:35 | andyf | I don't know enough to say whether you've covered all of the edge cases, but perhaps you have. Generative testing with large fraction of non-BMP chars and invalid surrogate pairs might help verify. |
| 18:36 | andyf | I suspect if someone cares a whole lot about regex matching and large char sets, and avoiding edge cases, they use Perl. |
| 18:36 | andyf | Or a different regex matching library than Java's built-in one. |
| 18:37 | TEttinger | ,(char 0x100000000) |
| 18:37 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for char: 4294967296> |
| 18:37 | andyf | e.g. maybe ICU lib is better at saner behavior here: http://site.icu-project.org |
| 18:37 | andyf | but I haven't tested it to find out |
| 18:38 | gfredericks | okay thanks andyf && TEttinger |
| 18:38 | andyf | The Unicode property support column on this page may give some clues here: http://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines |
| 18:39 | TEttinger | this is interesting, andyf and gfredericks http://site.icu-project.org/home/why-use-icu4j |
| 18:40 | andyf | Tom Christiansen has thought more about this than I bet anyone, and has worked hard on Perl's regex matching in this area. He has filed bugs with the Java development team in this area, and realizes that some of these things take a long time and a lot of testing to get right. |
| 18:40 | gfredericks | ooh interesting |
| 18:42 | andyf | Also perhaps here: http://userguide.icu-project.org/strings/regexp#TOC-Differences-with-Java-Regular-Expressions |
| 18:43 | andyf | Maybe wait for Java 12? |
| 18:43 | andyf | :) |
| 18:43 | andyf | (i.e. perhaps by then the built-in regex support will support Unicode more completely) |
| 18:44 | andyf | Although to be fair, perhaps Java's built-in regex support is reasonable when restricted to strings that don't have unpaired surrogates. |
| 18:48 | andyf | gfredericks: Do you expect to get 'malformed' UTF-16 strings, i.e. having unpaired surrogates, in some application? Or can they be discarded or treated as errors? |
| 18:52 | gfredericks | andyf: I'm generating the strings, so I'm just trying to figure out what's reasonable |
| 18:53 | andyf | I suspect there are all kinds of weird things that can happen, not only with regexes, in many parts of the Java lib, if given strings that have unpaired or wrongly-paired surrogates. |
| 18:54 | gfredericks | speaking of which it looks like test.check only generates characters up to 255 o_O /cc reiddraper |
| 18:55 | andyf | Just as I expect you'd get errors if you have a file you attempt to decode using UTF-8 but the byte sequence is not a valid UTF-8 byte sequence. |
| 18:57 | amalloy | gfredericks: it's fine, though, because nobody's ever had errors caused by two-byte characters |
| 18:58 | andyf | amalloy: More likely, nobody wants to debug them, because the libs get in their way :) |
| 18:59 | gfredericks | so if there existed a gen-unicode-char generator, would it be reasonable for it to generate every 2-byte value except the surrogates, along with every valid pair? (i.e., high+low for everything in the high/low range respectively) |
| 19:00 | andyf | gfredericks: that sounds way more reasonable than allowing it to generate single-Java-char unpaired surrogates. |
| 19:03 | andyf | It might be nice to have it generate surrogate pairs with a larger probability than a uniform range would lead to, but I guess a uniform range over the whole Unicode code point range would mostly be surrogate pairs. |
| 19:07 | mi6x3m | clojure, is it possible that I get a cyclic depdency with a namespace that is fully empty? |
| 19:11 | andyf | Do you mean you want a "fully empty namespace", but you get a cyclic dependency when you try to create one? |
| 19:12 | mi6x3m | well it's not supposed to be empty |
| 19:12 | mi6x3m | but even when it is I get the error |
| 19:12 | mi6x3m | when I try to reference it |
| 19:12 | andyf | Or do you mean you get an error message about a cyclic dependency, but it is confusing because one namespace isn't printed? |
| 19:12 | mi6x3m | the namespaces involved are printed |
| 19:12 | amalloy | if you have two namespaces which both depend on each other, it doesn't matter if any of them are empty |
| 19:12 | mi6x3m | and the one in the middle is empty |
| 19:12 | amalloy | it's still a cycle |
| 19:13 | mi6x3m | amalloy: how could they depend on each other if one is empty? |
| 19:13 | andyf | empty, meaning the namespace exists, but has nothing defined in it, other than an ns form? |
| 19:13 | mi6x3m | yes |
| 19:13 | mi6x3m | only (ns viewer.example-src) |
| 19:14 | mi6x3m | it could be a counterclockwise issue |
| 19:16 | mi6x3m | I understand, it's no a dependency in the code |
| 19:16 | mi6x3m | it's a "load" dependency |
| 19:16 | mi6x3m | but I still see no cycle |
| 19:16 | andyf | I don't see how that could be part of a cycle |
| 19:17 | andyf | but best to check the other namespaces reported in the cycle to see if they contain one. |
| 19:18 | mi6x3m | [viewer/example]->viewer/example_src->[/viewer/example]->/viewer-core |
| 19:18 | mi6x3m | and example_src is empty |
| 19:22 | andyf | Can you require one of those namespaces without error from a plain lein repl, started from outside CCW? |
| 19:23 | mi6x3m | andyf: let me try that, thanks for the patience |
| 19:37 | mi6x3m | andyf: I found it |
| 19:37 | mi6x3m | and it's a rather bizare error |
| 19:37 | mi6x3m | I have a test namespace with the same name |
| 19:37 | mi6x3m | and it seems to be included .... |
| 19:38 | mi6x3m | leiningen is seemingly confused |
| 19:52 | alpheus | Should this clojurescript let me use a tagged literal #ncms.core/foo? (cljs.reader/register-tag-parser! "ncms.core/foo" identity) |
| 19:52 | alpheus | (keys @cljs.reader/*tag-table*) => (inst uuid queue js ncms.core/foo), and |
| 19:52 | alpheus | (@cljs.reader/*tag-table* "ncms.core/foo") => #<function identity(x) {return x;} |
| 19:53 | kenrestivo | is this the most idiomatic way to process a map with nested state to add... more nested state? (into {} (for [[k m] some-map] [k (assoc m {:new-important-info (some-operation m)})])) |
| 19:53 | alpheus | But the expression #ncms.core/foo 1 is an error |
| 19:53 | kenrestivo | umm, actually assoc not merge. same question tho (into {} (for [[k m] some-map] [k (assoc m :new-important-info (some-operation m))])) |
| 19:54 | alpheus | kenrestivo: maybe update-in is what you're looking for? |
| 19:55 | kenrestivo | update in, sure, except i'm trying to perform the operation on several m's in that some-map |
| 19:55 | kenrestivo | but i guess (keys some-map) plus update-in might work too. still seems insufficiently golfy to me tho |
| 20:00 | kenrestivo | hmm, reduce-kv plus assoc or update-in maybe. |
| 20:00 | annelies | This doesn't make any sense to me: https://gist.github.com/rightfold/2a0f34e717d9c3d31fbf |
| 20:01 | annelies | Oh wait nevermind. :) |
| 20:02 | annelies | Nevermind that, I _am_ confused. :S |
| 20:10 | annelies | Is it because the compiler constructs a cons cell when expanding '(1 2) to (quote (1 2))? |
| 20:10 | annelies | or rather, the reader |
| 20:11 | triss | I'm going to be adding quite a lot to a library as I work on a project... |
| 20:12 | triss | at the moment I've got fancy reloading going on with figwheel |
| 20:12 | triss | I added the library as a dependency in project.clj and everything was hunky dory |
| 20:14 | gfredericks | annelies: ##(type ''(1 2)) |
| 20:14 | lazybot | ⇒ clojure.lang.PersistentList |
| 20:14 | triss | but because I wanted nice auto-reloading I thought removing it from there and simply adding a link (unixy ln -s to my project would then alow me top use it |
| 20:14 | gfredericks | nevermind I dunno |
| 20:15 | annelies | gfredericks: I think the reason clojure.lang.Cons appears is because the reader constructs a cons cell when expanding '(1 2) to (quote (1 2)), whereas it doesn't when you spell out quote directly as (quote (1 2)). |
| 20:15 | gfredericks | annelies: the two things aren't the same in any case, since it's dealing with the full form (quote (1 2)) in the second case |
| 20:15 | triss | i.e. reuire it just as i was before. |
| 20:15 | triss | ^require |
| 20:15 | annelies | gfredericks: yah I just noticed :p |
| 20:16 | annelies | context: http://stackoverflow.com/questions/27465223/clojure-list-and-macros |
| 20:16 | gfredericks | annelies: but for most purposes a PersistentList is equivalent to a Cons |
| 20:16 | annelies | Yeah, but Cons isn't a subtype of IPersistentList so list? returns false. |
| 20:17 | gfredericks | sure |
| 20:20 | triss | but now I'm finding none of my clojurescipt will even compile |
| 20:21 | annelies | Yeah, I read the reader source and the reader creates a cons cell when expanding '(1 2) to (quote (1 2)), but spelling out (quote (1 2)) manually doesn't. |
| 20:22 | annelies | meh |
| 20:22 | gfredericks | annelies: are you doing something where this makes a difference? |
| 20:23 | annelies | No, just wondering why list? returns false when used in a macro that is passed '(1 2) vs (quote (1 2)) |
| 20:23 | triss | never mind... sorted it... sorry for the noise |
| 20:23 | annelies | (defmacro islist [f] (list? f)) , (islist '(1 2)) #_false , (islist (quote (1 2))) #_true |
| 20:24 | gfredericks | annelies: list? isn't an appropriate test for macro usage like that; I think seq? is best |
| 20:25 | annelies | ok |
| 20:25 | annelies | thanks |
| 20:25 | gfredericks | np |
| 20:30 | gfredericks | omg I give up regexes |
| 20:30 | gfredericks | ,(def ascii (apply str (map char (range 128)))) |
| 20:30 | clojurebot | #'sandbox/ascii |
| 20:30 | gfredericks | ,(re-seq #"[x&&]" ascii) |
| 20:30 | clojurebot | ("x") |
| 20:31 | gfredericks | ,(re-seq #"[a-c&&]" ascii) |
| 20:31 | clojurebot | ("a" "b" "c") |
| 20:31 | gfredericks | ,(re-seq #"[a-cx&&]" ascii) |
| 20:31 | clojurebot | ("x") |
| 20:31 | gfredericks | what on earth is this. |
| 20:36 | gfredericks | ,(re-seq (re-pattern "[qd-fva-cxy&&]") ascii) |
| 20:36 | clojurebot | ("q" "v" "x" "y") |
| 20:37 | gfredericks | it's the "if you put two ampersands at the end of your character class all of the ranges become NOOPs" rule that we were all taught in college |
| 20:55 | amalloy | gfredericks: i'm telling you, intersections are just bad |
| 20:58 | gfredericks | amalloy: I'd been assuming this edge case (empty right side) wasn't an intersection at all |
| 20:58 | gfredericks | i.e., that it was a noop |
| 20:58 | gfredericks | but now I see it's a goofy-op |
| 20:59 | amalloy | why would it be a no-op? |
| 20:59 | gfredericks | cuz funny parser |
| 20:59 | gfredericks | it certainly seemed like one when I wasn't trying ranges |
| 20:59 | gfredericks | ,(re-matches #"[ab&&]" "b") ;; for example |
| 20:59 | clojurebot | "b" |
| 21:00 | gfredericks | ,(re-matches #"[ab&&]" "&") ;; no & match |
| 21:00 | clojurebot | nil |
| 21:00 | gfredericks | ,(re-matches #"[ab&&&]" "&") ;; except for 3 |
| 21:00 | clojurebot | "&" |
| 21:00 | gfredericks | ,(re-matches #"[ab&&&&]" "&") ;; but not 4 |
| 21:00 | clojurebot | nil |
| 21:00 | gfredericks | ,(re-matches #"[ab&&&&&]" "&") ;; but 5 |
| 21:00 | clojurebot | "&" |
| 21:00 | gfredericks | w00h! |
| 21:03 | gfredericks | I've been trying to read Pattern.java; I can't imagine what sort of weird impl would cause this behavior though |
| 21:08 | andyf | mi6x3m: Eastwood can detect files with the wrong namespace name in them. Try it out to see if it would have caught that. |
| 21:09 | andyf | Most tools are confused if there is such a mismatch. |
| 21:16 | amalloy | gfredericks: the behavior for && &&& &&&& &&&&& doesn't seem too crazy, if you pretend that using && for intersections makes sense to begin with |
| 21:17 | amalloy | [a&&], a intersected with nothing; [a&&&], a intersected with &; [a&&&&], a intersected with nothing intersected with nothing; [a&&&&&] a intersected with & intersected with nothing |
| 21:19 | gfredericks | amalloy: but intersecting with nothing should give you nothing |
| 21:19 | gfredericks | i.e., that doesn't explain why [a&&] matches "a" |
| 21:21 | amalloy | no, but taking the behavior of [a&&] as an axiom, the rest sorta follows from there |
| 21:22 | gfredericks | so it's NOOP and '&' alternating, not intersection and '&' |
| 21:22 | gfredericks | except for this new range twist I just discovered |
| 22:30 | munderwo | Saturday night in doing some clojurescript.. I feel like I should be less happy about this ;) |
| 22:31 | munderwo | the Paul Simon is helping as well. |
| 22:34 | gfredericks | Saturday night in doing some regex |
| 22:35 | andyf | you should be happy if you are enjoying programming in a language that helps you express things well |
| 22:37 | gfredericks | &(re-pattern (str "[" (clojure.string/join "&&" (repeat 10000 "x")) "]")) |
| 22:37 | lazybot | java.lang.StackOverflowError |
| 22:37 | mgaare | maybe some Elton John instead... "Saturday night's all right for Clojure" |
| 22:37 | munderwo | Well I think I have it better than gfredericks … |
| 22:37 | andyf | gfredericks is exploring dark mysteries |
| 22:38 | gfredericks | for science! |
| 22:41 | munderwo | “I can call you mapcat, and you can call me any?” |
| 22:49 | TEttinger | gfredericks, this is madness! |
| 22:49 | TEttinger | you'll stack overflow us all! |
| 23:17 | vivekramaswamy | Hello all, a quick question, what is the command to delete a form. (if (empty? my-array) (do this) (else do this)). I want to delete the whole if statement form my clojure code. Thanks in advance |
| 23:17 | vivekramaswamy | sorry forgot to mention, I am workingon emacs |
| 23:18 | gfredericks | amalloy: oh I think I figured it out |
| 23:19 | amalloy | vivekramaswamy: are you looking for C-M-k? |
| 23:19 | justin_smith | vivekramaswamy: paredit makes it very easy to work by forms |
| 23:19 | gfredericks | amalloy: when you end a char class with &&, I think it intersects the whole thing with the last thing before the && |
| 23:19 | vivekramaswamy | C-M-k would be Cntl+Alt+k right |
| 23:20 | amalloy | mhm |
| 23:20 | justin_smith | vivekramaswamy: usually, yes. Or Escape - C-k if you want more prefix and less chording |
| 23:20 | amalloy | gfredericks: how does that fit with your [a-cx&&] example? |
| 23:20 | Frozenlock | vivekramaswamy: you can take a look at https://github.com/magnars/expand-region.el |
| 23:21 | amalloy | that intersection (a-c with x) should be empty |
| 23:21 | gfredericks | amalloy: it's as if writing [a-cx&&x] |
| 23:21 | vivekramaswamy | sure thanks a lot C-M-k worked. I will definitely take a look |
| 23:22 | gfredericks | not quite so simple...looks like it has some optimizations with single characters where they all get merged together no matter where they endu p |
| 23:22 | gfredericks | ,(def ascii (apply str (map char (range 128)))) |
| 23:23 | clojurebot | #'sandbox/ascii |
| 23:23 | gfredericks | ,(re-seq #"[abc-def&&]" ascii) |
| 23:23 | clojurebot | ("a" "b" "e" "f") |
| 23:23 | gfredericks | ,(re-seq #"[abc-defg-h&&]" ascii) |
| 23:23 | clojurebot | ("g" "h") |
| 23:23 | gfredericks | you basically just get the last "thing" |