#clojure log - Jan 08 2015

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

0:00 lodin: For some reason, records do not implement function invocation. Don't ask me why.

0:00 sdegutis: ha

0:00 lodin: wow you know Clojure pretty well; been using it long?

0:01 lodin: Looked at it two years ago. Been using it more the last half year.

0:01 But no, I don't know it that well.

0:01 I just happened to know this.

0:02 sdegutis: :)

0:15 ToBeReplaced: i see a few edn readers in python -- anyone ever used one in production (with tagged literals)? trip reports?

0:15 lodin: sdegutis: I tried it out. It works. But I wouldn't use it. :-)

0:16 sdegutis: Promise worked! https://gist.github.com/sdegutis/a331db340c6cc3e94b67

0:16 lodin: hwy not?

0:17 scottj: ToBeReplaced: I think the bitemyapp guy used to always complain about the edn support in python

0:17 sdegutis: He left to use Haskell.

0:17 I forgot his nick, started with "c".

0:17 I keep wanting to say ciarran but I know that's not right.

0:18 lodin: sdegutis: I'd opt for being specific.

0:18 sdegutis: lodin: you mean explicit?

0:18 lodin: sdegutis: Yes.

0:18 sdegutis: lodin: I've done that for 2 years now. It's not as ideal as I'd hoped.

0:19 lodin: I've been working on a Clojure web app full time since late 2012.

0:19 lodin: sdegutis: Explicit it what way? You mean passing arguments around?

0:19 sdegutis: lodin: "self", yeah

0:20 justin_smith: sdegutis: callen

0:20 ToBeReplaced: scottj: it's a hard problem for a number of reasons, notably not having an immutable mapping, nor a named collection type other than namedtuple in standard library... too many decisions to make

0:20 justin_smith: sdegutis: he is still bitemyapp on twitter

0:20 lodin: sdegutis: I meant explicit as in having a function that transforms a method into a function.

0:21 ToBeReplaced: i luckily don't have any kind of speed requirement; but tagged records are necessary

0:21 sdegutis: ah right callen

0:21 such a colorufl character

0:21 lodin: oh

0:21 lodin: nah I want to avoid as many :requires as possible

0:22 Ideally nearly all of them.

0:22 That is, all of them in most files.

0:22 lodin: sdegutis: How does that relate to your problem?

0:23 sdegutis: If I have method->func, I need to :require some file that defines it.

0:23 If it's just (:greet bob) and I'm given bob, then I'm all set.

0:23 :)

0:24 I think reify with IFn might eventually be a cool alternative, but (bob :greet) isn't much better than (:greet bob)

0:25 Great, my OOP thing works. Now to add basic inheritance.

0:25 lodin: sdegutis: basic inheritance = merge. :-)

0:26 sdegutis: Good idea :D

0:26 This is what I've got so far: https://gist.github.com/sdegutis/d0c431a124d4d17f7cc2

0:26 lodin: sdegutis: Why do you want to avoid :requires?

0:26 sdegutis: lodin: because reasons.

0:26 lodin: I see.

0:27 sdegutis: lodin: I was thinking of just doing (merge imethods (some-superclass imethods)) but then I extracted (construct) into a function which takes both imethods and state.

0:27 Now I'm wondering if I should somehow do, like, auto-init-superclass-calling or something.

0:28 lodin: And you really don't want (call obj :method ...)?

0:28 sdegutis: Where would "call" symbol come from?

0:28 lodin: A require, of course.

0:28 :-)

0:28 sdegutis: ;)

0:29 lodin: I think that one thing that Clojure gets right, in constract to many other popular OO language, is method qualification.

0:29 But you wouldn't like that, since it would involve require.

0:29 ben_vulpes: i'm having trouble getting cider mode to turn on when i open a .clj file in emacs - where should i start finding the appropriate hook? clojure-mode turns on just handily, but...not cider mode, and not paredit.

0:29 sdegutis: whts that

0:29 lodin: whats that

0:30 lodin: sdegutis: When you use either multimethods or protocols you can have two completely different methods that have the same name.

0:31 sdegutis: lodin: oh yeah thats pretty cool

0:31 lodin: i have found them to be troublesome though

0:31 sorry for bad capitlization and typos, my fingers hurt a lot from rsi given to me by emacs

0:31 lodin: How's that?

0:31 sdegutis: (fingers and wrist and hand)

0:31 well, i forgot how. i just know.

0:32 they lacked some feature that my use-case needed

0:33 lodin: Could it have been that you wanted to reuse parts of an implementation?

0:34 sdegutis: doesnt ound famir

0:34 doesnt sound familiar

0:35 cfleming: sdegutis: reify with IFn is kind of ugly because you have to implement all the arities. proxy with AFn would be better depending on how much you care about speed.

0:35 sdegutis: cfleming: thanks although i'm just doing it much simpler now

0:36 ahhhh, (merge imethods cmethods) is biting me now that im trying to make inheritance work

0:36 namely because an instance has only imethods but a class has both imethods and cmethods, thus the class is defined as a merge between then

0:37 but since the imethods by itself is lost once the class is created, this doesnt allow me to access them by themselves later on when i constuct an instance of the base class

0:38 underplank: hi all. what would be the tradeoffs in using a agent vs and atom for a global counter from multiple threads?

0:39 lodin: sdegutis: Do you really need to make this distinction between classes and objects?

0:40 sdegutis: lodin: no, this could totally go the ruby way and have classes be instances of "class" class

0:40 lodin: but then that makes for a bootstrapping issue

0:41 lodin: sdegutis: I think your requirement/desire to not having requires is peculiar.

0:41 sdegutis: lodin: yet firm

1:07 lodin: sdegutis: So you decided on not using the "arrow map" I mentioned above?

2:35 SagiCZ1: lodin: i think records dont implement looking up the key (as maps do) because you may want to let them implement entirely different interface

2:38 lodin: SagiCZ1: You have a point. It has the unfortunate effect of not making records a drop-in replacement for maps though.

2:45 SagiCZ1: lodin: true.. thats why it is prefferable to use keys as functions to acces the values of maps

4:23 sm0ke_: hello all, so i have this webapp written over edn

4:24 now people want to use it from javascript, is there a library for this?

4:25 Empperi: https://github.com/shaunxcode/jsedn

4:28 sm0ke_: Empperi: is this still maintained?

4:28 Empperi: I have no idea

4:28 but that's the one linked here https://github.com/edn-format/edn/wiki/Implementations

4:34 sm0ke_: guess it too stable to be maintained :D

4:34 :P

4:38 sveri: Hi, any of the boot developers here?

4:39 cfleming: ping

4:42 cfleming: sveri: pong

4:43 hellofunk: cfleming: what's the best way to learn about new Cursive updates and get and install them?

4:43 sveri: cfleming: Hi, do you plan to integrate boot support in cursive anytime soon?

4:43 hellofunk: intellij has an auto update feature which informs you about new cursive updates

4:44 cfleming: hellofunk: IntelliJ will check for updates once a day, I think

4:44 sveri: hellofunk: and the homepage of cursive has an extensive list of versions + features

4:44 hellofunk: ok cool

4:44 cfleming: hellofunk: I send a longer mail with info about each release to the mailing list, too

4:45 hellofunk: I'm planning to publish those in a blog too since currently only subscribers see those

4:45 sveri: Yes, but I'm not sure when. It's very interesting to me, and I'd like to use it for building Cursive itself.

4:45 hellofunk: cfleming: awesome. hey what functionality in Cursive different between the free IntelliJ edition vs premium?

4:45 cfleming: sveri: But my to-do list is very long.

4:46 hellofunk: None, only IntelliJ features are different.

4:46 hellofunk: having never used IntelliJ before, sometimes it is not clear where the line is drawn between Cursive and intelliJ

4:47 cfleming: hellofunk: Depending on what you're doing, some of that might be useful - their web tech is really good. I'm discussing with them at the moment how to integrate Cursive with that.

4:47 sveri: cfleming: cool, if I get boot working on windows I will try to have a project.clj parallel to the build.boot file and use it to let intellij grab all the needed information

4:48 cfleming: sveri: Yeah, that's the recommended approach at the moment. You can set up your source dirs etc like that, and then use this in your boot script to get deps from project.clj: https://gist.github.com/bsima/88969126962803a6500f

4:49 sveri: You can use External Tools to run boot tasks too, I believe

4:49 sveri: cfleming: ah, thats a nice gist, thank you

4:49 cfleming: sveri: Yeah, I need to put this in a single page somewhere - a lot of people are asking about it.

4:50 sveri: cfleming: I have to see how it goes, right now some thing seems to be broken on windows -.-

5:01 cfleming: sveri: Cool, if you manage to get it working it would be interesting to know what you had to do, either here or on the Cursive mailing list - there's a lot of interest.

5:23 slipset: hmm, the pmonks is here as well!

5:31 Kristien: perl monks?

5:36 dysfun: i suppose you could loosely describe me as a perlmonk

5:37 Kristien: I like Perl

5:38 dysfun: as do i

5:39 the 'keep it simple' philosophy is one it shares with clojure

5:40 did you see the chaos computer club announcing perl's list folding was an exploit? that was amusing.

5:41 Kristien: no

5:42 dysfun: http://www.perlmonks.org/?node_id=1111750

6:00 Ninerian_: Hello

6:01 I have a list of directories as java.io.File, How can I filter the list, excluding entries with a specific folder name?

6:13 dysfun: (filter #(= (.whatever %) "foo") dirs) where .whatever is the relevant java.io.file method

6:14 or not= perhaps

6:14 SagiCZ1: you may want remove, which is the opposite of filter

6:20 Ninerian_: great, thanks

6:43 hellofunk: should I expect any overall performance issues on my 3-year old laptop if I run multiple REPLs simultaneously

6:43 SagiCZ1: hellofunk: i would expect you run out of RAM very soon

6:44 I have 4GB and 2 REPLs, my IDE and Chrome kill it in a few minutes

6:44 hellofunk: anyone know how much RAM a typical REPL uses up? Is it a standard number associated with JVM defaults or something?

6:44 SagiCZ1: which IDE do you like?

6:46 SagiCZ1: Yes it is a standard Java process so you can even set the heap size with arguments..

6:46 I use IntelliJ with cfleming's amazing Cursive plugin.. although I have to note that I have been unhappy with performance of the new 14 version.. Feels like the 13 version was faster..

6:48 hellofunk: i'm using intellij 14.0.1 and liking it, but cannot compare it with previous version

6:48 just started using it. it's awesome

6:49 it def does all the things i wish Cider could do

6:49 SagiCZ1: hellofunk: yeah it is.. and even after years of experience with it I still find new cool features..

6:51 luxbock: hellofunk: what things does Cursive do that Cider doesn't?

6:52 SagiCZ1: luxbock: isnt cider in emacs?

6:52 hellofunk: luxbock: watch cfleming's conj presentation on youtube for the first round of examples

6:53 luxbock: SagiCZ1: yep

6:53 hellofunk: alright

6:53 hellofunk: luxbock: but in short, it offers a lot of great tools that unlike Cider do not require REPL to offer all the editing coolness because it analyzes syntax directly

6:53 SagiCZ1: luxbock: well the main difference would be, that people dont need to learn emacs to use Cursive.. IntelliJ is similar to NetBeans or Eclipse only faster and less convoluted..

6:54 luxbock: yeah I'm pretty deep into Emacs already so I doubt I'll ever switch to using anything else :P

6:54 was just wondering if there was something I was missing out

6:54 hellofunk: luxbock: there is a big philosophical difference in how it handles editing. Cider uses a REPL for access to docs, arity hints, other things. Cursive, especially for clojurescript code, allows all these same tools

6:54 without relying on a REPL (though the REPL is available of course)

6:54 SagiCZ1: luxbock: i think there might be things you are missing out on, but maybe not enough to bother with changing your tool-chain.. not that i do not have experience with cider

6:55 luxbock: I always have a REPL open though

6:55 hellofunk: luxbock: because Cursive is operating at a syntax-only layer, it can mangle your code in ways Cider does not. lots of refactoring tools, and the structural editing and navigation features surpass emacs in my opinion

6:56 luxbock: I'll watch that video now and see if there's something my Emacs can't do :)

6:57 hellofunk: luxbock: out of the box, it does a lot Cider does not do. But emacs is certainly capable of doing these things, but no one has or is likely to develop a whole new approach to editing clojure in emacs

6:57 luxbock: also, that video whetted my appetite but i've discovered much more awesomeness after using it for about a week, stuff that is not in the video

6:58 luxbock: so Cursive doesn't use a middleware like Cider does?

6:58 hellofunk: luxbock: i sure ain't no IDE engineer so I don't know. but it does not at all require a connection to a REPL whatsoever

6:58 cfleming: luxbock: No, it doesn't

6:59 SagiCZ1: and here he is!

6:59 cfleming: cfleming: Most of the functionality is provided by analysing source code, so doesn't need a REPL

6:59 Oops, talking to myself again, sheesh

6:59 hellofunk: luxbock: i will say this: if someone developed a tool with Cursive's features for emacs, i would still prefer to use emacs, because I love it. and i know emacs is capable of just about anything. but i would certainly never hold my breath that it's going to happen anytime soon, or ever.

7:00 cfleming: lol

7:00 luxbock: I was under the impression that well configured Clojure environment for Emacs still had more features than Cursive

7:00 cfleming: You can get pretty close to cursive's features if you're an emacs power user and have your IDE totally tricked out with clj-refactor etc

7:01 And there are still features in Emacs that Cursive doesn't have yet - I'm working on macroexpansion right now, for example

7:01 luxbock: yeah projectile and clj-refactor helps a lot

7:01 hipsterslapfight: are you telling me the last three weeks i've spent trying to learn emacs to write clojure in has been pointless?! :v

7:01 SagiCZ1: hipsterslapfight: YES! dont learn clojure in emacs if you dont know either of those! too hard

7:02 hipsterslapfight: hahaha, okay then

7:02 cfleming: hipsterslapfight: It's not pointless - now you really understand you don't want all that pain just to write some code :)

7:02 hipsterslapfight: https://www.youtube.com/watch?v=vt1y2FbWQMg is this the video that was talked about earlier?

7:02 SagiCZ1: hipsterslapfight: check this out.. its a guide for instalilng beta version of Cursive https://cursiveclojure.com/userguide/

7:02 hellofunk: hipsterslapfight: i cherish being forced to learn emacs a year ago, it's awesome for so many things that i now rely on (irc, shell interaction, all kinds of stuff). but for editing clojure, if you don't want to learn emacs that is absolutely no need to now that Cursive is out there.

7:03 hipsterslapfight: cool, thanks SagiCZ1 hellofunk cfleming

7:03 will check this out

7:03 luxbock: I learned how to touch-type (with Colemak, which I since stopped using), use Emacs and Clojure at the same time :P

7:03 cfleming: luxbock: that must have hurt

7:03 luxbock: having not much of a programming background

7:03 yeah was a bit rough at first

7:04 scottj: luxbock: how long did you use colemak and why did you stop?

7:04 clojurebot: It's greek to me.

7:04 luxbock: scottj: I used it for a year and stopped when I started using evil with Emacs

7:05 cfleming: clojurebot: I know how you feel

7:05 clojurebot: Pardon?

7:05 cfleming: You heard me

7:05 hellofunk: lol

7:05 luxbock: I started using evil because my wrists started hurting from the regular Emacs keybinds

7:05 hellofunk: clojurebot: just, thank you for being you

7:05 clojurebot: Huh?

7:05 hellofunk: oh, clojurebot

7:07 scottj: luxbock: (non-evil non-colemak user here), was there some annoying mismatch (other than hjkl)?

7:09 luxbock: scottj: I tried to make it work at first, but then I also started using Pentadactyl with Firefox, and I realized I coulnd't be bothered to customize everything that uses the Vim keys

7:09 scottj: luxbock: ahh, ty

7:10 luxbock: btw, is it just hjkl or is there something else about colemak that's annoying with vim?

7:10 luxbock: scottj: mostly just hjkl, the rest of the stuff is reasonably close

7:12 does anyone know if Batsov, the maintainer of Cider, hangs around in IRC?

7:13 puredanger: I don't think so

7:14 cfleming: luxbock: I think there's a clojure/emacs channel

7:15 luxbock: cfleming: yep I'm in there, but I didn't see his nick there, but wasn't sure if he just used a different nick

7:15 cfleming: luxbock: I'm not sure - I don't think I've ever seen him around

7:16 luxbock: I was wondering if it would be possible to build a macroexpand for functions, where it would work by looking up the symbols and expanding them with the body of the function wherever it can. it would stop when it reaches a clojure.core function

7:18 I think for functions defined in the REPL one would need to use a nREPL middleware that would attach the function body as meta-data on the function though

7:19 slipset: cfleming: just curious, why would you develop clojure without having a REPL running?

7:20 cfleming: slipset: You don't have to, Cursive fully supports the REPL, it just doesn't rely on the REPL for editing functionality

7:20 SagiCZ1: slipset: in Cursive I actually have REPL up and I execute blocks of code from my editor window via shorcuts and then maybe edit them, tweak them and then copy paste them back to the editor..

7:21 cfleming: slipset: Analysing source rather than using the REPL has pros and cons, but I think ultimately it will be a more powerful solution

7:21 slipset: cfleming: I understand that Cursive lets you have the REPL running, but I can't see why you'd ever want to program Clojure without having the REPL running, so the advantage of being able to do stuff without the REPL seems moot?

7:21 cfleming: I'm not critizing nor trolling, just wondering.

7:22 cfleming: slipset: Sure, no problem, no offense taken :)

7:22 slipset: It's more that analysing the source allows a lot of functionality that you can't get via a REPL

7:23 slipset: cfleming thanks

7:23 cfleming: slipset: For example, you can create an index of your whole project - that's very hard to do from a REPL

7:23 slipset: What constantly seems to be a problem for me, is that I end up with something in the REPL which is not in my source files

7:24 cfleming: slipset: Also, all Cursive's functionality has worked for a long time for ClojureScript - that's only starting to come to REPL based systems now

7:25 slipset: That's fine, if you're working in the REPL editor Cursive uses the REPL much like Cider would. If you're working on your project files it uses the project indexes.

7:26 slipset: cfleming: out of curiosity, I used to use IntelliJ for JS development, but I never trusted their refactoring tools in such a dynamic language, since rename-thingy basically becomes a global search-replace.

7:26 Do you have such problems with Clojure as well?

7:27 cfleming: slipset: To a certain extent, but Clojure is more regular than JS. It can never be 100% accurate in some cases, but it's pretty close for most cases.

7:27 slipset: It's certainly much better than global search/replace.

7:27 slipset: :)

7:28 SagiCZ1: when intellij isnt sure what you wanted to refactor it shows quite handy filterable/groupable view that lets you easily decide what you had in mind

7:28 cfleming: SagiCZ1: True, although Cursive doesn't do that much yet. I'm definitely going to add that for ambiguous cases though (like renaming keywords)

7:29 slipset: cfleming: I guess (keyword "foo") could trip you up when renaming :foo to :bar?

7:30 SagiCZ1: slipset: well generally you dont want to rename literals

7:30 cfleming: slipset: Sure, or cases like (defrecord Record [field]) (:field (->Record x))

7:31 slipset: You're never sure if that :field use really refers to the record field or not, and even if you are the developer might have used :field in some other context elsewhere

7:31 slipset: true

7:31 hipsterslapfight: i've never used an IDE before, would i still be able to get the most out of cursive/find it useful?

7:32 SagiCZ1: hipsterslapfight: definitely

7:32 cfleming: slipset: That said, Cursive now provides find usages for keywords which finds :keys destructurings and allows you to rename them in one go, it's really awesome for refactoring map-based code

7:32 hipsterslapfight: cool, will finish watching cfleming's video then download everything and get it set up :3

7:32 SagiCZ1: hipsterslapfight: if you have any trouble, feel free to ask for help

7:33 slipset: cfleming: yes, I saw that in your conj talk, great talk BTW and quite impressive stuff!

7:33 hipsterslapfight: thanks SagiCZ1!

7:33 Empperi: cfleming: oh shit, really?

7:33 awesome

7:33 cfleming: hipsterslapfight: Sure, there's a learning curve like everything but IntelliJ is generally easier to get your head around than emacs/vim - it works like a "normal" app

7:33 Empperi: and I guess ::foo is only refactored in that namespace?

7:33 cfleming: slipset: Thanks!

7:33 hipsterslapfight: cool, thanks cfleming

7:34 cfleming: Empperi: Yeah, Cursive provides completion and renaming for keywords, and it's namespace aware

7:34 Empperi: cfleming: that being said, I've been facing a frustrating problem lately with Cursive in Windows

7:34 for some reason the keyboard shortcuts for REPL interaction don't seem to get through most of the time

7:34 sometimes they do

7:34 doesn't happen in OsX o_O

7:34 and I mean operations like load current namespace into repl etc

7:34 cfleming: Empperi: That's really weird - you mean that sometimes they just don't work?

7:34 Empperi: switch repl to current namespace

7:34 yeah

7:34 SagiCZ1: cfleming: oh and in intellij 14 the REPL menu disappeared from Tools

7:34 Empperi: nothing just happens

7:35 it's like the commands don't get through the nrepl

7:35 cfleming: Empperi: And you definitely have a REPL running?

7:35 Empperi: absolutely

7:35 what always works is "evaluate form before cursor in REPL"

7:35 cfleming: SagiCZ1: It won't be there until you have a REPL running

7:35 Empperi: that hasn't failed even once

7:35 hellofunk: hipsterslapfight: one thing I will say is that it is really nice to customize your work environment in Cursive compared to emacs. you don't have to "code" your work environment like you do in emacs. now once you get it setup, you may never change it, but it's nice to be able to make changes quickly and easily.

7:36 Empperi: I did not have this problem earlier, but it's been there in the last few versions

7:36 SagiCZ1: cfleming: oh.. nevermind then, no bug, it works, sorry

7:36 Empperi: have it both at my work desktop computer and at home desktop

7:36 hipsterslapfight: hellofunk: i was really happy when it only took me half an hour to figure out how to get `#` to come through properly (M-3 on british keyboard) in emacs :v

7:36 so yes, that sounds pretty good to me

7:36 Empperi: home mbp and work mbp don't have that problem

7:36 cfleming: Empperi: That's very strange, I've never heard of that. If you look in your Tools menu, do the menu items have the shortcuts beside them?

7:36 Empperi: yes

7:37 cfleming: Empperi: Huh

7:37 Empperi: it's such a vague problem I haven't even bothered to write an issue out of it

7:37 but it such a pain in the ass

7:37 cfleming: Empperi: I have no idea what could cause that

7:37 hellofunk: slipset: for starters, clojurescript dev doesn't use a REPL like clojure does. so Cursive allows you to have access to all these cool editing tools because it does so without a REPL and puts cljs and clj on the same plane for editing prowess

7:37 Empperi: it is

7:37 cfleming: Empperi: yeah, no doubt.

7:37 Empperi: have had that problem both in intellij 13 and 14

7:37 SagiCZ1: Empperi: isnt there a difference having the keybindings defined in the Other Settings/Clojure/Keybindings and in regular IntelliJ keybiundings?

7:38 Empperi: SagiCZ1: yes

7:38 but anyway, those do work sometiems

7:38 sometimes

7:38 cfleming: Empperi: Do you have problems with any other actions? Any normal IntelliJ ones, or structural editing?

7:38 Empperi: it seems to be related to how long the REPL has been running

7:38 usually if I start a fresh REPL it'll work for a while

7:38 no, everything else works just fine

7:38 it's just the REPL interaction from the editors

7:39 cfleming: Empperi: Any exceptions in your log?

7:39 Empperi: none

7:39 it's just like the keybind was not there

7:39 SagiCZ1: Empperi: I have all of them defined in AppearanceBehavior/Keymap.. and the Clojure keybindings is empty.. and it works well.. maybe try that

7:39 hellofunk: cfleming: you said: Cursive now provides find usages for keywords which finds :keys destructurings and allows you to rename them in one go, it's really awesome for refactoring map-based code.

7:39 cfleming: where can i read more about this?

7:39 Empperi: yeah, I've configured my keybindings myself since most of those operations don't have default keybindings anyway

7:40 cfleming: hellofunk: Only in IRC unfortunately :-)

7:40 hellofunk: My doc is woefully out of date

7:40 hellofunk: I demoed that in the video though

7:40 Empperi: it works just like any other "find references" etc does

7:41 just tried it, never even tried to do that before with keywords

7:41 seems to work just fine

7:41 which is awesomesauce

7:42 cfleming: one possible lead I do have though with that problem

7:42 cfleming: Empperi: Can you send me a mail at cursive@cursiveclojure.com? I'll send you a dev version with some debugging to figure out what's going on

7:42 Empperi: Shoot

7:42 hellofunk: cfleming: i'll have to watch again to remember. what am i to do? there are just way too many incredible things about Cursive to keep in my memory.

7:42 Empperi: I've sometimes seen that the commands are queued

7:42 like I've hit load file in repl several times in frustration

7:43 then I go and use the menu to do that and then boom, it loads it several times

7:43 I'd like to point out that using the menu with mouse works every time

7:43 it's just the keybindings which are funky

7:43 I have no idea at all if it is even Cursive's problem

7:43 cfleming: hellofunk: Find usages (Cmd-Option-F7) on a keyword should find all usages of a keyword

7:44 hellofunk: If that keyword is used in a :keys destructuring, you'll be shown those usages too

7:44 hellofunk: cfleming: thanks but the first thing i did with Cursive is setup a wholly custom keymap for everything, so i probably disabled that. i'll find that command somewhere though.

7:44 SagiCZ1: hellofunk: check out extracting and inlining variables.. so cool!

7:44 Empperi: cfleming: and I'll send the mail

7:45 cfleming: hellofunk: You can also find usages from the :keys binding too, so if you have {:keys [field1 field2]} you can find usages on field1 and field2

7:45 hellofunk: And it will show usages of that keyword and it's destructured vars everywhere

7:46 s/vars/bindings/

7:46 hellofunk: Renaming from any of those points will rename the keyword and all the bindings

7:46 Empperi: Ok, it might me some difference in IntelliJ's key handing on Windows, but no-one else has reported it

7:47 Empperi: Send me a mail and we'll see what we can do

7:47 Empperi: yeah, if it was just one computer I'd say it is my computer

7:47 but it's two totally different computers

7:47 with two different Ideas (at work using Ultimate edition, at home Community edition)

7:47 cfleming: Empperi: Got the mail, thanks. It's past my bedtime but I'll look at making a build tomorrow and get back to you

7:47 Empperi: yeah, no worries

7:48 I do have my macbook too :)

7:48 cfleming: Empperi: Clearly the solution is just to use a mac :)

7:48 Empperi: both have their perks

7:48 cfleming: Yeah, no doubt

7:48 Empperi: I like to stay using actively both

7:48 makes me see things in a wider perspective

7:53 cfleming: hellofunk: Definitely enable "Show Usages" though, it's one of the commands I use most

7:56 hellofunk: cfleming: sweet. i found it easier to setup a new keymap rather than learn any of the existing ones. allowed me to leverage my opinions on editing and do so quite easily

8:03 my paredit and structural tools, as well as basic navigation around a source file are all non-standard key command now in Cursive, i feel like i'm playing a piano when i code rather than making my fingers play a game of Twister

8:33 luxbock: ,('foo {'foo "bar"))

8:33 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

8:33 luxbock: &('foo {'foo "bar"))

8:33 lazybot: java.lang.RuntimeException: Unmatched delimiter: )

8:33 luxbock: ('foo {'foo "bar"}))

8:33 grrr

8:34 &('foo {'foo "bar"})

8:34 lazybot: ⇒ "bar"

8:34 Ninerian_: (defn get-XML-files

8:34 "Search files after a regex match.

8:34 Returns a list with java.io.files excluding Backups"

8:34 [searchDirectory pattern]

8:34 ((filter

8:34 #(not= (re-find #"_BACKUP" (str %)) "_BACKUP")

8:34 (fs/find-files searchDirectory pattern))

8:34 luxbock: didn't know that symbols are functions as well

8:34 Ninerian_: ))

8:34 I have a function '

8:34 I have a function `(defn get-XML-files

8:34 "Search files after a regex match.

8:34 Returns a list with java.io.files excluding Backups"

8:34 [searchDirectory pattern]

8:34 ((filter

8:34 #(not= (re-find #"_BACKUP" (str %)) "_BACKUP")

8:34 (fs/find-files searchDirectory pattern))

8:34 ))

8:35 foodoo: My memory claims that there is a counterpart to "filter" in Clojure. Something like "filter-false". Is there such a function in clojure.core?

8:35 clgv: Ninerian_: use refheap.com or similar

8:35 luxbock: foodoo: `remove`

8:35 clgv: Ninerian_: nobody can ready you multiline code paste on irc

8:35 foodoo: luxbock: thanks :)

8:35 Ninerian_: sorry.

8:38 https://www.refheap.com/95874

8:38 Could you explain me, why the first throws the exception and the second not?

8:40 slipset: ninarian: skip the extra parens

8:40 ((filter doesn't make sense

8:40 use (filter ...)

8:40 SagiCZ1: Ninerian_: btw instead of .. filter not(= ... you can use .. remove =

8:44 Ninerian_: Thanks the extra parens caused the error. What do you mean with remove = filter not( ?

8:44 slipset: remove removes elements from the list for which the predicate is true

8:44 SagiCZ1: remove does opposite of filter..

8:45 ,(remove odd? (range 10))

8:45 clojurebot: (0 2 4 6 8)

8:45 SagiCZ1: ,(filter odd? (range 10))

8:45 clojurebot: (1 3 5 7 9)

8:45 Ninerian_: ah okay

8:54 SagiCZ1: cfleming: around 38 minutes into your conj talk Cursive lets you refactor nested lambda functions which are incorrect in clojure into either (fn #(.. ) ) or #( .. (fn .. )) .. is this feature in the current Cursive version? doesn't seem to work for me

8:56 slipset: Ninerian_: Just out of curiousity, you filter the result from (fs/find-files ..)

8:56 Ninerian_: a function which takes a regex to match files against.

8:58 ah, you could probably use (fs/find-files* dir p)

9:27 Ninerian_: Thanks, i will look into this later. Now I go further into the xml. :-)

9:27 slipset: do that :)

9:37 sdegutis: Hi. I am working on an OOP library. I would love any feedback on the interface: https://gist.github.com/sdegutis/4ca0645798e6647fac53

9:38 tbaldridge: Well the first question should be, what does this offer over defprotocol and defmulti?

9:39 clgv: sdegutis: isnt there another lib already that explores OOP on top of clojure? something similar to CLOS afair

9:39 sdegutis: First, it lets you add methods to a a class via mixins, which I'm not sure how to do that.

9:39 clgv: CLOS is pretty complex, whereas mine aims for simplicity.

9:39 tbaldridge: sdegutis: protocols can do that, you can extend them to any Java class.

9:40 sdegutis: tbaldridge: This one lets you extend them to any class using this system.

9:40 tbaldridge: Second, this one has a very convenient shortcut for partialling an instance method with "self" and getting a 1-less arity

9:40 If you have an instance 'bob' with a method :greet, you can do (:greet bob) and get the 0-arity function with bob already bound to it.

9:41 tbaldridge: or I could just do (partial greet bob) with protocols and not have to include a new dep. Anyway, that's my feedback.

9:42 sdegutis: tbaldridge: I don't expect you to agree with the philosophies behind my library at all, in fact I think you'll probably strongly consider it an anti-pattern -- and I won't take offense at that.

9:42 ok

9:42 * sdegutis re-reads http://clojure.org/protocols

9:43 clgv: tbaldridge: what's new in pixie since mid december?

9:43 sdegutis: tbaldridge: I'm not seeing how you can combine behavior in a "mixin-like" way using Clojure protocols

9:44 tbaldridge: clgv: FFI support is pretty much what I'm working on these days. The current state is this: https://github.com/pixie-lang/pixie/blob/master/pixie/math.pxi should get even more elegant in a month or so.

9:45 sdegutis: tbaldridge: other than that, do you consider pixie stable/mature enough for daily private use yet?

9:45 tbaldridge: sdegutis: with extend and extend-type you can modify any existing class to extend a protocol.

9:46 Eh, we're not going to be stable for about another half a year, but I do plan on releasing something by the end of Q1 of this year.

9:46 sdegutis: tbaldridge: but afaict you can't take an implementation of something and combine it with another implementation in order to share behavior, which is what mixins do

9:46 clgv: tbaldridge: great :)

9:47 sdegutis: tbaldridge: the "mixins" in my library are basically like "multiple inheritance" but without any inherited initializers or the ability to override inherited functions

9:49 tbaldridge: thanks for providing me with a good idea of what kind of questions people will ask about my lib and what kind of things they will be confused about that I'll need to clarify up-front

9:50 tbaldridge: sdegutis: take a look at clojure.core/extend. That function takes a type and a hashmap of functions. You can easily create mixins with something like that http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/extend

9:51 sdegutis: tbaldridge: right, but that inverts the solution, since can't describe a thing that accepts mixins, you add mixins onto a thing -- in order to get what I want, I'd have to write a wrapper around that anyway

9:51 tbaldridge: so basically I might use extend/defprotocol/deftype in my library's implementation

9:51 But it's still a unique interface in its own right.

9:51 puredanger: David McNeil did something when we were working together that's in the ballpark of this - http://david-mcneil.com/post/1475458103/implementation-inheritance-in-clojure

9:53 sdegutis: One primary opinionated aspect of my library that's sure to be disagreed with strongly is that methods can be accessed without any special functions -- an object is just a Clojure map and its bound-methods are just keys within it.

9:53 Thus if you have an object, you don't need any requires to use it, you just access its methods and call them.

10:25 justin_smith: $mail sm0ke edn and js? you should look at transit

10:25 lazybot: Message saved.

10:54 sdegutis: Can macros really not make use of private functions?

10:56 clgv: sdegutis: they can use those at macro expansion time, but you cant include those private functions in the generated code that is returned

10:56 sdegutis: I see.

10:56 Thanks.

10:56 ordnungswidrig: clgv: even not if they exapand in the same namespace?!

10:57 sdegutis: Not ideal but meh.

10:57 Bronsa: ordnungswidrig: that'll obviously work but in that only makses sense for a private macro

10:58 ordnungswidrig: Bronsa: Now I get it, yes, the macro is expanded on the caller side, of course

10:59 ...in the caller's namespace

11:00 clgv: as Bronsa said ;)

11:01 * clgv is not keen on private functions most of the time

11:01 tbaldridge: (inc clgv)

11:01 lazybot: ⇒ 42

11:01 tbaldridge: heyo!

11:01 clgv: uh, that came unexpected

11:01 ordnungswidrig: clgv: they free you from thinking about the interface and documentation!

11:02 clgv: ordnungswidrig: a unified metadata that is supported by all those api doc generators would suffice for that

11:03 *metadata tag

11:03 ordnungswidrig: hmm, never use them.

11:03 I never use them. Just (doc some-fn) or maybe the dider integration

11:05 clgv: but (defn ^:api some-fn ...) would be pretty obvious as well, though information in the output of (doc some-fn) would be nice as well then

11:28 Leste: Im giving my first steps into programming using this as a resource. http://iloveponies.github.io/120-hour-epic-sax-marathon/training-day.html.

11:29 whys this doesn't evaluate 2728? (- 2 (* 78 35))

11:29 and results a negative number?

11:30 tbaldridge: because 2 - something large is a negative number.

11:30 hfaafb: because 2 - 2730 is -2728

11:30 tbaldridge: ,(- (* 78 35) 2)

11:30 clojurebot: 2728

11:31 Leste: @tbaldridge thank you. makes sense now

11:31 im embrassed with my noob question now:)

11:42 puredanger: we are all noobs sometimes!

11:44 hfaafb: not me

11:51 daniel``: nor me

12:00 EvanR: ok

12:01 so by using clojure.java.io/input-stream i get a java.io.BufferedInputStream. how do i use this in clojure?

12:01 is it like a lazy seq of bytes

12:02 llasram: EvanR: What are you trying to read / what do you want to get it as?

12:02 EvanR: im trying to split it to get a vector of byte-strings

12:03 llasram: And by "byte string" you mean?

12:03 EvanR: byte[]

12:04 stuartsierra: EvanR: I'd suggest starting with the Java tutorials on Basic I/O http://docs.oracle.com/javase/tutorial/essential/io/index.html — the interop isn't difficult once you know the conventions.

12:04 llasram: Ok. Welllll, you can certainly use the Java InputStream methods to read bytes directly

12:04 EvanR: i see that in the java docs

12:04 i "just" pass in byte array objects which it will fill

12:04 llasram: EvanR: Where are these bytes destined?

12:05 EvanR: they will be separated into a data base transaction and zero or more files to be written to disk

12:05 well uploaded to cloud storage

12:06 after being validated and converted etc

12:06 llasram: If the data itself has structure, you could use https://github.com/ztellman/gloss to parse them

12:06 I think there's another similar library about, but I can't recall its name off the top of my head

12:07 Otherwise, you can either use the InputStream methods, and/or use nio ByteBuffers

12:08 puredanger: Buffy the ByteBuffer slayer?

12:08 llasram: Ah, yes

12:08 puredanger: https://github.com/clojurewerkz/buffy/

12:08 ssideris: there is also gloss

12:08 a similar library

12:09 EvanR: gloss and buffy

12:09 clgv: That library is missing the mandatory image that goes along when a reference is used as library name ;)

12:10 llasram: A picture of Professor Pangloss would quite liven it up

12:10 clgv: llasram: you had to pick the wrong one! :P

12:10 llasram: </humor>

12:11 clgv: recognized, but I wanted to complain anyway :D

12:11 EvanR: gloss looks more likely to work

12:13 now if i could only figure out how to use it

12:16 (decode-all frame bytes) i guess bytes means BufferedInputStream

12:17 or ByteBuffers...

12:18 llasram: EvanR: I believe it will work

12:18 (with the InputStream)

12:19 It uses https://github.com/ztellman/byte-streams to coerce the input to a sequence of bytes

12:19 *sequence of byte buffers

12:19 clgv: Evanr nio.ByterBuffer it seems

12:20 ssideris: EvanR: with gloss you need to define the format of the bytes using the DSL and then you pass it the format and the bytes

12:20 ssideris: but it expects all bytes to be accounted for, you can't do a partial "parse"

12:20 EvanR: does the common "sequence of bytes" support streaming?

12:21 llasram: EvanR: See `lazy-decode-all`

12:21 EvanR: where?

12:21 clojurebot: where is your source code

12:21 llasram: EvanR: gloss.io/lazy-decode-all

12:21 EvanR: ok its not listed here http://ideolalia.com/gloss/gloss.io-api.html

12:21 llasram: Oh, or `decode-stream` really

12:22 EvanR: also not there

12:22 llasram: Yep. The generated API reference appears to be well out-of-date

12:23 EvanR: just for my information, if i wasnt dealing with java right now, what would be the clojure way to deal with io handles that take and return chunks of bytes at a time

12:23 llasram: mu

12:23 EvanR: none of the above?

12:23 llasram: Yeah, pretty much

12:24 EvanR: that simpliest things

12:24 simplifies

12:24 llasram: gloss, buffy, etc exist to fill the otherwise-absence

12:24 seangrove: In cljs, I have a (deftype Chainable [coll] ...), is there a way to add a method to the Chainable prototype?

12:25 I can add it to the object created, but deftypes don't seem to instantiate objects with an intermediate prototype

12:25 llasram: EvanR: Or to slightly-differently understand your question, all JVM Clojure IO uses the underlying Java classes, so you're using Readers, InputStreams, and/or nio

12:26 EvanR: ok but these involve mutable buffers

12:27 llasram: EvanR: Same situation. For strings, Clojure just uses the (immutable) Java String class

12:27 But Java has no immutable byte-sequence class, and Clojure itself does not provide one

12:27 EvanR: yes strings seems more fortunate

12:27 llasram: So you are in mutable land with byte arrays or nio ByteBuffers or the netty etc equivalents

12:28 Indeed (re: more fortunate)

12:28 thheller: seangrove: the JS prototype i presume?

12:28 EvanR: yeah i have NettyBufferedStreamCache at the moment, when a minute ago it was a RemoteFile

12:28 thheller: eg. add an instance method the Chainable. instances?

12:28 EvanR: hopefully the input-stream magic works in both cases

12:29 llasram: Worst-case you'll need to do some interop to get at something which can generate byte/buffers

12:30 EvanR: decode-stream returns a "channel"

12:31 java.nio.Channel...

12:31 whats this?

12:33 llasram: I thought it returned a manifold channel, but I haven't looked at manifold in detail yet -- maybe that's what it uses under the good?

12:33 seangrove: thheller: Yeah, exactly

12:33 llasram: EvanR: lazy-decode-all might be more appropriate. It's honestly been a while since I last used gloss, and I don't have the code for the project handy at the moment

12:33 And alas ztellman doesn't seem to be around at the moment

12:33 thheller: you can do that in deftype via Object

12:34 (deftype Chainable [coll] Object (someFunction [this] ...))

12:34 (.someFunction (Chainable. []))

12:34 would work after that

12:34 seangrove: thheller: Sorry, yes, doing that, but it adds it to the object, not its prototype

12:34 thheller: hmm nope?

12:35 seangrove: I need to add a .toString method to the prototype so the chrome dev console can print out a string represetation by default

12:35 EvanR: it does return a manifold.stream... rather than whats advertised

12:35 manifold/stream

12:35 thheller: dev console doesnt use toString AFAIK

12:36 if you check Chainable.prototype.someFunction in the console its all there

12:36 weavejester: Has anyone experienced issues with cljx recently?

12:37 I updated to 0.5.0 and it keeps excepting with "namespace 'cemerick.piggieback' not found"

12:37 seangrove: thheller: Thanks, I'll check that out again, I must have been mistaken about it

12:38 thheller: I wanted to change the way console prints objects too some time ago

12:38 eventually gave up though :P

12:38 seangrove: thheller: Ah, never got it?

12:39 sdegutis: Never mind, I figured it out.

12:40 thheller: well sort of. I now have a helper function+macro that first runs its arguments through (console-friendly val)

12:40 console-friendly checks whether an object satisfies IPrintWithWriter, if it does it prints that

12:41 except for some special cases (basically the types console already likes)

12:41 EvanR: ok so, before i dive into whats necessary to do all this... how do you "just" decode the contents of a InputStream and get a string

12:41 thheller: got tired of not being able to log clojure maps

12:41 EvanR: (str just gives "BufferedInputStream@..."

12:41 seangrove: thheller: Very nice - does that handle lazy infinite sequences nicely? I'd be concerned about locking up the console whenever it tried to pretty-print some custom cljs object

12:42 thheller: no it will blow up

12:42 but I don't have those ;)

12:42 seangrove: thheller: Heh, awesome, thanks for the head sup

12:42 heads up, even

12:43 thheller: might be possible to extend the dev tools to support more objects

12:43 but not sure how to

12:43 EvanR: slurp

12:44 weavejester: Looks like the latest cljs version doesn't work well with cljx...

12:44 sdegutis: Given [[:a 1 10] [:a 3 20] [:b 4 80] [:c 2 90] [:b 5 30]] what's a reasonable way to get {:a [[1 10] [3 20]] :b [[4 80] [5 30]] :c [[2 90]]} ?

12:44 dnolen_: thheller: re: CLJS-948, faster to discuss here

12:44 sdegutis: Btw this is not a homework problem.

12:44 thheller: hey, sure. whats up?

12:44 sdegutis: I know it looks like it but trust me it's really not.

12:45 dnolen_: thheller: seems like this is just a problem w/ the patch no? in the cached case we invoke parse-ns with :load-macros true and :analyze-deps true

12:45 thheller: line 1876 in analyzer.clj, so I do not understand why we aren't covered

12:48 sdegutis: group-by might work here, but then the values would need to be stripped of the first argument which is ugly.

12:48 *first element

12:48 thheller: checking, I'm not too familiar with the core caching code

12:48 dnolen_: thheller: that's the point of that line and why caching works at the moment

12:49 thheller: perhaps we don't propagate those options through

12:49 thheller: I ran into the described issue with shadow-build, roughly following the cljs code I presumed it would have the same issues

12:51 OscarZ: im trying to learn about macros here: http://learnxinyminutes.com/docs/clojure-macros/ .. this is weird stuff.. is it that when macro is run in code, it does some kind of bytecode generation / compilation at that time so it will be quite slow?

12:51 just thinking about what macro actually compiles to

12:51 what is fixed at that point

12:52 hellofunk: OscarZ: macros do not run at runtime, the run at compile time and they output code that is then compiled and run at runtime

12:52 \

12:52 dnolen_: thheller: testing should only be about ClojureScript - shadow-build is separate concern

12:52 hellofunk: OscarZ: they are like writing a program that runs before your program runs

12:52 lodin: sdegutis: Use (fn [[k & vs]] {k [vs]}) and then merge-with concat.

12:53 dnolen_: thheller: if there's something that make using the functionality difficult to use from shadow build that can addressed too but that's not the first thing to test

12:53 sdegutis: lodin: sounds clever! I'll try it :)

12:53 dnolen_: s/make/makes

12:53 lodin: sdegutis: Adjust accordlingly if you really want vectors everywhere.

12:53 sdegutis: nah

12:53 thheller: yeah of course. strill trying to understand the code path of caching

12:54 analyze-deps is confusing

12:54 dnolen_: thheller: it's just bottom up

12:54 thheller: let me try a plain CLJS example and see if I can reproduce the problem

12:54 dnolen_: thheller: analyze-deps always goes through analyze file

12:54 hiredman: Bronsa: does tools.reader have some kind of thing where it can read in a clojure map, but tell me what order the keys appeared in the source?

12:54 dnolen_: thheller: caching, reading caches only happens in analyze-file

12:55 thheller: yeah I mean analyze-deps and how it relates with cache

12:55 there is a :restore option

12:55 dnolen_: thheller: analyze-deps just defers to analyze-file

12:55 thheller: don't confuse `parse-ns` w/ anything else :)

12:55 hiredman: we have this big map of stuff at work, and I would like to enforce that entries added to it are sorted

12:56 dnolen_: thheller: `parse-ns` is a utility for parsing namespaces, you normally want to backtrack side-effects to compilation enviroment

12:56 thheller: wait parse-ns doesn't actually read the cache?

12:56 postpunkjustin: OscarZ: try playing around with the macroexpand function to see some examples in action

12:56 Bronsa: hiredman: the source logging reader keeps the string source around

12:56 dnolen_: thheller: absolutely not

12:56 postpunkjustin: ,(macroexpand '(when-not true :body :body))

12:56 OscarZ: ok, will do

12:56 clojurebot: (if true nil (do :body :body))

12:56 dnolen_: thheller: I think you keep getting tripped up about parse-ns, it's just a utility used for extra ns-info

12:57 thheller: it defaults to never mutate the compilation environment, never analyze dependencies

12:57 thheller: only when we read a cache file do we disable the defaults

12:57 hiredman: Bronsa: seems like that would leave me back were I started (having a string that contains a clojure map that I want to check the order of keys in)

12:57 Bronsa: hiredman: http://sprunge.us/eUfd?clj not sure if that'll be much helpful though

12:58 dnolen_: s/used for extra ns-info/used for extracting ns-info

12:58 Bronsa: hiredman: yeah..

12:58 sdegutis: lodin: beautiful, thanks :)

12:58 thheller: ah, alright.

12:59 hiredman: maybe I can use parsley's parser

12:59 Bronsa: hiredman: at the moment there's nothing else that would help you, a parser would probably be a better help

13:00 thheller: dnolen_: then there should be no problem, totally got that wrong

13:00 dnolen_: thheller: so the patch should be fine as is?

13:01 thheller: I would think so

13:01 as long as *load-macros* is true there is no problem

13:02 which it seems to be unless one manually calls parse-ns without

13:02 It is kinda difficult to write a test for this since you'd have to unload the macro namespace

13:04 cemerick: weavejester: please file an issue

13:05 sdegutis: (inc lodin)

13:05 lazybot: ⇒ 1

13:05 weavejester: cemerick: I will when I isolate the problem :)

13:07 lodin: :-)

13:28 arnaudsj: hi, is there a particular IRC room for the numerical clojure? (such as core.matrix and/or incanter)

13:33 mikerod: Who can explain why all over the clj Java source there are calls of this form: Util.ret1(arglist.first(),arglist = null)

13:34 I'm guessing it has something to do with ensuring the reference is null'ed out for gc or something

13:34 but it is strange to me. I don't see why that is necessary.

13:34 tbaldrid_: mikerod: yeah, that has to do with locals clearing.

13:34 mikerod: it may be called "locals clearing" I think from some digging, but I haven't really seen that explained anywhere in anything I've searched for

13:34 tbaldrid_: It passes the arg in, while at the same time setting the arg to null.

13:35 mikerod: tbaldrid_: yes, I always hear this "locals clearing", but I can't find anything about it

13:35 So here I was looking at AFn#applyToHelper

13:35 I don't get why you'd have to manage that reference setting to null

13:35 seems like when the method exited, the hard reference would be gone

13:35 tbaldrid_: Without it, if you passed a lazy seq into a function and that function called into another, and the inner function walks the seq, the outer call frame would hold onto the head, exhausting memory

13:36 hiredman: compiled java code generally puts local variables in slots provided for such in the method, and unless you null those out, they count as a gc reference

13:36 tbaldrid_: mikerod: right, but that allows the GC to clean it up before the method exists

13:36 mikerod: or something like that. I just haven't written Java where I always have to worry about null'ing out my params, locals, etc

13:36 tbaldrid_: mikerod: how often do you write Java code that uses a lazy seq? ;-)

13:37 weavejester: Hm, there's no way of extending a protocol with another protocol, right?

13:38 tbaldrid_: weavejester: not in CLJS but in CLJ you can I think.

13:38 stuartsierra: mikerod: In theory, the JVM could determine that the references aren't used after the tail call and GC them. But since it's not a common pattern in Java, it doesn't.

13:38 weavejester: tbaldrid_: That makes sense, because you can extend interfaces

13:38 stuartsierra: s/tail call/return/

13:39 hiredman: weavejester, tbaldrid_: nope

13:39 weavejester: yeah, you will be extending the protocol to the interface that backs another protocol

13:39 which is not the same thing

13:39 weavejester: Hm, right...

13:39 stuartsierra: You can extend a protocol to an interface, but it gets confusing because you can end up with multiple inheritance.

13:39 hiredman: and stop using the interface that backs a protocol

13:40 unless you are careful you are going to have a bad time

13:40 mikerod: tbaldrid_: hiredman thanks!

13:40 tbaldrid_: right, that's what I was thinking of.

13:40 mikerod: I feel enlightened

13:40 it is a lazy seq thing

13:40 hiredman: really the only time to use the interface that backs a protocol is if you have a java type you control you want to extend the protocol to

13:40 tbaldrid_: If I really needed that I guess I'd consider definterface + extend.

13:40 mikerod: I remember reading some old old clj mailing lists posts

13:40 weavejester: So how would I extend an ISeq with a protocol... I guess I can't

13:41 I'd have to use a multimethod.

13:41 mikerod: about holding onto the head and how "locals clearing" was being done all over

13:41 that makes sense to me now

13:41 tbaldrid_: weavejester: ISeq is a interface....

13:41 weavejester: tbaldrid_: Not in cljs

13:41 tbaldrid_: oh yeah, well CLJS is a whole different beast

13:41 weavejester: I'm currently writing a Functor protocol, but I've just realised it won't work in cljs.

13:42 tbaldrid_: "I'm currently writing a Functor protocol" Well there's your problem ;-)

13:42 weavejester: tbaldrid_: Is there a reason not to?

13:43 tbaldrid_: no, I'm just giving you a hard time about writing category theory stuff.

13:44 mikerod: stuartsierra: I'm guessing you ar referring to TCO here right?

13:44 oh, just tail-call clearing

13:44 tail-call locals clearing

13:44 not necessarily removing the stack frame completely

13:44 weavejester: tbaldrid_: I just want an efficient way of mapping over a collection without changing it. Functors seemed the logical way to go about it :)

13:45 tbaldrid_: like transducers?

13:45 weavejester: tbaldrid_: Do transducers retain the collection type?

13:45 I didn't think they made that guarantee.

13:46 stuartsierra: There's an fmap implementation in https://github.com/clojure/algo.monads

13:46 tbaldrid_: no, but I'm pretty sure you could fake it with conj!, and empty.

13:46 hiredman: obviously you need a lens

13:46 weavejester: stuartsierra: Yep, but it uses multimethods. I wanted something a little more efficient.

13:46 tbaldrid_: hiredman: we need a clojurebot response for that ^^

13:47 stuartsierra: If you know the result type you want you can always build it with a transducer.

13:48 weavejester: Hm... I could redesign it to use transducers. Does cljs have them yet?

13:48 mikerod: use `into` w/ transducer

13:48 tbaldrid_: yep

13:48 mikerod: `into` <what-type-i-want> <transducer>

13:48 tbaldrid_: transducers were ported to CLJS within about a week of them being reduced

13:49 dnolen_: weavejester: cannot extend protocols to protocols unless you catch them in default case

13:49 tbaldrid_: ,(let [v [1 2 3]] (into (empty v) (map inc) v))

13:49 clojurebot: [2 3 4]

13:50 tbaldrid_: ,(let [v #{1 2 3}] (into (empty v) (map inc) v))

13:50 clojurebot: #{4 3 2}

13:50 weavejester: tbaldrid_: I wanted to make use of more efficient functions, like reduce-kv, transients and mapv.

13:51 I might just put this aside for now and wait for transducers...

13:51 tbaldrid_: weavejester: well into will use transients, as well as collection specific reduce, and all that exists in CLJS today.

13:51 weavejester: tbaldrid_: Oh, hm, that's right.

13:53 I guess I'll shelve this and wait until 1.7.

13:55 tbaldrid_: lol, yeah I forget that 1.7 isn't out yet.

13:56 that's why we should keep languages in perpetual alpha, like CLJS

13:57 hiredman: *snort*

14:02 sdegutis: I keep forgetting or not knowing what types my bindings are.

14:03 How do you usually deal with this problem?

14:05 weavejester: sdegutis: What do you mean by bindings? Bound symbols, or dynamic vars?

14:05 justin_smith: sdegutis: I like to use prismatic/schema to declare the shapes of incoming data (at least the important parts, ie. the keys I care about in a given map)

14:05 sdegutis: weavejester: Symbols bound by lets & friends, and function parameters.

14:05 *by let

14:06 justin_smith: do you mean in the context of within an app's source code, or just when an app receives data from an external service?

14:06 postpunkjustin: sdegutis: I second justin_smith's recommendation of prismatic/schema. I've also been using core.typed lately.

14:06 Otherwise docstrings

14:06 justin_smith: sdegutis: within the source code, where the bindings are declared

14:07 sdegutis: for data internal to the app, using it as a type declaration

14:07 I think the name "schema" hides how generally useful its assertions / descriptions are

14:08 sdegutis: Hm.

14:08 postpunkjustin: schema makes for great code documentation, even if you turn it off at runtime

14:09 justin_smith: it's not going to enforce the rigour that core.typed does, but then again it doesn't demand the rigour that core.typed does, which is nice

14:17 zB0hs: is there a function to get a subset from a set using indices, so if i have #{1 2 3 4 5} i want to return 3 and 4

14:18 justin_smith: zB0hs: sets are not ordered

14:18 zB0hs: justin_smith i had a feeling. thanks

14:19 justin_smith: you can sort them and then do something like that with the sorted result

14:19 or use sorted-set / sorted-set-by

14:20 zB0hs: justin_smith if i convert to a vector is the order guaranteed?

14:20 tcrayford____: no

14:20 sets don't have defined order

14:20 if you convert to a vector, then sort it, sure

14:21 justin_smith: if you want a specific sorting based order, sorted-set is likely what you want (just remember they don't do the pr-str / read round trip

14:21 tbaldrid_: zB0hs: if you seq over the same set more than once, the order will be the same

14:21 zB0hs: but if you add/update/remove an item from the set the order may change

14:22 zB0hs: thanks tabldrid_

14:22 tbaldrid_

14:22 justin_smith: tbaldrid_: or serialize to edn, and read from a different clojure version the order may change too (odd scenario, I know, but worth considering)

14:22 statan: Started using Clojurescript with NodeJS but I find myself doing more (. setProperty jsObject "value") than (cljsfunc [args] body) so I'm wondering .... what's the point? I'm not really programming in values if most of the time I'm get/setting properties in JS objects. Or maybe I'm missing the obvious.

14:23 justin_smith: statan: if most of what you are doing is using existing libs, you will see a lot of interop, but the more logic you actually implement, the more native cljs, I would guess

14:24 statan: similar comes up in jvm clojure - if what I am doing is mostly using java libs, then my code is a bunch of interop

14:24 mfikes: statan: I've ended up feeling the same way when driving UIKit from ClojureScript.

14:24 statan: justin_smith: There are very few cljs libs so you end up using a ton of Node libs.

14:24 justin_smith: statan: yeah, I would imagine

14:25 but I guess "the point" is that for whatever amount of unique logic you implement, you get the benefits of immutability and functional design (as much as you leverage these at least)

14:26 statan: Unless we replicate the masses of Node/JS libs that's not going to happen.

14:26 justin_smith: Rewrite node libs in cljs I mean.

14:27 justin_smith: ie. a LOT of work which probably won't happen

14:28 postpunkjustin: satan: right, I wouldn't hold my breath for node libs to be rewritten (or even wrapped) in cljs

14:28 justin_smith: statan: I bet the java standard libs compare well in size to node and the usable libs for it

14:28 mfikes: statan: As justin_smith says, when I look at some imperative code that interacts with UIKit, there's lots of little functional nuggets I can extract and put off to the side.

14:28 statan: justin_smith: I'm not sure a small amount of cljs code interop-ing with a mass of mutable/oo js is much of a win.

14:28 postpunkjustin: I also don't think the cljs/node combo is that great

14:29 justin_smith: statan: and sure I end up using interop, but a fair amount of what I implement is logic that isn't just some calls to an existing lib

14:32 dnolen_: http://mullr.github.io/micrologic/literate.html

14:36 justin_smith: dnolen_: cool

14:58 sdegutis: Hi. I wrote an OOP library. Any feedback? https://github.com/sdegutis/oops

15:02 thearthur: sdegutis: i like the name :-)

15:02 AimHere: I thought the lack of OOP was supposed to be a clojure selling-point!

15:02 sdegutis: thearthur: :)

15:03 AimHere: OOP has its place just like FP does; they're not mutually exclusive

15:03 thearthur: which is why the name is great!

15:03 sdegutis: thearthur: yeah it's a nod to the common misconception that OOP is lesser than or incompatible with FP

15:04 All the library mostly does is allow you to bind an implicit first argument to a function, containing state and other functions with the same implicit first parameter.

15:04 tbaldrid_: complecting state with code

15:05 sdegutis: I'm not sure it can rightfully be called "state" since it's immutable.

15:06 This is for those times when you have a group of functions which act on the same data.

15:07 tbaldrid_: so a few bits of feedback (ignoring my aversion to OOP):

15:07 1) this is going to be super, slow, perhaps even slower than multimethods

15:08 2) unless you're namespacing methods and fields, it's going to be pretty easy to accidentally include two mixins with the same name or a mixin could override a field.

15:09 sdegutis: Regarding #2, that's a good point; I'll make a note of it in the readme that people should take care to avoid name collisions.

15:09 I don't know how to fix #1, although I'm not sure it'll be *super* slow.

15:10 tbaldrid_: well it won't be jitted properly since the JIT doesn't have a way to promote the method bodies to constants. And you'll also have the overhead of a hashmap lookup on every callsite.

15:11 sdegutis: I imagine it's still faster than Ruby :)

15:11 tbaldrid_: probably not, since Ruby at least caches method lookups, as does ObjectiveC

15:11 you might be able to add that, but it'd take some magic

15:12 sdegutis: But Clojure is already significantly faster than Ruby.

15:13 tbaldrid_: that's partly because the JIT can inline, you're removing that with this programming model

15:14 sdegutis: Hmm. I don't know how to allow the JIT to promote method bodies to constants.

15:15 tbaldrid_: that's why defprotocol exists vs. multimethods, and why protocols are about 100x faster

15:16 but benchmark it and see, I could be wrong

15:16 sveri: tbaldrid_: Uh, I didnt know that, is that 100 times made up or from some real benchmarks?

15:17 puredanger: I don't believe that diff

15:17 I have not measured it recently but that seems improbable

15:19 amalloy: even 10x seems improbably high

15:20 tbaldrid_: https://searchcode.com/codesearch/view/26894602/

15:21 that was the research done my the core.matrix project awhile back ^^

15:21 turbofail: i suspect that would depend a lot on the dispatch function

15:21 and the calling pattern

15:21 tbaldrid_: 231.00 us for multimethods, 7.95 us for interface based protocol dispatch, 13.81 us for non-interface protocol dispatch

15:22 so no, not 100x, that's only 33x, my bad :-)

15:22 sveri: tbaldrid_: thanks, good to know that

15:23 tbaldrid_: that being said, I use multimethods all the time. I just wouldn't use them inside a tight inner loop.

15:24 puredanger: the 231 is for double-multimethod, should be comparing to the class-multimethod I think? that was 89 us

15:25 gfredericks: protip: a multimethod that uses a multimethod that uses a multimethod as its dispatch function as its dispatch function

15:25 TimMc: tbaldrid_: Only half an order of magnitude off, good enough for gov't work.

15:25 gfredericks: StackUnderflowError

15:25 gfredericks: TimMc: what

15:30 puredanger: I just re-ran those on 1.7.0-alpha4 locally and I got 7.4 us for protocol, 39.9 us for multimethod

15:30 so 5x

15:30 gfredericks: 5 is O(100)

15:31 puredanger: not sure if serious or joking. if serious, not sure what you mean. ;)

15:32 gfredericks: I meant something that is technically true and completely irrelevant to the situation

15:32 puredanger: ok, then I'm in agreement :)

15:33 gfredericks: well it might be relevant but it's at least not at all helpful

15:33 puredanger: there were some perf changes in multi methods in 1.6, not sure when those numbers were run

15:34 seangrove: dnolen_: I need this for the mori.chain ns I'm working on http://dev.clojure.org/jira/browse/CLJS-698 - if there's still interest, I can take a stab at a patch

15:35 sdegutis: The whole point of Clojure is expressiveness and building the language you need for your situation. If efficiency is a primary goal then Java would be better suited.

15:36 puredanger: actually I'd say the whole point of Clojure is expressiveness WITH efficiency

15:36 seangrove: Hrm...

15:36 I didn't think expressiveness was as important as containing complexity

15:36 dnolen_: seangrove: I'm kinda meh on that, why can't you just use it goog.exportSymbol directly, sees trivial to macroize too

15:36 s/sees/seems

15:37 turbofail: i'm with puredanger on that one

15:37 seangrove: dnolen_: So after the deftype, just manually invoke goog.exportSymbol for all of the symbols?

15:37 turbofail: it's nice that clojure makes it possible to have abstractions that don't necessarily cost you much at runtime

15:38 dnolen_: seangrove: yep

15:38 AimHere: Isn't that the case with C++ too? Templates are entirely compile-time

15:38 seangrove: dnolen_: I'm fine with that

15:38 puredanger: seangrove: I think expressiveness and "containing complexity" are squishy enough that they may have overlap. but my point is that Rich is generally not interested in changes that make Clojure more expressive at the expense of performance

15:38 dnolen_: seangrove: cool

15:38 turbofail: AimHere: well that's where the extra expressiveness comes in as well

15:39 AimHere: Well templates do make C++ more expressive

15:39 turbofail: i suppose they can

15:39 mi6x3m-alt: AimHere: never seen templated C++ code which is expressive for a human being

15:39 sdegutis: puredanger: I've never considered or heard of efficiency being a primary reason for Clojure -- it was always entirely expressiveness

15:40 turbofail: that said clojure is still a lot more expressive than C++ for most purposes

15:40 sdegutis: puredanger: I think Rust would be better suited for expressiveness WITH efficiency

15:40 seangrove: puredanger: That's fair, definitely

15:41 turbofail: more like the expressiveness of many other high level languages, while still being much more efficient than said languages

15:42 gfredericks: sdegutis: I hear about clojure + efficiency all the time; e.g., compared to jruby

15:42 puredanger: sdegutis: efficiency drove (and continues to drive) many design decisions around Clojure

15:43 like it should probably be fast enough to like write a database in for example

15:44 if the language designer wanted to do such a thing :)

15:44 sdegutis: I know of two camps using Clojure -- one that uses it mostly for very comp-sci problems requiring efficiency, and one that uses it mostly as an alternative to Ruby and were drawn to it primarily due to its expressiveness and discouragement of Rails-like magic

15:45 You half-dozen belong to the first camp. Everyone else I know belongs to the second.

15:45 (Rich and the Datomic team belong mostly to the first also.)

15:45 mi6x3m-alt: sdegutis: I cannot agree there. As an alternative to Ruby? Please

15:45 sdegutis: mi6x3m-alt: you sound like you're from the first camp

15:45 puredanger: those are definitely two of the major paths to clojure

15:46 sdegutis: mi6x3m-alt: you also sound like you haven't met anyone from the second camp

15:46 mi6x3m-alt: sdegutis: I am not and most clojure software I've seen is very far from comp.sci. and very practical

15:46 sdegutis: puredanger: what are the others?

15:46 turbofail: meh. i like clojure for both of those reasons. they're not two separate camps

15:46 sveri: how about an alternative to java?

15:46 puredanger: some people come to it from js via cljs

15:46 mi6x3m-alt: you should listen to sveri

15:46 puredanger: some come to it via java

15:46 sdegutis: What benefit does it give over Java?

15:47 sveri: I mean, JVM is one of the big selling points for clojure

15:47 mi6x3m-alt: readibility sdegutis

15:47 puredanger: abstraction, concision, expressivity

15:47 sdegutis: I would probably rewrite our site in Java 8 if I was allowed.

15:47 hfaafb: be careful or you'll end up in one of sdegutis's camps

15:47 turbofail: also, functional data structures

15:47 gfredericks: "comp-sci" is kind of a vague term here

15:47 puredanger: we've got hot dogs at my camp

15:47 mi6x3m-alt: sdegutis: could it be you belong to a third, very negative camp?

15:47 sdegutis: Oh right. I'm in #clojure, I forgot.

15:47 No criticism of Clojure allowed at all (as an unwritten rule).

15:47 puredanger: I heard they've got volleyball at the one next door

15:48 I'm just glad we're out of school

15:48 turbofail: was there criticism? i didn't really see any

15:48 sdegutis: Not that I'm even criticizing Clojure, but painting a picture about who uses it that nobody wants to believe.

15:48 puredanger: maybe there's a knot-tying clsas

15:48 mi6x3m-alt: I didn't catch any neither

15:48 puredanger: or actually for Clojure, maybe a knot-untie-ing

15:48 jarjar_prime: how do you return values from a recur?

15:49 gfredericks: sdegutis: people don't tend to react well to being put in boxes

15:49 puredanger: (recur val1 val2 etc)

15:49 jarjar_prime: i am getting nil :(

15:49 mi6x3m-alt: jarjar_prime: (recur foo)

15:49 sdegutis: All I know is, there are many (many) people who are coming to Clojure from Rails as refugees.

15:49 puredanger: but of jarjar_prime but of course those don't "return"

15:49 mi6x3m-alt: jarjar_prime: to be exact, you return a value from loop

15:49 when you don't call recur

15:49 jarjar_prime: puredanger: that passes the value to the next loop

15:49 sdegutis: And they really don't care much about performance, they're just trying to make maintainable web apps.

15:49 puredanger: jarjar_prime: yes, my point. *don't* recur to return

15:49 jarjar_prime: ah, okay, so outside of the loop

15:50 tbaldridge: jarjar_prime: use a if to only call recur if you want to recur

15:50 gfredericks: sdegutis: I know people who came to clojure from rails for performance

15:50 sdegutis: And none of those people ever come in #clojure.

15:50 puredanger: it's almost like people use general purpose languages for all sorts of things

15:50 turbofail: also i didn't really see much criticism of your supposed criticism, so i don't really see where the "help i'm being repressed" thing is coming from

15:50 gfredericks: (inc puredanger)

15:50 lazybot: ⇒ 26

15:50 puredanger: did anyone catch my knot joke above? that was pretty good I thought.

15:51 llasram: (inc puredanger)

15:51 lazybot: ⇒ 27

15:51 llasram: (for the knot joke)

15:51 sdegutis: (inc puredanger)

15:51 lazybot: ⇒ 28

15:51 sdegutis: here let me increase your karma for you

15:51 (inc puredanger)

15:51 lazybot: ⇒ 29

15:51 mi6x3m-alt: puredanger: I laughed my ass off!!!!

15:51 puredanger: basks in karma

15:51 tbaldridge: puredanger: it was okay, but the analogy started to unravel after awhile.

15:52 sdegutis: (inc puredanger)

15:52 lazybot: ⇒ 30

15:52 puredanger: anyhow, I love you all and pssst I think we're all in one big camp

15:52 sdegutis: There now your karma is more than my age.

15:53 puredanger: later all.. gonna go finish writing HTML(!!!) to finish the new Clojure/West site

15:53 arohner: tbaldridge: puns are almost deserving of (dec), IMO :-p

15:53 sdegutis: What's an efficient way to create a simple Java class from within Clojure?

15:53 llasram: tbaldridge: I was a-frayed someone would say something like that

15:54 turbofail: ooh, clojure/west. where is that going to be this year?

15:54 gfredericks: sdegutis: depends what it's made of

15:54 sdegutis: cemerick made a great interop flow chart for answering that question, it should be googleable

15:55 puredanger: turbofail: Portland

15:55 turbofail: doh. might be a bit far for me

15:56 gfredericks: I had no regrets about portland

15:56 turbofail: though i've been looking for an excuse to visit portland anyway

15:56 llasram: I occasionally regret not living there, because it is so awesome

15:57 ystael: speaking of interop, am I wrong to wish it were possible to define an alternative constructor for a defrecord? sometimes what i want to expose to java callers could be exactly a defrecord, except that they have no way to create it with the intended contents, so i need to expose a separate factory class that makes them the right way

15:57 cfleming: SagiCZ1: It should be, yeah - I'll check that's not broken somehow

16:00 sdegutis: What's the current opinion on using deftype?

16:01 puredanger: it's fun

16:01 llasram: sdegutis: for?

16:03 sdegutis: I don't know, I just remember one of these things wasn't strictly deprecated but was discouraged by The Community.

16:03 tbaldridge: defstruct

16:04 gfredericks: ~defstruct is the goto of clojure

16:04 clojurebot: Ik begrijp

16:05 puredanger: it's not at all deprecated

16:05 llasram: puredanger: So you'd recommend using it in new code?

16:06 puredanger: if it was the right tool, sure

16:06 if you're making data, use the existing collections

16:06 tbaldridge: when is defstruct the right tool?

16:06 cfleming: deftype, that is, not defstruct

16:06 puredanger: we're talking deftype

16:06 cfleming: I'm assuming

16:06 tbaldridge: oh ok

16:06 puredanger: if you're making an information entity that represents part of your domain, use a record

16:06 if you need a custom data type that does special stuff, use a deftype

16:07 in practice, I think that's comparatively rare

16:07 turbofail: i mostly use deftype for interop things

16:07 cfleming: Yeah, I use deftype quite a lot

16:07 llasram: Oh, I thought we were talking about destruct

16:07 *defstruct

16:07 puredanger: the original question was "What's the current opinion on using deftype?"

16:08 I've literally never used defstruct ever

16:09 dnolen_: probably goign to have to add them to ClojureScript just as sugar over defrecord just to simplify porting clojure.pprint

16:09 justin_smith: ... scrollback ... PORTLAND! I look forward to meeting all you lovely people when you come to my fair city

16:09 puredanger: dnolen_: yuck

16:10 justin_smith: we're all staying at your place

16:10 keep meaning to tell you

16:10 dnolen_: puredanger: yeah, but in the end it does help with portability

16:10 turbofail: i guess most of those interop things would work just as well with defrecord. i just happened to have no need for the record stuff

16:10 cfleming: puredanger: Are there dates for Clojure/West yet?

16:10 justin_smith: awesome

16:10 puredanger: cfleming: Apr 20-22

16:10 cfleming: nice

16:11 justin_smith: I actually do have a spare room, but only the one

16:11 sdegutis: Is :gen-class discouraged except for in the "main" namespace?

16:11 puredanger: no?

16:11 clojurebot: no is tufflax: there was a question somewhere in there, the answer

16:11 turbofail: it's not "discouraged," it's just a pain in the ass

16:11 llasram: sdegutis: I'd personally say :gen-class is discouraged wherever it is unnecessary, which is generally everywhere

16:12 sdegutis: Oh.

16:12 turbofail: well some interop things require it

16:12 sdegutis: I'm looking for ways to use basic OOP features without dropping down to Java.

16:12 I think deftype is what I want, although I can't get it working.

16:12 turbofail: like if you want to make clojure work with spark, you have to do a named subclass

16:13 sdegutis: ,(deftype Person [] (greet [this] (prn "sup")))

16:13 clojurebot: #<CompilerException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)>

16:13 llasram: turbofail: Oh, are you one of the people doing one of the Clojure-Spark integration libraries?

16:13 puredanger: you need an interface or protocol in there

16:13 deftype can't just have methods

16:13 turbofail: llasram: no, just using them

16:13 sdegutis: What's the basic interface that has no methods?

16:13 llasram: turbofail: And not really, -- it just causes a class to be created for the namespace itself, which is almost never what you need

16:13 tbaldridge: sdegutis: no but you can use definterface to create a interface

16:13 sdegutis: Thanks.

16:14 llasram: turbofail: For anything depending on e.g. AOT for individual function-classes, :gen-class for the namespace is irrelevant

16:14 cfleming: llasram: Actually you can use gen-class to create multiple classes in a single namespace and call them whatever you want

16:14 SagiCZ1: sdegutis: don't you want clojure.typed?

16:14 sdegutis: Are definterface and defprotocol the same now?

16:14 SagiCZ1: no.

16:14 cfleming: sdegutis: No

16:14 SagiCZ1: sdegutis: ok nevermind then

16:14 llasram: cfleming: Sure -- I assumed the :-prefix on the original :gen-class mention was for specifically the `ns` form helper

16:15 seangrove: dnolen_: Trying to figure out how to get my mori.chain ns exposed/usable via require('../mori-chain'), or via require('../mori').chain - whichever is more idiomatic - is there some documentation in the cljs work about how to do that, or is it all on the js side?

16:15 sdegutis: SagiCZ1: I want a way to have a partial'd first "self" argument on my functions, and for them to each have access to instance variables.

16:15 turbofail: llasram: yeah that's true, :gen-class in the namespace is usually not necessary

16:15 cfleming: sdegutis: defprotocol creates an interface under the hood, but also creates a protocol

16:15 sdegutis: Oh.

16:15 SagiCZ1: sdegutis: yeah i am wondering what will you come up with in the end

16:15 sdegutis: SagiCZ1: I did this: https://github.com/sdegutis/oops

16:15 llasram: cfleming: But yeah, definitely no argument -- you can use `gen-class` to create an number of classes.

16:15 I personally even then find it to be actively worse than other options, but YMMV

16:15 gfredericks: (def ^:dynamic *this*)

16:15 llasram: turbofail: OOC which one?

16:16 dnolen_: seangrove: pretty sure we just export one object

16:16 llasram: turbofail: (Spark API, that is)

16:16 cfleming: llasram: Yeah, currently I just write a java class rather than use gen-class, which makes me want to scratch my eyes out

16:16 dnolen_: seangrove: so `var chain = require("mori").chain;`

16:16 llasram: (inc cfleming)

16:16 lazybot: ⇒ 7

16:16 llasram: :-)

16:17 turbofail: llasram: i was using flambo. but they all work pretty much the same way under the hood

16:18 llasram: turbofail: ok. I was hoping there was one I hadn't heard about... I'm hopefully getting Spark deployed soon at my company,

16:18 but I'm not a so-far a fan of certain design made by all the Clojure integration libs I'm currently aware of :-/

16:18 turbofail: yeah. spark is a lot more pleasant to use than hadoop, which is what we were using before

16:20 llasram: turbofail: Well, I wrote Parkour and have pretty full cluster-REPL integration with it. I'm hoping for faster multi-stage job-execution time with Spark, but

16:20 am currently worried the level of interactivity will drop until I give it some love

16:20 turbofail: well the existing clojure spark libraries do let you do a decent amount of REPL-integration

16:21 a lot more so than using spark from scala

16:21 llasram: That's good to hear

16:21 turbofail: only problem is you have to make sure you use their serializable function macros for every function you're going to call

16:21 llasram: Ah, yeah

16:21 There's the philosophical difference :-)

16:21 turbofail: and hope you don't capture anything in the environment that's not serializable

16:22 also toplevel defs won't get transmitted...

16:22 etc.

16:22 llasram: Cool. Cool. So then some time this year there will be a new Clojure-Spark integration library appearing :-)

16:23 TimMc: ystael: Or static methods on defrecords, that would also work.

16:23 zanes: llasram: https://gorillalabs.github.io/sparkling/

16:23 TimMc: Those are reasonable substitutes for constructors.

16:25 sdegutis: So far it looks like deftype with an identical definterface is exactly what I want.

16:25 Just need to macro them together into "defclass" for convenience.

16:25 turbofail: ah, looks like sparkling avoids gen-class by providing a bunch of java stubs

16:26 llasram: zanes: Has exactly the same problems

16:27 zanes: Ah, I wasn’t reading closely enough. Thought I saw you hypothesizing the existence of a Clojure/Spark integration lib.

16:30 llasram: zanes: Well, if you know of any others which don't share sparkling's heritage, then I am interested :-)

16:30 zanes: I don’t, sadly.

16:32 seangrove: dnolen_: Thanks, I'll try that. Wasn't working beforek, but if that's supposed to work then I'll keep digging

16:43 [blake|: I'm trying to use ring.middleware.defaults but when I try to redirect I get a "Invalid anti-forgery token".

16:44 weavejester: [blake|: By default, anti-forgery protection for POST requests is turned on

16:44 [blake|: If you don't have any sessions you can turn it off

16:47 [blake|: weavejester: I can probably turn it off anyway (I do have sessions, but it's an internal app), but I wish I knew how to use it.

16:47 weavejester: [blake|: There's a more detailed explanation here: https://github.com/ring-clojure/ring-anti-forgery

16:48 It's also linked from the ring-defaults README>].

16:48 sdegutis: I find it problematic that certain libraries are de facto simply because people don't know about any other options, and so they continue to spread the word that this library is great, not considering its pros and cons correctly.

16:49 tbaldridge: welcome to software development.

16:49 That's pretty much true of the entire .NET platform, or or any language platform

16:49 mi6x3m-alt: let's make survey, which is currently your favourite clojure library?

16:49 I vote for humanize

16:53 [blake|: weavejester: Thank you.

16:54 (inc weavejester)

16:54 lazybot: ⇒ 12

17:01 expez: what does 'could not find artifact <my-artifact> in clojars' usually mean when trying to do lein deploy?

17:26 justin_smith: expez: that's weird

17:28 sdegutis: Is calling a method on an instance of a deftype exactly as fast as calling a normal Clojure-function?

17:30 justin_smith: sdegutis: could be faster or slower, when you factor in var lookup vs. method reflection

17:32 tbaldridge: sdegutis: if you type hint it, yes

17:33 do (set! *warn-on-reflection* true) to make sure

17:34 sdegutis: Should I do that in -main?

17:35 tbaldridge: actually you probably want that at the top of your main namespace so that it's run before everything compiles.

17:36 sdegutis: Thanks :)

17:38 srruby: Any job leads? I'm a good Clojure coder. Ruby on Rails veteran.

17:39 sritchie: anyone notice that cursors in Om 0.8.0 are coming as as PersistentArrayMaps?

17:52 amalloy: tbaldridge: set! only applies to the current namespace. i think you know that already, but from what you said sdegutis might get the impression that setting *warn-on-reflection* in the main namespace makes it apply to all namespaces

17:52 tbaldridge: it does apply to all namespaces, as long as you set it before you load those namespaces

17:52 set! is global

17:54 amalloy: *warn-on-reflection* is referenced during compilation, so it only takes effect for future requires

17:54 amalloy: tbaldridge: *warn-on-reflection* is dynamically bound, and i thought it was re-set at the start of each file

17:55 tbaldridge: nope

17:55 amalloy: set! of course only applies to the innermost (binding), but you're saying it's only bound once

17:57 ben_vulpes: how would i go about writing a function that does different things based on its argument type? similar to multiple arity, but multiple *type*.

17:57 amalloy: tbaldridge: what is up with the Var.pushThreadBindings in Compiler/load, then? does that not get run when you require, or is it not equivalent to a binding or something?

17:57 ben_vulpes: (if (= (class arg) int) ...) ?

17:57 sdegutis: tbaldridge: Thanks for all your feedback. Based on your valuable input, I've made good use of definterface and deftype :) https://gist.github.com/sdegutis/c0e5cafee6add52c4bd9

17:58 mgaare: ben_vulpes: protocols are for taht

17:59 tbaldridge: amalloy: compiler line number?

18:00 Bronsa: sdegutis: I honestly can't understand if you're trolling or what but how is that an improvement over deftype? :|

18:00 sdegutis: Bronsa: first of all, it combines deftype and definterface; secondly, it gives an implicit self; thirdly I'm adding mixin functionality as we speak

18:00 When I'm writing Clojure-only classes that don't need to inter-op with Java, I don't want to have to declare the interface separately.

18:01 And in that situation, writing the 'this' parameter in one place but not the other is confusing.

18:01 Plus mixin functionality is useful in its own right.

18:01 amalloy: oh whoops. i'm looking at RT/load, not Compiler/load. i was thinking of https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L426, tbaldridge

18:01 but https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7163 looks similar

18:03 Bronsa: sdegutis: there are already libraries out there that provide you with extend-like traits/mixins support for inline deftype methods (e.g. https://github.com/Bronsa/neurotic, I think ztellman has one too)

18:03 sdegutis: Bronsa: that only addresses #3, what about the other two?

18:03 Bronsa: sdegutis: so you feel like trading writing a "this" for "defmethod" is a worthwile improvement?

18:04 sdegutis: Yes.

18:04 Bronsa: well then go on with your macro.

18:04 sdegutis: Thanks :)

18:05 Is there any way to get the current value of a symbol during expansion time without passing it as the result of your macro?

18:06 tbaldridge: nope, that's not how lisp works

18:06 compile time vs runtime

18:06 turbofail: unless you're using picolisp or something

18:07 tbaldridge: I'll say this, whenever I've tried something different in a language, and it's not exactly working out, or it's awkward, I have to stop and ask myself it it's something I should be doing. Or if its a bad fit for the language

18:08 sdegutis: I guess that's why you're getting so much push-back on stuff like this. You're trying to do something that doesn't exactly fit with the language you're using. The questions you are asking imply that you don't fully understand the ramifications of what you're trying to do.

18:19 [blake|: OK, maybe I'm doing this wrong. Recommended way to get session info (e.g., username) into the web page?

18:25 sdegutis: tbaldridge: yeah I totally get that what I'm doing is not idiomatic

18:25 tbaldridge: but I don't fully agree with idiomatic Clojure, so that's why I'm doing it in the first place.

18:26 What I'm trying to do is store something in one macro during compile-time so that I can use it in another macro.

18:26 I was hoping to just leave a quoted form somewhere and later eval it when it's used in the other macro.

18:27 Maybe I can manipulate &env.

18:33 It works!!! https://gist.github.com/sdegutis/c0e5cafee6add52c4bd9

18:37 And here's a readme: https://github.com/sdegutis/oops

18:41 postpunkjustin: ...

18:41 seangrove: Is there anyway to add a property to a (deftype ... [coll] Object )? Seems like it's only possible to add functions

18:42 amalloy: seangrove: you mean a field?

18:42 tbaldridge: sdegutis: in cljs?

18:42 seangrove: amalloy: Ah yes, that's it

18:42 sdegutis: tbaldridge: I doubt this works in cljs.

18:42 tbaldridge: bleh, seangrove in cljs?

18:42 amalloy: that's the [coll] arg

18:42 sdegutis: ha

18:42 wrong person :)

18:42 amalloy: those are the fields

18:42 seangrove: tbaldridge: Yes, in cljs

18:42 * sdegutis tries to figure out how to make clojure.test work

18:42 seangrove: amalloy: haha, thanks

18:42 tbaldridge: seangrove: if this is in cljs you can just use (set! (.-bar foo) 42)

18:43 there's no way to do it in deftype specifically, but they're just JS objects at the end of the day, so have at it

18:43 seangrove: tbaldridge: That's an interesting idea as well, thanks

18:48 mearnsh: [blake|: are you looking for a way to do authentication?

18:50 [blake|: "...handles things like retaining authentication details in the user session" => https://github.com/cemerick/friend#authentication

19:10 [blake|: mearnsh: I've got an LDAP thing working. I'm just having trouble displaying the user name and retaining the session info.

19:11 Well, one or the other, probably not both.

19:15 I'm trying to pull apart what everything does, since the defaults don't seem to be working for me.

19:17 mearnsh: alright, i'm still learning too but have used cemerick/friend recently to good effect for managing :session

19:18 [blake|: Well, maybe I can use it to figure out where I'm going wrong, thanks.

19:20 mearnsh: it has a number of "workflows" that make it easy to integrate with http-basic, forms etc.

19:22 [blake|: Looks like it's just using handler/site, which is what I'm doing.

19:24 seangrove: Do I have to require/import anything to use (goog/exportSymbol "mySymbol") in cljs?

19:33 dnolen_: seangrove: should not pretty sure it's declare in base.js

19:33 s/declare/declared

19:34 julianleviston: Is this a better room to ask cljs questions than #clojurescript/

19:36 How do I control an Om input whose type is file? I have a function attached to onchange, and every time I change the file, it disappears.

19:36 Ordinarily, I’d hook some component local state up to value, but it’s not the value that’s being controlled, if I understand it correctly, it’s the files attribute. If I try to set the files attribute to some component local state it doesn’t alter its behaviour. Neither files nor value work.

19:41 dnolen_: julianleviston: don't think this can be done w/ React not an Om issue https://groups.google.com/forum/#!topic/reactjs/sqfVJqlQc2E

19:41 julianleviston: there's a #clojurescript channel btw for questions like this, people ask Om/Reagent etc questions there

19:45 julianleviston: dnolen_: thanks

20:03 underplank: Hi all. So I want to be able to exec a long running process from a clojure app. say like a python webserver. I found the “sh” command and also (.exec (Runtime/getRuntime ….) …is there anything else?

20:04 Also with the getRunTime the code example I found used (read-lines ).getInputStream process) which I think comes from an old contrib lib. How is the normal way to read from a java stream

20:08 exaptic: underplank: i've used conch a bit, which provides some nice abstraction

20:08 underplank: there's also clojure.java.shell if conch is too high level

20:09 underplank: yeah. So I saw the shell thing. and it seems like its for running “ls” or something like that. I wasnt sure how it handled long running processes that continue to output data

20:11 exaptic: underplank: well i think, you can opt to get streams back i think

20:12 underplank: ahh, cool. I’ll have a look at that

20:13 exaptic: underplank: hmm, nm -- can't find that option now

20:13 underplank: check out conch https://github.com/Raynes/conch

20:13 underplank: cool just lein installed it :)

20:13 exaptic: "Conch is more flexible than clojure.java.shell because you have direct access to all of the streams and the process object itself."

20:21 i've had success with it

20:32 jarjar_prime: :)

20:33 how would I merge a sequence of vectors into one.... ([:a] [] [:b]) -> [:a :b]

20:34 i've come up with... (into [] (apply concat (for [b x] (into [] b))))

20:34 but i'm wondering fi that will not be performant

20:35 tbaldridge: jarjar_prime: I'd do something like reduce + into

20:35 ,(reduce into [] '([1 2 3] [4 5 6]))

20:35 clojurebot: [1 2 3 4 5 ...]

20:35 jarjar_prime: haha, thanks clojurebot :D

20:36 tbaldridge: thanks, that definitely reads better

20:37 is reduce doing something similar to apply concat?

20:58 exaptic: it's evaluating (into [] [1 2 3]), then (into [1 2 3] [4 5 6]) and returning the result of the second

20:59 (it evals one "into" for each element of its third argument)

21:11 julianleviston: what about vec concat?

21:11 (vec (concat [1 2 3] [ 4 5 6]))

21:12 ohhhhhh a sequence of vectors…

21:14 Then I guess (vec (apply concat '([1 2 3] [4 5 6]))) would work.

21:52 atratus: does anyone know what the subscript S on crossclj means?

22:07 scottj: atratus: where? I'd guess it means it runs on clojure and clojurescript

22:09 dnolen_: seangrove: everything merged

22:09 seangrove: I think the smartest thing to do is next is partitioned builds through Google Closure modules

22:10 scottj: atratus: based on http://crossclj.info/ns/org.clojure/core.async/0.1.346.0-17112a-alpha/clojure.core.async.html I'd say the s means it's clojurescript

22:10 dnolen_: seangrove: we could write a custom script for this of course, would be a bit tedious - the right way to do would be to fix the outstanding ClojureScript ticket so everyone can benefit

22:11 seangrove: then we could ship a core which is just data structures and basic ops, then addons (full standard lib, chaining operations)

22:40 seangrove: anyways I got some cycles to work on CLJS tomorrow perhaps can spend some time on this myself. thanks for the PRs, night

Logging service provided by n01se.net