2014-10-28
| 00:01 | justin_smith | fairuz: I'd avoid things like database interaction in the live mode - I think it will try to |
| 00:01 | justin_smith | fairuz: and as you edit the code it will likely repeatedly execute the command, which likely isn't what you want? |
| 00:02 | justin_smith | fairuz: if you want the advantage of live mode you could make a function that generates the *data* that generates the db action, and then use live mode to look at that data |
| 00:02 | justin_smith | and finally have a trivial function that takes that data and plugs it into a db call |
| 00:02 | justin_smith | (that you don't use in a live repl, of course) |
| 00:02 | justin_smith | *live mode |
| 00:06 | fairuz | yeah that's what I realize too |
| 00:07 | fairuz | I made a mistake of trying to connect to the database in live mode |
| 00:07 | fairuz | and it create some files along the way as I type the path |
| 00:07 | fairuz | so need to clean that up :(' |
| 00:07 | justin_smith | fairuz: having one function that does all the purely argument based logic and has no side effects (only a return value) and another (minimal) one that makes the side effects happen is pretty much the right way to do things in fp |
| 00:08 | justin_smith | fairuz: this also makes things like testing much more powerful, and easier to use |
| 00:08 | fairuz | justin_smith: ok great. I will slowly trying to adapt fp in my work :) |
| 00:09 | justin_smith | in clojure fp style is pretty much best (until performance backs you into a corner) |
| 00:10 | justin_smith | and even then, much of clojure is tailored so the fp way to do it will be the way that performs decently |
| 00:15 | fairuz | j |
| 00:47 | justin_smith | TIL lein beanstalk is broken with clojure 1.7 :( |
| 00:48 | sm0ke | feeling adventurous? |
| 00:49 | justin_smith | sm0ke: feeling like getting staging deployed and I found out at the last minute that 1.7 breaks my deploy step |
| 00:50 | justin_smith | I've been working with 1.7 for the past month, everything was great - until the part where I package it up for AWS |
| 00:50 | sm0ke | hurm there is a lein docker builder or something .. but probably too much? |
| 00:50 | justin_smith | beanstalk does not use docker |
| 00:51 | justin_smith | they run tomcat, you upload a war file |
| 00:51 | sm0ke | never used beanstalk, so you dont get a machine? |
| 00:51 | justin_smith | you do get one, but its cheaper because things are pre-configured, streamlined |
| 00:51 | sm0ke | weird, what if you needed some native libs to be installed? |
| 00:51 | justin_smith | has automatic scaling etc. that works because the boxes are generic |
| 00:52 | justin_smith | sm0ke: then you don't use beanstalk I guess |
| 00:52 | sm0ke | :/ |
| 00:52 | justin_smith | it's not for everyone |
| 00:52 | justin_smith | but if it works for your project, it is simpler and cheaper than a regular aws instance |
| 00:52 | sm0ke | aws is awful for long running services imo |
| 00:53 | sm0ke | and costly too |
| 00:54 | justin_smith | it's not very general or flexible, but it's very plug and play, which is why the client uses it |
| 00:54 | justin_smith | I'm just using their preferred stack |
| 00:55 | sm0ke | "But it works perfectly on my machine!" |
| 00:55 | sm0ke | this sould be printed on a t shirt |
| 00:55 | justin_smith | sm0ke: beanstalk actually prevents that - it wasn't that my project wouldn't run on beanstalk, it's that my clojure based deployment / building plugin broke with 1.7 |
| 00:56 | sm0ke | hurm but building part is done locally right? why did you not see this before? |
| 00:56 | justin_smith | sm0ke: because I was not building it |
| 00:57 | justin_smith | just running it |
| 00:57 | sm0ke | ah |
| 00:57 | justin_smith | to deploy, I pack up a war file |
| 00:57 | sm0ke | lein ring? |
| 00:57 | justin_smith | which is a jar with certain special classes defined |
| 00:57 | justin_smith | lein beanstalk, it uses lein ring, but also has its own stuff |
| 00:58 | sm0ke | just revert to 1.6 than ? dont tell me you areusing transducers? |
| 00:58 | justin_smith | sm0ke: I reverted |
| 00:58 | sm0ke | good :D |
| 00:59 | justin_smith | I was just griping about a) the process of narrowing down the root cause of my issue |
| 00:59 | justin_smith | (which wasted about 45 minutes of my precious time) |
| 00:59 | justin_smith | and |
| 00:59 | justin_smith | well, mainly just that |
| 01:28 | n_blownapart | hi anyone here advocate using lighttable to learn clojure? I know a little ruby but never quite learned how to properly use the repl gem pry. |
| 01:29 | justin_smith | n_blownapart: light table is not very actively developed right now |
| 01:29 | justin_smith | if you want an IDE I hear nothing but good things about cursive, which is a plugin for intellij idea |
| 01:30 | n_blownapart | justin_smith, really? ok, thanks, I heard clojure runs great on lighttable and its a good learning tool but I'm not very experienced with programming. |
| 01:30 | justin_smith | OK |
| 01:31 | justin_smith | light table is kind of cool, and don't feel like you shouldn't try it out |
| 01:31 | justin_smith | it just isn't very actively developed, and hasn't been for a while |
| 01:31 | n_blownapart | justin_smith, thanks kindly |
| 01:31 | justin_smith | also, especially when you are first learning, you can just use the repl from a terminal |
| 01:32 | justin_smith | with the basics of require with :reload and the command line editing keys you can get a lot done |
| 01:32 | justin_smith | n_blownapart: also, if you aren't yet, start with lein |
| 01:32 | justin_smith | it makes clojure much simpler |
| 01:32 | n_blownapart | lein? one sec. |
| 01:33 | justin_smith | n_blownapart: lein is our package manager and build tool of choice |
| 01:33 | justin_smith | it finds and downloads dependencies, and helps with the automation of building / running your app |
| 01:34 | justin_smith | n_blownapart: if you used the "gem" tool just about every time you used ruby (except maybe on production) that is kind of the role lein has with clojure for most of us |
| 01:35 | n_blownapart | I'm new to programming. I went through a ruby book and learning linux now. a confused noob still not grasping oop very well. |
| 01:35 | n_blownapart | justin_smith, ^ |
| 01:35 | justin_smith | OK |
| 01:36 | justin_smith | well that's helpful, because we don't do a whole lot of OOP |
| 01:36 | justin_smith | and the hard part for many newcomers to Clojure is expecting to do things the OO way and being confused |
| 01:36 | n_blownapart | good advice. thanks justin_smith I'll check out your suggestions. |
| 01:37 | justin_smith | n_blownapart: lein is very easy to install, it's just a single file and downloads everything else it needs |
| 01:37 | justin_smith | make sure you use 2.x and not 1.x though (your linux package manager may only have 1.x) |
| 01:37 | n_blownapart | cool I heard clojure was tough to learn . wish me luck ! justin_smith |
| 01:38 | justin_smith | n_blownapart: and don't be afraid to ask questions |
| 01:38 | n_blownapart | excellent thanks. |
| 01:38 | justin_smith | I think it's easier if you don't know other languages yet - the really hard parts about clojure are how it diverges with many of the mainstream assumptions |
| 01:39 | justin_smith | n_blownapart: also, there is a really good tutorial oriented for people who are new to programming |
| 01:39 | justin_smith | n_blownapart: http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome |
| 01:39 | n_blownapart | no prob. I have no assumptions formed. got it thanks justin_smith ! |
| 01:43 | justin_smith | n_blownapart: also, I just double checked, that tutorial starts with downloading lein and using it, so it's a great resource right off the bat |
| 03:08 | zhcpkl | Anyone have any experience with tess4j? |
| 03:18 | fairuz | Hi guys. How to list down all available functions from a library? |
| 03:30 | roelof_ | hello, why do I get this error message ( Map literal must contain an even number of forms) on this form : http://pastebin.com/HHDpfbL9 |
| 03:34 | roelof_ | hello, why do I get this error message ( Map literal must contain an even number of forms) on this form : http://pastebin.com/HHDpfbL9 |
| 03:35 | broquaint | roelof_: I don't think that form is causing that error, there are no map literals in it and it's valid code. |
| 03:35 | nhanH | That snippet of code by it self is fine, are you sure the error is not somewhere else? |
| 03:36 | roelof_ | broquaint: wierd, when I do lein midje I see this error appear |
| 03:36 | broquaint | Most odd. |
| 03:38 | roelof_ | broquaint: yep.that is why i asked here for help |
| 03:39 | broquaint | Why do you think it's that piece of code in particular? |
| 03:39 | roelof_ | broquaint: because that is the last what I have changed |
| 03:42 | broquaint | And if you drop that 'lein midje' works ok? |
| 03:43 | nhanH | Anyone here familiar with at-at? |
| 03:44 | roelof_ | broquaint: when I do the same in repl and do (do-a-thing 5) I get a answer and no error message |
| 03:45 | roelof_ | very wierd., I deleted the file and did a fresh download from github. Changed it to the script and everything works |
| 03:46 | mavbozo | roelof_: i presume you have done 'lein clean'? |
| 03:47 | roelof_ | mavbozo: nope, just deleted the file and did a git clone command |
| 03:49 | m00nlight_ | lein deploy will only deploy the jar not the standalone.jar? |
| 03:53 | jonathanj | i don't suppose there is Dash (the Mac app) integration with clojuredocs.org? :( |
| 03:54 | jonathanj | (that i don't have to generate manually) |
| 04:00 | mavbozo | m00nlight_: yes |
| 04:03 | m00nlight_ | mavbozo: So why the building jar report an error unbound var of function I write in a file and I required in another file? |
| 04:09 | mavbozo | m00nlight_: have u try 'lein clean' & 'lein compile' |
| 04:10 | m00nlight_ | mavbozo: Yes |
| 04:11 | foofoobar | Hi. Is there something like tour.golang.org for clojure? |
| 04:16 | mavbozo | m00nlight_: you try to build the jar with 'lein jar'? |
| 04:16 | m00nlight_ | lein uberjar |
| 04:34 | ered | foofoobar: did you look at http://www.tryclj.com/ |
| 04:34 | ered | ? |
| 04:35 | foofoobar | ered: yes, it’s very short :/ |
| 04:35 | ered | ah |
| 04:35 | ered | you're looking for something more in depth then? |
| 04:36 | foofoobar | ered: yes |
| 04:36 | ered | hmm |
| 04:36 | foofoobar | The golang tour showed a lot of the go language with examples etc. |
| 04:36 | ered | ah wow |
| 04:36 | ered | golang tour is a lot more in depth than i remember |
| 04:37 | ered | could have sworn tryclj is longer |
| 04:38 | ered | hmm |
| 04:38 | ered | trying to think of stuff, most of what i learned from initially was reading and following along in my own repl, not on a website |
| 04:39 | ered | i bet there's better stuff now though |
| 04:39 | ered | reading books* |
| 04:40 | ered | clojure wiki links to this article, but it's not interactive like golang tour is http://java.ociweb.com/mark/clojure/article.html |
| 04:41 | ered | worst case there you could read through that and install lein so you have your own repl to follow along |
| 04:41 | ered | :\ there should definitely be something better though |
| 04:41 | foofoobar | okay, thank you. |
| 04:41 | foofoobar | I have lein installed (and it’s up to date when running upgrade), but I get the following error when running lein repl: Exception in thread "main" java.lang.IllegalArgumentException: Cannot open <#<Socket Socket[addr=localhost/127.0.0.1,port=54060,localport=54080]>> as an OutputStream. (form-init4763471810287640460.clj:1) |
| 04:41 | ered | thankfully lein isn't too bad to install, i know go can be a little bit of a hassle to set up the environment |
| 04:42 | ered | ah okay |
| 04:42 | foofoobar | ah sorry, I was in a wrong directory. |
| 04:42 | ered | ah |
| 04:42 | foofoobar | Calling it in an empty directory it works |
| 04:42 | ered | yeah true |
| 04:43 | ered | or in a tiny project directory should be safe too |
| 04:43 | ered | the article i linked recommends doing it that way |
| 04:43 | foofoobar | ok |
| 04:43 | foofoobar | thanks |
| 04:45 | irctc | I am currently reading programming clojure 2nd edition and I enjoy it so far.. |
| 04:45 | ered | irctc: true, i mean i learned from a book too |
| 04:45 | ered | but books cost money :) |
| 04:45 | irctc | foofoobar, maybe try with this book |
| 04:45 | ered | (though a lot of books have online editions) |
| 04:45 | ered | (joy of clojure's site is broken atm) |
| 04:45 | ered | i really like joy of clojure |
| 04:46 | irctc | Ill check that out once I finish with this. |
| 04:46 | ered | oh, i originally learned from the o'reilly book |
| 04:46 | irctc | The only part I don't like about clojure books is that they tend to be really hefty |
| 04:46 | ered | yeah there's... a lot of material |
| 04:46 | ered | plus if you get into the rich hickey talks and all that |
| 04:47 | ered | i still have clojure in action on my backlog too |
| 04:47 | ered | bought it forever ago but still haven't gotten to reading it yet |
| 04:47 | irctc | There are other means to obtain electroci copies of the book, if you are really poor and thirsty |
| 04:47 | ered | :3 |
| 04:47 | ered | irctc: oh another one i was following was brave clojure |
| 04:47 | ered | that one had a section on setting up emacs which i thought was nice |
| 04:48 | irctc | I currently use vim, is there any reason to switch to emacs ? |
| 04:48 | irctc | I see lots of people using emacs for clojure |
| 04:48 | ered | irctc: personal preference mostly |
| 04:48 | ered | historically (like 3 years ago) vim was terrible for lisp development |
| 04:48 | ered | i know this from personal experience |
| 04:48 | ered | common lisp specifically |
| 04:49 | ered | that's what got me to switch to emacs in the first place |
| 04:49 | ered | i still use evil-mode though |
| 04:49 | ered | so vim keybinds and all that |
| 04:49 | ered | the login button on manning is an image so it's impossible to find :| |
| 04:50 | irctc | ah I see, well i use vim-clojure-static and fireplace and raibow_parentheses plugin and it works fine, |
| 04:50 | irctc | I can eval in the same buffer |
| 04:50 | ered | yeah i hear fireplace is nice now |
| 04:50 | ered | it used to be for common lisp, all there was was like slimv and it barely worked |
| 04:50 | ered | compared to slime |
| 04:50 | ered | in emacs |
| 04:51 | ered | okay finally redownloaded joy of clojure, remembered why i liked it |
| 04:51 | ered | it has chapters at the end on stuff like clojurescript and core.logic |
| 04:52 | irctc | there is also this enormous book called Clojure in small peices :) |
| 04:53 | irctc | I like the whole literate programming idea |
| 04:53 | ered | i know haskell people love it |
| 04:53 | irctc | Timothy Daly is the editor :) |
| 04:53 | ered | they have that whole .lhs format that's parsed completely different from .hs |
| 04:53 | ered | (literate haskell) |
| 04:54 | ered | there's the one doc library in clojure that really promotes literate too |
| 04:54 | ered | i think that one is marginalia? |
| 04:54 | ered | yeah |
| 04:54 | ered | https://fogus.github.io/marginalia/ |
| 04:54 | aztak | are we talking about books? I'm currently working through this one: https://leanpub.com/fp-oo -- recommended :) |
| 04:55 | irctc | cool, and clojurescriptone too i think |
| 04:55 | ered | neat, that book has an interesting approach |
| 04:55 | irctc | http://clojurescriptone.com/documentation.html |
| 04:55 | ered | not so useful to me personally but i can see where it comes in handy for coming from heavy OOP world |
| 04:56 | ered | hmm |
| 04:56 | ered | yeah i haven't done enough clojurescript to say for sure how i'd do it |
| 04:56 | ered | i'd like to get into it more though |
| 04:56 | irctc | i bought that one too, didn't like it much |
| 04:56 | ered | isn't clojurescriptone the one that's big on coupling the server and browser to the same framework? |
| 04:56 | irctc | too slow |
| 04:56 | ered | or is that pedestal? |
| 04:57 | ered | oh, this one is just docs |
| 04:57 | ered | nvm |
| 04:57 | ered | i am thinking of pedestal |
| 04:57 | ered | i will definitely look at this one |
| 04:58 | aztak | ered: the interesting thing with the fp-oo book is that you slowly (well) discover that OO is basically FP with implicit scopes :) In that way it's a nice companion to http://www.smashcompany.com/technology/object-oriented-programming-is-an-expensive-disaster-which-must-end |
| 04:59 | irctc | isn't pedestal just a web server for clojure..need to check |
| 04:59 | ered | aztak: neat |
| 04:59 | irctc | Well OO should not be used for storing data into object, it should be storing behaviours. |
| 05:00 | ered | my style in OO languages is as "functional" (read: defensive) as i can get away with these days |
| 05:01 | irctc | aztak, thanks for the link, I like reading about horrible OO concepts :) |
| 05:02 | aztak | irctc: it's a looooong read.. I confess that I didn't read every single word.. but there are some interesting quotes in there. |
| 05:27 | sveri | This link took me about 90 minutes to read, however, a text ending with a citation of joel spolsky is almost always worth it :D |
| 06:31 | Urza- | Hi, im looking for some information regarding the benefits of clojure (have to give a presentation about it on friday). I've been looking around the web, and have done a couple of tutorials, but the main "why would you actually want to use this language" still eludes me. Any golden tips? |
| 06:31 | SagiCZ1 | Urza-: how about some of the classic rich hickey presentations? |
| 06:32 | aztak | Urza-: functional programming in itself is an argument. Also the 'decomplecting' syntax of Clojure is a big win compared to other FP languages in the JVM imo. |
| 06:33 | SagiCZ1 | i would focus on the fact that clojure emphazises immutability and pure functions which lead to code that is easier to reason about, also it inherently reduces problems with concurrency |
| 06:34 | aztak | http://thecleancoder.blogspot.se/2010/08/why-clojure.html ? |
| 06:34 | aztak | (that was the first google hit for "why clojure?" ;)) |
| 06:34 | SagiCZ1 | also point out the advantages of JVM as a mature platform which is thouroughly tested, fast and reliable and the ability of using the whole java plethora of open source and/or commercial libraries |
| 06:34 | hyPiRion | Urza-: http://www.infoq.com/presentations/Simple-Made-Easy – great talk regardless of whether you adopt Clojure or not |
| 06:35 | hyPiRion | but Clojure is more or less built around this (simplicity) |
| 06:35 | Urza- | ah thanks for the info guys |
| 06:36 | Urza- | rick hickey presentations seem like a good starting point, shame i forgot my headphones today :( |
| 06:36 | SagiCZ1 | Urza-: you can go through the slides on infoq |
| 06:36 | Urza- | ah yeah |
| 06:39 | Urza- | SagoCZ1, why clojure over other FP languages? also what do you mean 'decompleting'? |
| 06:39 | Urza- | err aztak I mean |
| 06:40 | justin_smith | Urza-: the term is decomplecting |
| 06:40 | justin_smith | reducing complexity |
| 06:40 | kungi | Urza-: Mostly because clojure is "modern" and on the JVM. This alone makes it much more valuable for real world use. |
| 06:40 | aztak | justin_smith: (sorry - typo) |
| 06:41 | justin_smith | aztak: you got it right |
| 06:41 | Urza- | I see, most of the tutorials i've done so far have focussed on that aswell. Heres how you you would write program x in java (25 lines), and here it is in clojure (3 lines). |
| 06:41 | aztak | ah, sorry for complecting the discussion with noise :) I should have scrolled up and read what I wrote *grin* |
| 06:42 | mavbozo | Urza-: "Clojure: the JFDI language" can be a inspiration https://docs.google.com/presentation/d/15-7qFy6URdE7Owi2LitkQI_OHBu1AFWPUwHxgBc-O4E/edit?usp=sharing |
| 06:42 | justin_smith | aztak: though I would argue that syntax is only a trivial case of decomplecting in clojure, and it's more about the simle vs. easy philosophy of the lang semantics |
| 06:42 | Urza- | however the benefits do seem closely tied to the data structure (lists, vectors, maps) |
| 06:43 | justin_smith | *simple |
| 06:43 | mavbozo | Urza-: lots of materials, but in the end, depends on your audience |
| 06:44 | Urza- | audience consists of junior programmers |
| 06:44 | aztak | justin_smith: yeah, true. But to me a simple (and unambigious) syntax is a great selling-point compared to (for example) Scala. |
| 06:44 | SagiCZ1 | Urza-: yes, because data and its processing is what programming is about.. if you make data easy and efficient you solved many problems of today's languages |
| 06:45 | aztak | The language syntax is more complex in Java than in Clojure. But again - have a look at the Simple/Easy video.. |
| 06:45 | SagiCZ1 | aztak: the syntax of clojure has less concepts than any other language i know, but knowing and understanding core functions is not easy at all |
| 06:45 | justin_smith | Urza-: I think a big aspect of Clojure's niche is the overlap of default immutability / jvm platform / dynamic typing - those three combined are kind of unique |
| 06:45 | mavbozo | Urza-: what languages that most of those junior programmers familiar to? |
| 06:45 | justin_smith | Urza-: my employers would not have been able to use Clojure if it was not hosted on the jvm |
| 06:46 | Urza- | mostof them have recently completed their java certification (or are still working on it) |
| 06:46 | aztak | SagiCZ1: agreed. But at least you can focus on that without spending time on accidental complexity introduced by a big syntax :) |
| 06:46 | SagiCZ1 | aztak: agreed |
| 06:46 | hyPiRion | the Clojure syntax is to some extent more complex. You cannot distinguish function calls and control flow (macros) in Clojure, but you can in Java. |
| 06:47 | SagiCZ1 | hyPiRion: the question is do you need to distinguish them? |
| 06:48 | mavbozo | Urza-: Clojure by Java Programmers by Rich Hickey could be a great starting point http://www.youtube.com/watch?v=P76Vbsk_3J0 |
| 06:48 | hyPiRion | SagiCZ1: Imagine (foo t (bar x) (bar y)) – bar is a function with side effects (say println). How many times will we see a println in this case? |
| 06:49 | hyPiRion | I'm not saying it's worse than Java, but it's different. |
| 06:49 | mavbozo | Urza-: It's long, more than 2 hours, but because you know your audience's knowledge about java, you can adapt it |
| 06:49 | SagiCZ1 | hyPiRion: i see your point |
| 06:49 | Urza- | yeah good tip, thanks |
| 06:51 | justin_smith | hyPiRion: vastly outweighed by Foo.bar(baz) - how exactly has the internal state of baz been pushed around (not an issue in a majority of clojure code) |
| 06:52 | Bronsa | justin_smith: that has nothing to do with syntax though |
| 06:53 | hyPiRion | justin_smith: I agree, but that hasn't that much to do with syntax |
| 06:53 | justin_smith | hyPiRion: right, not a syntax issue! |
| 06:53 | justin_smith | a counterbalancing complexity is all |
| 06:53 | Bronsa | hyPiRion: we actually have a way to distinguish between macro calls & function calls -- indentation :) |
| 06:54 | justin_smith | Bronsa: don't forget syntax highlighting |
| 06:54 | justin_smith | haha |
| 06:54 | Bronsa | heh |
| 06:55 | Bronsa | I was actually quite serious btw, indentation plays a huge semantic role in lisps |
| 06:55 | justin_smith | Bronsa: it does, but like highlighting it's not enforced or evaluated by the compiler |
| 06:55 | Bronsa | right |
| 06:55 | SagiCZ1 | justin_smith: what seems complex to me in clojure are the exit points of functions, since there is no return keyword, it is very hard to see for me if i didnt forget to add correct exit path |
| 06:55 | hyPiRion | Bronsa: and binding forms. They are quite noticable |
| 06:56 | justin_smith | SagiCZ1: but that can be determined by the paren nesting - a macro aware editor program can determine it |
| 06:56 | kungi | justin_smith: Does Emacs differentiate between macros and functions when syntax highlighting? |
| 06:56 | SagiCZ1 | justin_smith: i guess i just have to train my eye to see it |
| 06:57 | justin_smith | kungi: no, but it should imho |
| 06:57 | mavbozo | btw, talking about indentation, any of you guys using lisp code beautifier |
| 06:57 | hyPiRion | kungi: for known macros, not self-defined ones |
| 06:57 | kungi | mavbozo: Is there such a thing |
| 06:57 | Bronsa | a tools.analyzer backed editor might be able to highlight differently the exit points of a functino |
| 06:57 | justin_smith | hyPiRion: oh, yeah, I guess they have a consistent color... |
| 06:58 | mavbozo | kungi: c family has code beautifier program |
| 06:58 | justin_smith | Bronsa: that would be awesome |
| 06:58 | kungi | mavbozo: I know but I haven't found one for clojure |
| 06:58 | justin_smith | Bronsa: for example highlighting each "tail" of a form would be great |
| 06:58 | kungi | I like the go philosophy in this case. "Use goformat or go ...." |
| 06:58 | mavbozo | kungi: agree |
| 06:59 | justin_smith | kungi: use the clojure-mode indentor for emacs? |
| 06:59 | kungi | justin_smith: I already do, but this does not solve the problem completely. |
| 06:59 | justin_smith | we have a clojure lib that does indenting / pretty printing for code though right? |
| 06:59 | justin_smith | kungi: agreed |
| 07:00 | kungi | justin_smith: I would like to have a tool where I can say: I want my lines to be 100 characters wide => Go and produce nice lisp indetation for me. |
| 07:00 | mavbozo | justin_smith: it doesnot fix trailing parenthesis last time i checked |
| 07:00 | kungi | Then run on all source files before saving them. |
| 07:01 | justin_smith | mavbozo: yeah, it's incomplete and not as bossy as a proper formatter |
| 07:01 | justin_smith | it doesn't override any line-break decisions |
| 07:01 | justin_smith | only indentation ones |
| 07:02 | kungi | A tool to enforce a company wide style would be great |
| 07:02 | mavbozo | kungi: c has formatter that let's you choose, say, kernighan-richie style and others that i forgot. |
| 07:03 | kungi | mavbozo: I know about indent which helped a lot |
| 07:03 | mavbozo | weird, for all those talks about letting machine do our job, but no formatters come from lisp programmers for ~50 years |
| 07:04 | dysfun | i don't think i agree. i find that a lot of my clojure has to be manuall reindented to read the easiest |
| 07:04 | justin_smith | ,(clojure.pprint/write '(let [a 0 b 1] (+ a b)) :dispatch clojure.pprint/code-dispatch) |
| 07:04 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint> |
| 07:04 | dysfun | there's some sort of subconscious logic balancing brevity with ease of reading |
| 07:04 | justin_smith | ,(require 'clojure.pprint) |
| 07:04 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 07:04 | justin_smith | blerg |
| 07:05 | justin_smith | mavbozo: won'twork with the bot, but check out what pprint/write does there |
| 07:06 | dysfun | speaking of the bot, where's the evaluator source code? i want to see how it's dealing with the securitymanager stuff |
| 07:06 | SagiCZ1 | why would clojure repl use both of my cores when i didnt design for parallelism anywhere, is it normal? |
| 07:07 | justin_smith | SagiCZ1: are you using lein repl? |
| 07:07 | justin_smith | or nrepl |
| 07:07 | SagiCZ1 | lein |
| 07:07 | dysfun | lein has to trampoline another instance |
| 07:07 | justin_smith | lein repl opens an nrepl process, and also a client of the process |
| 07:07 | Bronsa | justin_smith: the issue w/ using t.a for backing an editor is that to be accurate t.a needs to evaluate code |
| 07:08 | justin_smith | Bronsa: yeah that could get very messy |
| 07:08 | justin_smith | Bronsa: our kingdom for purity and an IO monad, huh |
| 07:08 | dysfun | justin_smith: haskell is --> that-a-way |
| 07:08 | Bronsa | justin_smith: I know that somebody in the cider team is trying to use it anyway, I've added some hooks that should allow for unevaluated code to be analysed but have no idea how that's working out for them |
| 07:09 | justin_smith | dysfun: just pointing out that feature addresses that issue |
| 07:09 | Bronsa | justin_smith: the need for evaluating code comes from macros actually |
| 07:09 | SagiCZ1 | justin_smith: what is a "client of the process" ? |
| 07:09 | Bronsa | it's a known "limitation" of lisps |
| 07:09 | mavbozo | justin_smith: i tried in in my emacs cider repl and it returns (let [a 0 b 1] (+ a b)) in one line |
| 07:09 | mavbozo | justin_smith: is that what you expect? |
| 07:10 | justin_smith | SagiCZ1: the thread that reads your input, and then sends it over the network to the one that does the eval part, and then reads the result over the network, and prints it |
| 07:10 | SagiCZ1 | justin_smith: thank you |
| 07:11 | justin_smith | mavbozo: no, that's less than ideal - but try a do form with multiple printlns |
| 07:11 | Bronsa | mavbozo: writing a lisp code formatter is not an easy task, because of how little syntax lisp has |
| 07:13 | dysfun | Bronsa: writing macros in other language is also not an easy task because of how much syntax they have :) |
| 07:15 | SagiCZ1 | what is the best way to store timestamps in clojure? just a string? or some sort of long? or java's Date object? i need it to be efficient and reasonably small |
| 07:16 | SagiCZ1 | maybe java.sql.Timestamp |
| 07:17 | daniel__ | SagiCZ1: to store them in a database? |
| 07:17 | daniel__ | then yes, java.sql.Timestamp |
| 07:17 | SagiCZ1 | daniel__: no, just to use them internally |
| 07:17 | dysfun | why not just use joda time? |
| 07:18 | SagiCZ1 | dysfun: i could, so there is no idiomatic clojure way? |
| 07:18 | dysfun | well, clj-time is an idiomatic clojure wrapper for joda time |
| 07:19 | SagiCZ1 | dysfun: sounds greay |
| 07:19 | daniel__ | i was about to say clj-time and to-sql-date |
| 07:19 | SagiCZ1 | *great |
| 07:19 | justin_smith | SagiCZ1: I usually just use numeric timestamps, but it really depends on what properties you need - I just need offsets between two of them and the numbers suffice for that |
| 07:19 | dysfun | the moment i hear someone talking about 'efficient and reasonably small' |
| 07:19 | dysfun | i get a little twitchy |
| 07:20 | justin_smith | ,(.getTime (java.util.Date.)) |
| 07:20 | clojurebot | 1414495153784 |
| 07:20 | dysfun | data is just data, it can be transformed into various shapes |
| 07:20 | dysfun | the 'efficiency' is in how you manipulate it |
| 07:20 | justin_smith | dysfun: cache-line and heap usage are things you know |
| 07:21 | dysfun | and have you profiled and discovered there's a problem? |
| 07:21 | mavbozo | SagiCZ1: designer of datomic chose java.util.Date. So, I think it suffices for lots of cases |
| 07:21 | clgv | :( |
| 07:21 | dysfun | and frankly if you're going to be optimising cache lines, why on earth are you programming clojure? |
| 07:22 | clgv | then better use clj-time - java.util.Date and the surrounding API is just broken |
| 07:22 | justin_smith | dysfun: not saying they are the only things, just saying they are things, and sometimes they matter |
| 07:22 | clgv | everything is a thing, right? :P |
| 07:23 | justin_smith | clgv: it's an idiom |
| 07:23 | perplexa | is anybody here familiar with clj-time? i'm trying to figure out the most elegant way to get a datetime object for the current hour, (t/now) gives me #<DateTime 2014-10-28T11:14:21.597Z>, i get #<DateTime 2014-10-28T11:00:00.000Z> with (t/date-time (t/year (t/now)) (t/month (t/now)) (t/day (t/now)) (t/hour (t/now))) but there must be a more elegant way, maybe (tc/from-long (* (long (/ (tc/to-long (t/now)) 3600000)) 3600000)) - that works, too. |
| 07:23 | dysfun | they do indeed. but perhaps something where you actually control memory allocation directly might be a better solution for dealing with cache lines |
| 07:23 | perplexa | but i don't know what would be prefered ;x |
| 07:25 | justin_smith | dysfun: and also, thinking about it a bit more, they are just criteria for putting your data into a specific shape, which does not contradict your point, in fact it re-enforces it in a way |
| 07:26 | justin_smith | dysfun: see for example disruptor - they use the jvm to get high performance cache line usage (by shoving everything into a ring buffer array) |
| 07:27 | justin_smith | s/everything/the part that matters/ |
| 07:29 | dysfun | i'm not saying it can't be done |
| 07:31 | dysfun | see, in perl, if i had a performance problem, i'd just go write a little bit of. Granted, I have to do that more often in perl because standard performance is not nearly as good as clojure. But when performance does become a problem in clojure, it's not nearly as easy to make it run faster |
| 07:31 | dysfun | "little bit of C" |
| 07:31 | justin_smith | well, we do have interop, and to re-use my prior example, disruptor outperforms any c++ alternative |
| 07:32 | justin_smith | (but that's because of good design, and a smart c++ project could replicate it and out do them, of course) |
| 07:34 | dysfun | is there a nice clojure wrapper for disruptor? |
| 07:34 | justin_smith | not that I know of |
| 07:34 | dysfun | pity. i was looking at immutant, but it all feels a bit "enterprise" |
| 07:34 | justin_smith | and it's a pretty niche tool (low latency message queue with a very opinionated architecture) |
| 07:34 | dysfun | the app i'm building, well i'd quite like to ship a single config file with it, not about 40 |
| 07:34 | dysfun | though embedding something like hornetmq would be awesome |
| 07:36 | dysfun | there's this enormous tendency of java apps to support every config option under the sun, i've noticed :( |
| 07:36 | dysfun | it all confuses my poor little brain |
| 07:36 | justin_smith | dysfun: yeah, disruptor is not inter-process, it's for in-process queues |
| 07:36 | dysfun | immutant embeds hornetmq if you let it |
| 07:37 | justin_smith | hugo duncan code is often good https://github.com/hugoduncan/hornetq-clj |
| 07:37 | dysfun | heh, i used ritz for the longest time |
| 07:37 | justin_smith | though the typo in the readme is a bad sign... |
| 07:38 | justin_smith | hotnetq |
| 07:38 | dysfun | yeah, i saw |
| 07:38 | dysfun | they're next to each other. easy to do |
| 07:38 | dysfun | and when i used to work with magento, i never did stop myself from typing 'magneto' and correcting it every tie |
| 07:39 | justin_smith | haha |
| 07:39 | perplexa | i think i've found the answer to my question :P |
| 07:39 | perplexa | (-> (t/now) (.withMinuteOfHour 0) (.withSecondOfMinute 0) (.withMillisOfSecond 0)) |
| 07:39 | justin_smith | someone should come out with a magento-killer named Xaiver |
| 07:39 | perplexa | unless that massive joda datetime has a better way ;x |
| 07:40 | justin_smith | dysfun: or perhaps proeffserX |
| 07:40 | dysfun | oh, right, i get you now. the intentional misspelling |
| 07:56 | SagiCZ1 | justin_smith: yeah i guess plain numbers wouldnt suffice here.. i need to parse various formats of dates from the source data, so i need clj-time.format anyways.. might use the core as well |
| 07:57 | mbac | so i have a tick function and a draw function. i want the tick function to update world state that the draw function reads. i guess the tick function also needs to watch an event stream whereas the draw function gets driven by a library timer. do i want to use vars to share the world-state and async to drive the tick function? |
| 07:57 | mbac | a stm approach seems like inefficient overkill for this, on cursory reading |
| 07:58 | justin_smith | mbac: one thing that has worked for me is to have a pure-data representation of world state, and a function that takes a world state, and a series of events since last update, and returns an updated state |
| 07:59 | justin_smith | mbac: the result of this calculation can then be fed to a "generate scene" function, the output of that offered to the drawing function |
| 07:59 | mbac | sounds elegant, but really i just want a buffer that one function running in a loop can update and the other function running in a loop can read |
| 08:00 | mbac | the ugly imperative thing is the way forward :P |
| 08:00 | justin_smith | mbac: "just" is tricky here, but you can put it in an atom if you like |
| 08:01 | mbac | i think atom is what i was looking for. it seems like i would need to alternate buffers to avoid making state-swaps so costly |
| 08:02 | SagiCZ1 | mbac: i was dealing with similar problems and with many tips from this channel i managed to avoid stm altogether so far.. i basically used what justin_smith just described |
| 08:06 | sveri | Hi, are there any advantages that liberator provides over compojure routes? |
| 08:06 | justin_smith | sveri: liberator simplifies a bunch of the patterns that you have with a REST service |
| 08:07 | justin_smith | sveri: it makes it easy to do a bunch of things that are all possible with compojure, just more tedious |
| 08:07 | sveri | justin_smith: so basically it's an abstraction? |
| 08:08 | justin_smith | (on the other hand, if what you are doing is not a RESt service, I think liberator would be a pain in the ass) |
| 08:08 | justin_smith | sveri: compojure is an abstraction too, they are different abstractions :) |
| 08:08 | justin_smith | sveri: I like how this page presents it http://clojure-liberator.github.io/liberator/tutorial/decision-graph.html |
| 08:09 | justin_smith | there's a "decision graph" on that page, showing the amount of logic liberator simplifies |
| 08:09 | sveri | Hm, I see |
| 08:09 | justin_smith | and REST services tend to have common decision trees, deriving from the spec |
| 08:10 | justin_smith | so why not have a layer that is formed around that |
| 08:10 | sveri | I guess, no one rly implements all that logic if he goes without liberator |
| 08:10 | justin_smith | all that said I haven't used liberator yet - but I did a lot of work on another clojure web platform and I like the design from what I have seen |
| 08:11 | justin_smith | sveri: but good code should have :) |
| 08:11 | sveri | justin_smith: that's the problem with good code, a lot of things should be in there, but, well, I guess you know yourself |
| 08:12 | justin_smith | sveri: I like the fact that it makes it simple to handle the error cases with the right response codes, and to describe the status you would present to a client |
| 08:13 | sveri | justin_smith: Hm, I guess I just give it a go and see how it works, thank you very much |
| 08:14 | justin_smith | sveri: also, unless I am mistaken liberator and compojure are orthogonal - you could plug a resource definition into any router you like, and the docs show using compojure because that is the router most people use |
| 08:15 | justin_smith | sveri: for the tool I worked on we ditched compojure because we used a db to describe routes (for internal workflow reasons) and compojure makes data-driven route generation more difficult than it should be |
| 08:16 | sveri | justin_smith: yea, I just saw the compojure example |
| 08:17 | justin_smith | sveri: oh wow, I am just looking at this for the first time and after years of doing webapps it's making me so happy: http://clojure-liberator.github.io/liberator/tutorial/debugging.html |
| 08:17 | dysfun | justin_smith: high praise indeed |
| 08:17 | justin_smith | sveri: it is an automatic and smart way to do the ad-hoc stuff I end up doing when debugging a site... |
| 08:18 | justin_smith | dysfun: just got done updating all routes on a client site to use textual slugs from the db rather than numeric ids... |
| 08:18 | justin_smith | I wish I had that debugging functionality they are showing here while doing that |
| 08:19 | justin_smith | dysfun: when I was a kid, at one point my dad jacked up our house to put a new foundation underneath it - it felt kind of like that :) |
| 08:20 | dysfun | justin_smith: so what *does* it gie you for all this fancy debugging? |
| 08:20 | sveri | justin_smith: yep, that looks rly awesome, one more reason to try it out |
| 08:20 | jeffterrell | Wow, that is nice. Just started using Liberator (after doing my last API by hand), and I'm so looking forward to all of this. |
| 08:20 | dysfun | just all this X-Liberator-Trace? |
| 08:20 | justin_smith | dysfun: and that flow chart |
| 08:21 | sveri | I mean, even developers like flow charts! |
| 08:21 | mavbozo | justin_smith: my sympathy for dealing with url schema without identifier for machines |
| 08:21 | justin_smith | dysfun: what I was doing with way too many logging calls |
| 08:21 | justin_smith | mavbozo: the customer is always right, right? |
| 08:21 | dysfun | nice to have that integrated, yeah |
| 08:22 | dysfun | might have to steal some of that |
| 08:23 | mavbozo | justin_smith: no, but we must live to fight another day |
| 08:24 | mavbozo | justin_smith: so, what do you use to make routes as compojure route replacement? |
| 08:25 | justin_smith | mavbozo: https://github.com/caribou/polaris it allows creating routes based on functions taking edn data |
| 08:26 | justin_smith | mavbozo: using db to govern the routes isn't always a smart choice, but we used it for a particular workflow to some success |
| 08:27 | justin_smith | mavbozo: and I can imagine other routes-as-data use cases |
| 08:28 | mavbozo | justin_smith: wow, I didn't know that polaris exists. makes me wonder why it does not exist in clojure-toolbox.com cause I use it first to find libraries. At first, I thought you use bidi https://github.com/juxt/bidi |
| 08:29 | mavbozo | it seems there are lots more routing libraries out there |
| 08:29 | pandeiro | liberator users: is there an easy way to marshall java.sql.Timestamp values in my tables into JSON? |
| 08:30 | justin_smith | mavbozo: polaris is part of caribou, which is listed there |
| 08:31 | mavbozo | justin_smith: i looked for libraries not frameworks :p |
| 08:32 | mavbozo | pandeiro: tables from sql databases? |
| 08:32 | justin_smith | mavbozo: there's a gray area :) we aimed to make each part of caribou independently repacible |
| 08:35 | pandeiro | mavbozo: yeah, doing it with this way: https://github.com/clojure-liberator/liberator/issues/71#issuecomment-54992507 |
| 08:35 | dysfun | interesting. that works similarly to something i've written (and not yet released) |
| 08:36 | dysfun | (polaris) |
| 08:36 | justin_smith | dysfun: that's a good sign I think :) |
| 08:36 | dysfun | if two different people come up with similar looking things, it's generally the case |
| 08:37 | justin_smith | dysfun: polaris was made by three of us, after a lot of arguing and speculating and heavy collective design work |
| 08:37 | justin_smith | (based on limitations in our previous ad-hoc solution) |
| 08:38 | dysfun | arguing is totally necessary |
| 08:39 | justin_smith | dysfun: indeed, it's good if you can keep things functional and avoid side effects on the arguments too :) |
| 08:40 | dysfun | well a lot of stuff i've been doing really has been making stuff declarative with data |
| 08:40 | dysfun | for various reasons |
| 08:40 | justin_smith | dysfun: yup, I was attempting a subtle pun |
| 08:40 | justin_smith | but yes |
| 08:41 | dysfun | yes, i chose to save you the embarrassment :) |
| 08:41 | justin_smith | haha |
| 08:41 | justin_smith | (side effects in our case being any damage to the professional or friend relationship of course) |
| 08:42 | mavbozo | justin_smith: hohoho |
| 08:42 | dysfun | yes. having just gone into business with two friends, this is going to be entertaining |
| 08:43 | dysfun | i can't count how many people have told me not to do this. but i also realised that there was basically no other way of getting the thing off the ground without sacrificing things i didn't want to sacrifice |
| 08:48 | mavbozo | pandeiro: i guess there's no easy way because in that link you gave there's a statement that says liberator use clojure.data.json but they do not parametrize data.json's :value-fn |
| 08:49 | pandeiro | mavbozo: yep that's the issue; extending the type is easy enough |
| 09:00 | justin_smith | pandeiro: you can extend clojure.data.json by extending a type to the JSONWriter protocol |
| 09:01 | justin_smith | https://github.com/clojure/data.json/blob/master/src/main/clojure/clojure/data/json.clj#L395 |
| 09:01 | justin_smith | see how it is done for the built in types, but you can do this from your own namespace for whichever types you like |
| 09:02 | justin_smith | (btw this is what I like about protocols) |
| 09:02 | pandeiro | justin_smith: yeah the link i posted does exactly that |
| 09:03 | pandeiro | i admit i never use protocols or types/records so it feels foreign to me |
| 09:03 | pandeiro | but this seems like the ideal use case |
| 09:03 | justin_smith | also, instead of (str date) you could use (bean date) |
| 09:03 | justin_smith | ,(bean (java.util.Date.)) |
| 09:03 | clojurebot | {:day 2, :date 28, :time 1414501376263, :month 9, :seconds 56, ...} |
| 09:03 | pandeiro | ha nice |
| 09:04 | justin_smith | that uses reflection though |
| 09:04 | justin_smith | cheaper to grab the fields you care about |
| 09:05 | justin_smith | pandeiro: I saw your question regarding an easy way, but did not see that link before |
| 09:05 | justin_smith | pandeiro: but to me what's in that link *does* look like an easy way :) |
| 09:05 | pandeiro | justin_smith: np thanks for the explanation |
| 09:05 | pandeiro | i hadn't found that link when i asked :) |
| 09:07 | justin_smith | pandeiro: it's all coming together, perhaps I should have some coffee |
| 09:08 | kungi | Why is Java so meh! :-( |
| 09:08 | kungi | I start to get a real aversion against this builder pattern. |
| 09:11 | borkdude | I'm doing java right now, and I feel so bored with ti |
| 09:11 | CookedGryphon | justin_smith: be careful with that bean, notice the month |
| 09:11 | kungi | borkdude: ti? |
| 09:11 | borkdude | it |
| 09:11 | kungi | borkdude: I thought ti was some kind of elaborate Java thingy :-) |
| 09:12 | borkdude | especially the style that every domain object should have its own class I find perverted |
| 09:12 | borkdude | only as a layer between the database, while not much is happining in these things |
| 09:15 | mavbozo | borkdude: I just did some PHP, well, most of my work is in PHP. Same here. |
| 09:15 | kungi | Why do i have to politely ask a config class to give me a ConfigBuilder which then builds the config which I can then give the Class I want to instantiate ... |
| 09:20 | dysfun | because someone wanted to write way more code than was necessary |
| 09:21 | kungi | dysfun: maybe he was payed by lines of code? |
| 09:21 | dysfun | i knew a manager that judged progress by numbers of +s in svn diffs per week |
| 09:22 | dysfun | if anything, i'd be inclined to judge it by net negative lines of code without breaking tests |
| 09:22 | kungi | dysfun: I know at least one person who would have shown him the middle finger and went away |
| 09:22 | dysfun | yeah, i did :) |
| 09:26 | kungi | I am currently trying to use metrics-clojure with riemann. I found a riemann reporter and some code showing how it's done. Now this riemann reporter is an AbstractPollingReporter and not the needed ScheduledReporter. |
| 09:38 | clgv | dysfun: haha, I encountered something similar where I had to implement a scheduler, it associated configuration object and an associated provider class. in clojure a similar solution just involved one function that needed to be passed as argument |
| 09:39 | joshhead | ,(= "(some code)" (str '(some code))) |
| 09:39 | clojurebot | true |
| 09:39 | joshhead | (= "(some code)" (str '(some code))) This is true in simple cases but not generally. Why? |
| 09:39 | joshhead | Tagged literals, printing issues? |
| 09:40 | stuartsierra | joshhead: Could be any number of things. |
| 09:40 | stuartsierra | whitespace, nonprintable objects, ... |
| 09:41 | joshhead | Whitespace is definitely going to cause a difference yeah. But I don't think that will matter for Datomic transaction fns (which is where I wished this would work) |
| 09:41 | stuartsierra | compiled functions aren't printable |
| 09:42 | joshhead | Hmm like datomic.api/q for example? |
| 09:43 | stuartsierra | Any function. Once it's compiled, it's going to print like #<datomic.api.q__4224907> |
| 09:45 | joshhead | Maybe I'm confused about the semantics of the single quote. If I quote a list that is a function call, won't I just get a symbol at the head of the list and not the function itself? |
| 09:45 | stuartsierra | yes you will |
| 09:46 | stuartsierra | get a symbol in a list, that is |
| 09:46 | joshhead | Hmm okay. If I quote something with a tagged literal, does the handler function get called before it gets quoted? |
| 09:47 | stuartsierra | Yes |
| 09:48 | stuartsierra | Tagged literals are a mess. Don't use them in code if you can avoid it. |
| 09:49 | joshhead | stuartsierra would you recommend avoiding #db/fn literals too? |
| 09:49 | stuartsierra | joshhead: yes, in code (.clj) files. |
| 09:49 | stuartsierra | Use d/function or whatever it's called. |
| 09:50 | joshhead | all right |
| 09:50 | joshhead | as for the code in tx fn's, I guess string literals are the way to go? Is there an emacs plugin or something to make paredit and indenting work inside strings? |
| 09:51 | stuartsierra | joshhead: Clojure code can be quoted |
| 09:51 | joshhead | oh d/function will just accept quoted code instead of a string? |
| 09:52 | joshhead | "a string or data containing the code of the body" I guess so |
| 09:52 | stuartsierra | yes, quoted string |
| 09:52 | stuartsierra | I mean quoted literal code |
| 09:52 | stuartsierra | single-quote |
| 09:53 | joshhead | OK cool that is way more convenient than editing strings. Thanks for the tips |
| 10:11 | agarman | how do I force (into-array ...) to use a base type? |
| 10:12 | clgv | agarman: what is a "base type"? |
| 10:12 | agarman | I'm trying (into-array [^Base a ^Base b]), but that doesn't seem to be working |
| 10:12 | agarman | clgv: in this case my base type is OtpErlangObject |
| 10:12 | agarman | clgv: sub-types are OtpErlangTuple & OtpErlangPid |
| 10:13 | clgv | agarman: why does that matter? for primitives it makes a difference for anything derived from object it doesnt |
| 10:13 | Bronsa | agarman: into-array has a 2 arg arity |
| 10:13 | Bronsa | (into-array Base [a b]) |
| 10:13 | Bronsa | ,(class (into-array Object ["foo"])) |
| 10:13 | clojurebot | [Ljava.lang.Object; |
| 10:13 | Bronsa | ,(class (into-array ["foo"])) |
| 10:13 | clojurebot | [Ljava.lang.String; |
| 10:13 | clgv | Bronsa: but does that really make any difference for objects? |
| 10:14 | agarman | Bronsa: ty ty |
| 10:14 | agarman | (inc Bronsa) |
| 10:14 | lazybot | ⇒ 64 |
| 10:14 | clgv | power of two :D |
| 10:15 | Bronsa | clgv: I guess if your array is heterogeneous you need that |
| 10:15 | borkdude | why is it that some developers are fluent in server side languages, but find CSS difficult and are bad at it? |
| 10:15 | Bronsa | ,(into-array ["foo" 1]) |
| 10:15 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: array element type mismatch> |
| 10:15 | stuartsierra | csgv: Java arrays are strongly-typed |
| 10:15 | Bronsa | ,(into-array Object ["foo" 1]) |
| 10:15 | clojurebot | #<Object[] [Ljava.lang.Object;@548719> |
| 10:16 | clgv | ,(into-array Object [[] "foo"]) |
| 10:16 | clojurebot | #<Object[] [Ljava.lang.Object;@c087be> |
| 10:17 | clgv | ,(into-array Object [[] {}]) |
| 10:17 | clojurebot | #<Object[] [Ljava.lang.Object;@1829097> |
| 10:17 | clgv | Bronsa: it seems arrays of strings are special, right? |
| 10:17 | Bronsa | no? |
| 10:17 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 10:17 | Bronsa | ,(into-array [1 1]) |
| 10:17 | clojurebot | #<Long[] [Ljava.lang.Long;@a19cc5> |
| 10:17 | Bronsa | ,(into-array [[] []]) |
| 10:17 | clojurebot | #<PersistentVector[] [Lclojure.lang.PersistentVector;@e44dd3> |
| 10:18 | Bronsa | clgv: if you don't give the array type to into-array, it will use the class of the first element |
| 10:18 | clgv | Bronsa: so why is it able to use object for the case with a vector and a hashmap? |
| 10:18 | Bronsa | clgv: because they are both Objects, while an hashmap is not a persistentvector |
| 10:18 | Bronsa | ,(into-array clojure.lang.IPersistentCollection [{} []]) |
| 10:18 | clojurebot | #<IPersistentCollection[] [Lclojure.lang.IPersistentCollection;@1dbbaab> |
| 10:19 | Bronsa | you just need a superclass |
| 10:19 | clgv | Bronsa: yeah, but if it looks only at the first element it should choose the vector class |
| 10:19 | Bronsa | clgv: but you explicitely gave Object as the array class |
| 10:20 | clgv | Bronsa: damn, copied the wrong one. sorry |
| 10:20 | clgv | ,(into-array [[] {}]) |
| 10:20 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: array element type mismatch> |
| 10:20 | clgv | ah, that's what I wanted to know |
| 10:21 | andrewhr | borkdude: I guess, because browsers are inconsistent? Not that languages are much better though |
| 11:16 | jonathanj | hrm, what's a concise way of taking the last item from a vector? |
| 11:17 | CookedGryphon | peek |
| 11:17 | CookedGryphon | and most importantly, never ever last |
| 11:17 | jonathanj | i was going to say, last seems kind of not good |
| 11:17 | jonathanj | is there not something that combines peek and pop? |
| 11:17 | borkdude | after my CSS question, I just discovered this podcast : http://dotnetrocks.com/default.aspx?showNum=1053 |
| 11:18 | Bronsa | jonathanj: no but you can use (juxt pop peek) |
| 11:19 | CookedGryphon | jonathanj: why would you want to combine peek and pop? Are you thinking of destructure-last sorts of things? |
| 11:20 | jonathanj | CookedGryphon: i want to take the last item from a vector, prepend ":" to it and put it back in the vector |
| 11:20 | Bronsa | jonathanj: you can use assoc then |
| 11:20 | clgv | jonathanj: peek, pop, conj |
| 11:20 | CookedGryphon | sounds more like you want to (update (count coll) (prepend :)) |
| 11:20 | clgv | or assoc ;) |
| 11:20 | Bronsa | (assoc [1 2 3] 2 4) |
| 11:20 | Bronsa | ,(assoc [1 2 3] 2 4) |
| 11:20 | clojurebot | [1 2 4] |
| 11:21 | clgv | get + assoc that is |
| 11:21 | CookedGryphon | oh wait, but only if you have clojure 1.7, otherwise you won't have update |
| 11:21 | Bronsa | ah yeah, update is definitely better in this case |
| 11:21 | Bronsa | (inc CookedGryphon) |
| 11:21 | lazybot | ⇒ 4 |
| 11:21 | jonathanj | hrm, too bad i can't specify a negative index |
| 11:21 | Bronsa | CookedGryphon: well update-in works just as fine |
| 11:22 | CookedGryphon | yep, only a little clunkier |
| 11:22 | Bronsa | ,(let [v [1 2 3]] (update-in v [(count v)] inc)) |
| 11:22 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 11:22 | Bronsa | :( |
| 11:22 | Bronsa | ,(let [v [1 2 3]] (update-in v [(dec (count v))] inc)) |
| 11:22 | clojurebot | [1 2 4] |
| 11:22 | jonathanj | (dec (count xs)) is kind of yuck |
| 11:23 | CookedGryphon | (defn update-last [coll f & args] (apply update-in coll [(dec (count coll))] f args)) |
| 11:24 | CookedGryphon | it's a pity nth doesn't support negative indices |
| 11:25 | CookedGryphon | it's something I really like in python |
| 11:25 | Bronsa | yeah |
| 11:27 | jonathanj | is there a destructuring syntax for the last item in a vector? |
| 11:27 | CookedGryphon | nope |
| 11:27 | CookedGryphon | it's been discussed a few times, but generally agreed would get a bit clunky and magical |
| 11:39 | the_danko | got a little destructuring question, fellows. motivated by something in brave clojure |
| 11:39 | the_danko | (defn my-first |
| 11:39 | the_danko | [[first-thing]] ; Notice that first-thing is within a vector |
| 11:39 | the_danko | first-thing) |
| 11:39 | the_danko | => (var user/my-first) |
| 11:39 | the_danko | (my-first #{"oven" "bike" "waraxe"}) |
| 11:39 | the_danko | UnsupportedOperationException nth not supported on this type: PersistentHashSet clojure.lang.RT.nthFrom (RT.java:857) |
| 11:40 | the_danko | so this destructuring doesn't work on a set it seems? |
| 11:41 | stuartsierra | the_danko: that's correct, sequential destructuring doesn't work on non-sequential things like sets. |
| 11:42 | the_danko | stuartsierra: thanks! |
| 11:42 | stuartsierra | You can call `seq` on the set to get a sequential thing, or just call `first` (which calls `seq`). |
| 11:42 | CookedGryphon | you could call seq on it to make it sequential, but you will get an unpredictable element out of it |
| 11:42 | clgv | is there something like (gen/subset (range 10)) in test.check? |
| 11:43 | clgv | ultimately, I need a vector of different elements in "random" order from a given list/set of values |
| 11:44 | puredanger | you can use gen/bind and gen/return to creators generators out of generators while applying arbitrary functions |
| 11:45 | stuartsierra | Or shuffle and take. |
| 11:45 | reiddraper | clgv: there is a 'shuffle' generator on test.check master, but not subset |
| 11:45 | clgv | reiddraper: subset would be quite handy as well, since it is pretty general |
| 11:45 | reiddraper | clgv: subset should be pretty simple, there's an explanation of writing one with Erlang quickcheck here: http://roberto-aloi.com/erlang/notes-on-erlang-quickcheck/ |
| 11:45 | CookedGryphon | or perhaps sample, which could work on vectors too |
| 11:45 | reiddraper | clgv: but I agree it'd be handy |
| 11:46 | dagda1_ | is this the right syntax for querySelector in clojurescript (.querySelector js/document "btn.btn-primary") |
| 11:50 | pandeiro | How can I deal with this error: #<CompilerException java.lang.IllegalStateException: var: #'ring.middleware.file-info/make-http-format is not public, compiling:(clj_webjars.clj:32:12)> |
| 11:50 | pandeiro | dagda1_: yes correct syntax |
| 12:06 | sdegutis | Question of the day http://stackoverflow.com/questions/7295016/clojure-method-missing |
| 12:09 | clgv | sdegutis: hehe |
| 12:09 | sdegutis | I was wondering it myself. |
| 12:09 | sdegutis | So I googled it and found the answer. |
| 12:09 | clgv | sdegutis: well defmulti comes quite close ;) |
| 12:10 | clgv | sdegutis: what did you find? |
| 12:10 | sdegutis | That in Clojure you use macros instead of method_missing. |
| 12:10 | sdegutis | Because Clojure doesn't have a concept of "objects" or "classes". |
| 12:11 | sdegutis | Except things like deftype. |
| 12:11 | sdegutis | And defmulti and defrecord. |
| 12:11 | clgv | how'd you use a macro with similar semantic? |
| 12:11 | sdegutis | I don't know yet :) |
| 12:11 | sdegutis | I'm still learning how to do Clojure well. |
| 12:11 | sdegutis | Idiomatic Clojure is an ever-evolving thing, a moving target. |
| 12:11 | technomancy | lifehack: doing clojure well does not involve method_missing functionality. |
| 12:12 | technomancy | s/clojure/programming/ |
| 12:12 | clgv | hehe |
| 12:12 | sdegutis | technomancy: you can't do that my sentence is immutable |
| 12:12 | sdegutis | Also this is good for learning http://stackoverflow.com/questions/11662084/why-does-clojure-distinguish-between-symbols-and-vars |
| 12:15 | sdegutis | Is dynamic function generation via macros a good practice? |
| 12:18 | noonian | sdegutis: i think it depends on the use case and how magical the macro is. defrecord defines new constructor fns and such for the record type defined for example |
| 12:18 | sdegutis | So then what is the rule of thumb for deciding when "it depends" applies to a given case? |
| 12:19 | kenrestivo | huh. i reach for function composition first... and it's been a few years since i needed to reach past that to macros, unless the library i'm dealing with is already macro-heavy and the only way around is to out-macro the macros. |
| 12:19 | arrdem | macros are more or less only for userland compilers and def generation that cannot be achieved by function composition or partial application |
| 12:19 | stuartsierra | sdegutis: Always use the fewest, and the simplest, tools available to solve any problem. |
| 12:20 | sdegutis | stuartsierra: But that excludes the use of macros, incorrect? |
| 12:20 | arrdem | sdegutis: no, it means that macros are appropriate if and only if they are the lowest power tool for the job |
| 12:20 | sdegutis | Oh. |
| 12:20 | arrdem | sdegutis: if they are not the lowest power tool, use a lower power one |
| 12:21 | sdegutis | I am anticipating using a lot more macros soon. That is why I wonder. |
| 12:21 | sdegutis | Right now we use almost no macros (except those that Compojure come with). |
| 12:21 | stuartsierra | In roughly *decreasing* order of simplicity: data structures, functions, protocols, multimethods, macros. |
| 12:21 | sdegutis | That's a good chart stuartsierra. You should tweet it. |
| 12:21 | stuartsierra | sdegutis: it's Stuart Halloway's hierarchy, more or less |
| 12:22 | sdegutis | stuartsierra: Whatever, if you don't, I will. And I'll take credit. |
| 12:22 | sdegutis | (I mean, assuming we don't definitively know who said it.) |
| 12:22 | stuartsierra | Sheesh, what is this, publication by blackmail? |
| 12:22 | sdegutis | I don't know what that means :) |
| 12:23 | stuartsierra | neither do I |
| 12:23 | sdegutis | Anyway, I'm starting to not like the explicitness of a typical Compojure app. |
| 12:23 | sdegutis | I'm starting to think we should do something more magical like "convention over configuration" and "automatic stuff". |
| 12:24 | sdegutis | Wow, I think every Heroku app is down. |
| 12:24 | noonian | lol |
| 12:24 | sdegutis | http://speclj.com/ http://joodoweb.com/ http://joyofclojure.com/ |
| 12:24 | technomancy | not the cool ones https://syme.herokuapp.com/ |
| 12:24 | sdegutis | Oh, ok. |
| 12:24 | kenrestivo | insider trading! |
| 12:24 | dbasch | this is up too http://dalai.herokuapp.com/ |
| 12:25 | wink | 3 with own domains vs 2 with subdomains |
| 12:25 | kenrestivo | ok, now is the time to hype up your not-down heroku app. |
| 12:25 | wink | point not proven |
| 12:25 | wink | everything is a dns problem until proven otherwise |
| 12:26 | noonian | sdegutis: Aaron Bedra's talk 'Ready Set Clojure!' might be interesting to you. He walks through writing a simple redis client lib that used macros to generate the fns. At the end he goes a little overboard so you might get a feel for why you might choose to use macros |
| 12:26 | sdegutis | http://joodoweb.herokuapp.com/ works |
| 12:26 | sdegutis | This is a good thing: http://joodoweb.herokuapp.com/tutorial/basics |
| 12:26 | wink | apparently I can mind read |
| 12:27 | sdegutis | noonian: Isn't he a Rubyist? |
| 12:27 | ered | joyofclojure is back |
| 12:27 | sdegutis | Not for me. http://joyofclojure.com/ |
| 12:28 | noonian | sdegutis: i don't know his background but it wouldn't suprise me; a lot of clojurists come from a ruby background. |
| 12:28 | sdegutis | Oh no! |
| 12:28 | sdegutis | Well I suppose that's fine. |
| 12:29 | sdegutis | I came from Python. |
| 12:29 | ered | maybe there's some weird routing thing going on |
| 12:29 | ered | joodo's site is down for me |
| 12:29 | sdegutis | I like the magical implicitness this library uses, very similar to Rails: http://joodoweb.herokuapp.com/tutorial/basics |
| 12:29 | ered | maybe it's heroku dns fail |
| 12:29 | technomancy | joy of clojure is on the ancient deprecated stack =\ |
| 12:29 | ered | i don't mind compojure personally because in other languages i like web frameworks like sinatra or flask |
| 12:29 | ered | ah |
| 12:30 | wink | the joy of legacy |
| 12:30 | sdegutis | technomancy: it's deprecated!? |
| 12:30 | sdegutis | technomancy: I was just going to buypurchas it. |
| 12:30 | wink | didn't he say "stack"? |
| 12:30 | wink | as in "on heroku"? |
| 12:30 | ered | the heroku stack, not the book |
| 12:30 | ered | if i read that right |
| 12:30 | sdegutis | I thought it was more about concepts than APIs, and thus is generally still applicable!? |
| 12:31 | sdegutis | Oh. |
| 12:31 | sdegutis | Yes, that makes the sense. |
| 12:31 | wink | sdegutis: and there should be a 2nd release yea |
| 12:31 | wink | of the book |
| 12:31 | wink | blargh :) |
| 12:31 | wink | s,release,edition,. hell. time to go home |
| 12:31 | sdegutis | Good night wink. |
| 12:31 | ered | if joyofclojure.com doesn't work for you try http://joyofclojure.herokuapp.com/ |
| 12:31 | sdegutis | ered: I heard there's going to be a second addition. |
| 12:32 | sdegutis | So I'll hold out. |
| 12:32 | ered | it should be out already |
| 12:32 | sdegutis | Oh. |
| 12:32 | sdegutis | With transducers? |
| 12:32 | ered | http://www.manning.com/fogus2/ |
| 12:32 | ered | this is the 2nd edition |
| 12:32 | wink | wtf @ naminh |
| 12:32 | technomancy | just emailed chouser offering to help |
| 12:33 | technomancy | since he doesn't hang out on freenode any more =( |
| 12:33 | ered | my copy doesn't mention transducers |
| 12:33 | wink | apparently only one guy named smith wrote one manning book. |
| 12:33 | ered | wink: maybe it's like the WGA where they make people change their name if there are collisions? :3 |
| 12:33 | sdegutis | Also, https://twitter.com/_sdegutis/status/527135858017984512 |
| 12:33 | wink | ered: hehe |
| 12:34 | ered | sdegutis: i forgot where i first read this, but i only ever use macros for 3 cases - with-foo, do-foo, create-foo |
| 12:34 | sdegutis | Hmm. |
| 12:34 | ered | where in the create-foo case it's to make like 5 related objects |
| 12:34 | noonian | didn't stuartsierra say that in this chat? |
| 12:34 | sdegutis | I want to start using Macros to design my routing system. |
| 12:35 | sdegutis | I think the "composability" style is not working out as greatly as first imagined. |
| 12:35 | kenrestivo | sdegutis: let no one's work evade your eyes, plagiarize, plagiarize |
| 12:35 | technomancy | don't start with macros =( |
| 12:35 | wink | a lot of people have an irrational hatred for macros |
| 12:35 | sdegutis | wink: I can see that already! |
| 12:35 | noonian | yeah, functions are awesome |
| 12:35 | technomancy | start with functions and tough it out for a while so you have a better appreciation for where the pain points are and how macros can help you |
| 12:35 | kenrestivo | wink: i didn't until i got stuck using a library that was macro heavy |
| 12:35 | wink | I'd love to see something like korma without a macro |
| 12:36 | sdegutis | The primary point of macros is to reduce the number of times you have to type (fn [] ...) |
| 12:36 | sdegutis | That's what I read. |
| 12:36 | wink | write and show me ;) |
| 12:36 | ered | imo you just know when you need a macro |
| 12:36 | ered | if that makes any sense |
| 12:36 | sdegutis | technomancy: I think I'm quite experienced enough with functions by now to know how to use Macros. |
| 12:36 | sdegutis | I've used Functions for quite a few years, even Clojure ones. |
| 12:36 | wink | hehe |
| 12:36 | kenrestivo | someone explained that macros were for creating custom syntax. i should tweet that |
| 12:36 | technomancy | sdegutis: you're not experienced in the domain of writing this library that doesn't exist yet though. |
| 12:36 | wink | sdegutis: wow, have you ever looked into methods? |
| 12:37 | technomancy | neither am I, believe it or not. |
| 12:37 | wink | kenrestivo: yeah, that's where I don't see a way arounf |
| 12:37 | noonian | i don't usually look to write a macro until i've written the code i want without macros and just want to clean up boilerplate and make it more concise |
| 12:37 | sdegutis | technomancy: How are you so confident? |
| 12:37 | sdegutis | wink: Yes, I used to use method_missing like a pro. |
| 12:38 | wink | sdegutis: wow, that's brave :) |
| 12:40 | technomancy | call it a hunch |
| 12:41 | sdegutis | We just learned about that on Word Girl. The word you're looking for is "intuition" |
| 12:45 | stompyj | I wonder how much money method_missing cost businesses |
| 12:45 | sdegutis | Not as much as null |
| 12:45 | stompyj | during its reign of terror, in the early rails days |
| 12:45 | sdegutis | Which Java still has! :) |
| 12:46 | sdegutis | Is there a language that doesn't have nil problems? |
| 12:46 | technomancy | lots |
| 12:46 | ered | rust |
| 12:46 | ered | haskell |
| 12:46 | ered | anything with an option type |
| 12:46 | technomancy | racket |
| 12:46 | technomancy | erlang |
| 12:46 | ered | i think F# has option types too |
| 12:46 | technomancy | java has option types |
| 12:46 | technomancy | that's not enough to fix the problem by a long shot |
| 12:46 | technomancy | you have to actually use them =) |
| 12:47 | ered | java's option types don't work well iirc |
| 12:47 | ered | at least the ones in guava |
| 12:47 | ered | they don't play nice with flatmap, so i'm told |
| 12:47 | technomancy | they come with the jdk now |
| 12:47 | ered | keep forgetting java 8 is a thing |
| 12:47 | ered | since iirc a huge chunk of the world is stuck on 6 |
| 12:48 | sdegutis | so which one? |
| 12:48 | sdegutis | i would love to use java |
| 12:48 | sdegutis | ive never written it before. it sounds like a lot of fun. |
| 12:49 | ered | schema has option types now too but iirc schema's validations are technically optional |
| 12:49 | ered | by which i mean only run when you tell them to run |
| 12:49 | ered | at least when i remember last using them |
| 12:49 | noonian | yeah i think you can annotate the fns so they always run or call them with validation turned on when you want it |
| 12:49 | ered | yeah that sounds right |
| 12:50 | ered | i want to say it has a performance hit is why it's not on by default |
| 12:50 | sdegutis | If you were to write a brand new web app today, what language would you choose? |
| 12:51 | technomancy | HTML |
| 12:51 | sdegutis | No I mean a dynamic website, the back-end. |
| 12:51 | sdegutis | Some examples are: Ruby, Python, Clojure. |
| 12:51 | technomancy | DHTML |
| 12:51 | the_danko | ha |
| 12:51 | sdegutis | No I mean ones that still exist. |
| 12:51 | technomancy | the D stands for Dynamic, you know |
| 12:51 | ered | CGI? :3 |
| 12:51 | the_danko | haha |
| 12:51 | sdegutis | CGI is an interface not a language. |
| 12:51 | noonian | i'm going to go out on a limb here and say a lot of people here might choose clojure |
| 12:51 | sdegutis | This isn't that hard, people. |
| 12:52 | the_danko | haha |
| 12:52 | sdegutis | noonian: you know what they say about assuming |
| 12:52 | sdegutis | "don't" |
| 12:52 | noonian | i heard it was the brother of all fuckups or something |
| 12:53 | sdegutis | wat |
| 12:53 | sdegutis | echo -n '' > quine && chmod +x quine && ./quine |
| 12:53 | lazybot | -n '' > quine && chmod +x quine && ./quine |
| 12:53 | nathan7 | that's not much of a quine, is it |
| 12:53 | noonian | anyway, a lot of dynamic sites these days are single page js apps talking to api servers |
| 12:53 | mavbozo | is HTML a programming language? |
| 12:53 | sdegutis | $ ./quine > quine && ./quine |
| 12:54 | mavbozo | is DHTML a programming language? |
| 12:54 | pandeiro | anyone know why a lib would produce this when I try to require it: #<CompilerException java.lang.IllegalStateException: var: #'ring.middleware.file-info/make-http-format is not public, compiling:(clj_webjars.clj:32:12)> |
| 12:55 | mavbozo | pandeiro: make-http-format is private? |
| 12:55 | the_danko | i am sorry to interrupt the HTML merriment. i do have a quick question if anyone is feeling game. |
| 12:55 | the_danko | (defn p [x] (println x)) |
| 12:55 | the_danko | => (var user/p) |
| 12:55 | the_danko | (map p [1 2 3]) |
| 12:55 | the_danko | => (1 2 3 nil nil nil) |
| 12:55 | the_danko | why is there a 1 2 3 in the return from the map? |
| 12:56 | the_danko | i thought that the function p there should always return nil |
| 12:56 | the_danko | why does the println go into the returned list? |
| 12:56 | pandeiro | mavbozo: it is private; but that doesn't matter when i run a repl from the lib's project; and i thought you could use fully qualified vars even if not public |
| 12:57 | ered | functions you use with map shouldn't have side effects |
| 12:57 | ered | also because println returns nil |
| 12:57 | ered | hmm |
| 12:57 | ered | hang on i'm confused now |
| 12:57 | bostonaholic | the_danko: which version of clojure? |
| 12:57 | noonian | the_danko: the 1 2 3 just happens to be printing as the repl is printing the return value so it looks like its in the seq returned |
| 12:58 | the_danko | (def r (map p [1 2 3]) |
| 12:58 | the_danko | ) |
| 12:58 | the_danko | => (var user/r) |
| 12:58 | the_danko | (println r) |
| 12:58 | the_danko | (1 |
| 12:58 | the_danko | 2 |
| 12:58 | the_danko | 3 |
| 12:58 | the_danko | nil nil nil |
| 12:58 | ered | what are you trying to do? print each element of the list on its own line? |
| 12:58 | the_danko | bostanaholic: 1.6 |
| 12:59 | the_danko | ered: i am just trying to learn what is happening here. i stumbled into this example and realized it means i don't know how map works. |
| 12:59 | the_danko | ered: ok, so i am trying to learn clojure and how map works is the answer. |
| 12:59 | ered | i'm not sure if this explains it entirely (someone else feel free to jump in), but since println has side effects you don't want to use map |
| 12:59 | ered | instead you should use doseq |
| 13:00 | noonian | the prints will happen when the map is realized, which at the repl is immediately since the repl is trying to print the return value |
| 13:01 | noonian | try (def res (map p [1 2 3])) then (do res nil) |
| 13:01 | noonian | you should just see 1 2 3 nil or something |
| 13:01 | the_danko | noonian: AHH! yes. (count r) is 3! |
| 13:02 | the_danko | noonian: thanks! |
| 13:02 | noonian | the_danko: np |
| 13:02 | pandeiro | why does accessing a fully namespaced private var cause an IllegalStateException when a project is required but not when running a repl within the project itself? |
| 13:06 | noonian | i just don't use private anymore :P |
| 13:10 | mavbozo | pandeiro: what do you mean by "when a project is required"? |
| 13:10 | bacon1989 | Does anyone know of some good defmacro exercises I could do to get more familiar with macros? |
| 13:10 | mavbozo | pandeiro: is it '(require '[ring.middleware.file-info :refer [make-http-format]])'? |
| 13:25 | stompyj | bacon1989: Why do you need exercises? You mean with the semantics of how they work? |
| 13:27 | stompyj | Does anyone here use kafka in clojure? If so, what client are you using? All of them seem a bit out-of-data |
| 13:27 | stompyj | date* |
| 13:36 | mindbender1 | Is there a function that evaluates `value expr` pairs and returns the first truthy value of expr? |
| 13:36 | justin_smith | mindbender1: cond? |
| 13:36 | noonian | mindbender1: cond |
| 13:37 | justin_smith | ,(cond false 0 nil 1 true 2) |
| 13:37 | clojurebot | 2 |
| 13:37 | noonian | ,(cond nil :falsey :truthy :truthy) |
| 13:37 | clojurebot | :truthy |
| 13:38 | mindbender1 | I want (cond :truthy :falsy :falsy :truthy) => :truthy |
| 13:38 | justin_smith | than reverse the args? |
| 13:38 | hyPiRion | 2[3~ |
| 13:38 | justin_smith | *then |
| 13:39 | Bronsa | mindbender1: that doesn't make much sense? what would the expr part be there for then? |
| 13:39 | justin_smith | mindbender1: wait - what's the logic there? |
| 13:39 | mindbender1 | I am trying to port a js code but it doesn;t translate easily into reversing. |
| 13:40 | sdegutis | ,CLOJURE_VERSION |
| 13:40 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: CLOJURE_VERSION in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 13:40 | mindbender1 | e.g.... |
| 13:40 | Bronsa | ,*clojure-version* |
| 13:40 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 13:40 | sdegutis | ,*clojure-version* |
| 13:40 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 13:40 | Bronsa | ,(clojure-version) |
| 13:40 | clojurebot | "1.7.0-master-SNAPSHOT" |
| 13:40 | sdegutis | ,(map identity) |
| 13:40 | clojurebot | #<core$map$fn__4341 clojure.core$map$fn__4341@1eb41e5> |
| 13:40 | sdegutis | WHOA LOOK A TRANSDUCER |
| 13:41 | noonian | mindbender1: everything in clojure is truthy except nil and false |
| 13:41 | sdegutis | mindbender1: Clojure is basically Ruby |
| 13:41 | Bronsa | sdegutis: what? |
| 13:42 | sdegutis | Bronsa: nil and false |
| 13:42 | sdegutis | (and nil false) |
| 13:42 | noonian | Sgeo: thems fightin words! |
| 13:42 | Bronsa | sdegutis: and that.. makes it "basically Ruby"? |
| 13:42 | sdegutis | noonian: whoa dude, calm down.. I'm over here |
| 13:42 | noonian | sdegutis: opps :P |
| 13:42 | sdegutis | You're on the roll today my friend. |
| 13:42 | noonian | can't type this morning |
| 13:43 | sdegutis | lol the guy who wrote Dash said I was "on the roll" and I was like "lol wat" |
| 13:43 | sdegutis | I had to break the news that it's "on a roll" and he took it rather well. |
| 13:44 | justin_smith | sdegutis: "on the roll" means like you are like part of the breakfast food conspiracy |
| 13:46 | noonian | im on the english muffin this morning |
| 13:47 | sdegutis | hi |
| 13:48 | mindbender1 | switch (e.keyCode) {case "esc": if true {return true;} else {return false} break; case "end": if true {return true;} else {return false;} break; } |
| 13:48 | mindbender1 | something like that in clojure? |
| 13:49 | mindbender1 | the return value of the expression determines if it continues |
| 13:50 | noonian | ,(let [val "foo"] (cond (= val "bar") "it was bar" (= val "foo") "it was foo" :else nil)) |
| 13:50 | clojurebot | "it was foo" |
| 13:51 | noonian | there are less general ways to do this also, case works if you know your switch values at compile time, and condp if you always use the same predicate |
| 13:51 | mindbender1 | noonian: sorry the exprs are different for each case |
| 13:52 | noonian | ,(let [val "foo"] (cond (#"ar" val) "it contains 'ar'" (= val "foo") "the val is foo")) |
| 13:52 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to clojure.lang.IFn> |
| 13:52 | noonian | ,(let [val "foo"] (cond (re-find #"ar" val) "it contains 'ar'" (= val "foo") "the val is foo")) |
| 13:52 | clojurebot | "the val is foo" |
| 13:52 | noonian | mindbender1: i think you can do everything you want with cond |
| 13:53 | justin_smith | mindbender1: that's just a case, where the right hand side of each case is an if |
| 13:53 | justin_smith | exactly like in js |
| 13:53 | justin_smith | (case "esc" (if true true false) "end" (if true true false)) |
| 13:53 | justin_smith | is literally that code |
| 13:53 | mindbender1 | justin_smith: yes and the right hand determines if it keeps going further. |
| 13:54 | justin_smith | err (case e.keyCode ...) |
| 13:54 | justin_smith | no, the breaks happen after the if |
| 13:54 | justin_smith | in that code |
| 13:54 | justin_smith | they apply regardless of branch |
| 13:56 | noonian | but you can have arbitrary code in the right hand side of cond, you might want to break it into helper functions to keep it readable though |
| 13:56 | justin_smith | mindbender1: it is true that we don't have a convenient version of case with fallthrough and early return |
| 13:56 | noonian | you can usually refactor that into the top level cond though |
| 13:56 | justin_smith | mindbender1: but you can replace return with a promise / deliver combo |
| 13:56 | justin_smith | and check the value of the promise at the end |
| 13:59 | justin_smith | ,(let [return (promise)] (if false (deliver return 0)) (if nil (deliver return 1)) (if true (deliver return 2)) @return) |
| 13:59 | clojurebot | 2 |
| 13:59 | justin_smith | not as pretty as case with fallthrough / return statements, but capable of the same semantics |
| 14:03 | justin_smith | ,(let [return (promise)] (if false (deliver return 0)) (if nil (deliver return 1)) (if true (deliver return 2)) (if :redundant (deliver return 3)) @return) ; for good measure |
| 14:03 | clojurebot | 2 |
| 14:25 | pandeiro | mavbozo: no, the lib in question is clj-webjars, which uses the aforementioned private fn |
| 14:25 | pandeiro | when i run a repl in the clj-webjars project, it compiles |
| 14:26 | pandeiro | when i require the lib from another project, it doesn't |
| 14:29 | justin_smith | pandeiro: do you need to be able to use that private var from another project? |
| 14:29 | pandeiro | justin_smith: no, a third party lib is using it |
| 14:29 | pandeiro | it seems that it works unless ring (owner of private fn) is also included in deps |
| 14:30 | justin_smith | oh - so both the definition and usage are both in 3rd party tools |
| 14:30 | justin_smith | weird |
| 14:30 | justin_smith | pandeiro: perhaps you get a different version of the code that makes the var private if you explicitly depend on ring? |
| 14:30 | pandeiro | justin_smith: just tested that |
| 14:31 | pandeiro | clj-webjars depends on ring 1.3.0; even using that version as a dep in my project causes clj-webjars to fail to compile |
| 14:31 | pandeiro | maybe i need exclusions |
| 14:32 | the_danko | yo fellas, got a little quandry. |
| 14:32 | the_danko | (defn my-partial |
| 14:32 | the_danko | [partialized-fn & args] |
| 14:32 | the_danko | (fn [& more-args] |
| 14:32 | the_danko | (apply partialized-fn (into args more-args)))) |
| 14:32 | the_danko | ok so i know that into works differently if the first argument is a list or a vector |
| 14:32 | justin_smith | the_danko: that's gonna screw up the arg order |
| 14:32 | the_danko | justin_smith: just what i am asking! |
| 14:32 | justin_smith | unless you want more-args reversed on the front of the args |
| 14:33 | justin_smith | & more-args makes a list, that puts things on the front with into |
| 14:33 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: more-args in this context |
| 14:33 | pandeiro | exclusions doesn't solve it... |
| 14:33 | pandeiro | lesson here is: don't use a lib that uses other lib's private stuff? |
| 14:33 | the_danko | justin_smith: so this is an example from brave clojure. ok so doesn't the type of the return from the into statement depend on the type of args? |
| 14:34 | the_danko | justin_smith: not more-args? |
| 14:34 | the_danko | justin_smith: my question is the same as your issue. i can't figure out how the order works. |
| 14:34 | justin_smith | the_danko: ahh, right |
| 14:34 | justin_smith | args will also be a list |
| 14:34 | justin_smith | the order will be each arg appended to the front of the initial |
| 14:34 | the_danko | justin_smith: so here args is a rest-param? correct? is that the correct term? |
| 14:35 | justin_smith | that is what into does with lists |
| 14:35 | justin_smith | the_danko: yes |
| 14:35 | justin_smith | ,(into '(0 1 2) 3 4 5) |
| 14:35 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core/into> |
| 14:35 | justin_smith | ,(into '(0 1 2) [3 4 5]) |
| 14:35 | clojurebot | (5 4 3 0 1 ...) |
| 14:36 | justin_smith | the_danko: & args creates a list, into adds each element from mor-args to the front of args |
| 14:37 | sdegutis | If you use a font that came with your OS in making an app icon for your closed-source commercial Clojure app, do you have to pay for licensing or something? |
| 14:37 | the_danko | justin_smith: sweet, so rest-params is always a list? |
| 14:37 | the_danko | justin_smith: i'll email mr brave clojure about this example |
| 14:37 | justin_smith | ,((fn [a & r] (class r)) (range)) |
| 14:37 | clojurebot | nil |
| 14:37 | justin_smith | hmm |
| 14:37 | llasram | justin_smith: `apply`? |
| 14:37 | justin_smith | ,((fn [a & r] (class r)) 1 2 3 4 5 6) |
| 14:37 | clojurebot | clojure.lang.ArraySeq |
| 14:38 | justin_smith | the_danko: technically an ArraySeq, but it has the same conj and into behavior as a list |
| 14:39 | llasram | ,(apply (class %&) (range)) |
| 14:39 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %& in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:39 | llasram | ,(apply #(class %&) (range)) |
| 14:39 | clojurebot | clojure.lang.ChunkedCons |
| 14:39 | llasram | It can be many things |
| 14:39 | justin_smith | llasram: good point |
| 14:39 | llasram | ,(apply #(class %&) [1 2 3]) |
| 14:39 | clojurebot | clojure.lang.PersistentVector$ChunkedSeq |
| 14:39 | justin_smith | llasram: many things that all have the conj behavior of list :) |
| 14:39 | llasram | fair |
| 14:40 | the_danko | justin_smith: llasrma: thanks guys. very helpful! |
| 14:47 | bacon1989 | stompyj: kinda late, but I just like exercises creating macros. I suppose I could just take any clojure.core macros and try and reimplement them my self |
| 14:47 | stompyj | bacon1989: fair enough |
| 14:47 | bacon1989 | i'm going to a point in my project where I think a few macros would simplify things creatly |
| 14:47 | mdrogalis | bacon1989: Go implement `let` :) |
| 14:48 | justin_smith | bacon1989: use macros to create a C style case statement with fallthrough if you don't invoke (break) |
| 14:48 | mdrogalis | Er, I think it was the destructuring code actually. It's pretty wild. |
| 14:48 | bacon1989 | sounds interesting |
| 14:49 | bacon1989 | yeah, idk about 'let', i'd assume that would be a monster |
| 14:49 | mdrogalis | It happens to be a function https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L4045 |
| 14:49 | justin_smith | let* is doing the binding part though :) |
| 14:49 | bacon1989 | yikes |
| 14:50 | justin_smith | ,(special-symbol? 'let*) |
| 14:50 | clojurebot | true |
| 14:58 | justin_smith | mindbender1: a more general approach to your translating case question, btw https://www.refheap.com/92434 |
| 15:00 | mindbender1 | justin_smith: I'm checking it. |
| 15:00 | justin_smith | mindbender1: just updated again, refresh |
| 15:01 | mindbender1 | okay |
| 15:01 | justin_smith | mindbender1: you could have any number of those (if-not (realized? return) ...) blocks for further logic that should be skipped if return has been delivered but run otherwise |
| 15:03 | justin_smith | mindbender1: of course there is always a clean idiomatic solution, but the possible advantage here is that the code would linearly follow the same sequence read top to bottom |
| 15:04 | amalloy | bacon1989: re trying to implement 'let: of course doing all the destructuring from scratch is a nightmare, but you don't have to: you can define let as a macro that expands into fn, which does the same destructuring |
| 15:05 | puredanger | there is of course the destructure function |
| 15:05 | amalloy | the reason it's a cool exercise is it reminds you that fn is all you really need; if you had fn and macros, you could build all of lisp |
| 15:06 | TimMc | And of course macros could be avoided by passing lambdas. |
| 15:06 | TimMc | *most macros, whoops |
| 15:06 | amalloy | puredanger: it's pretty rare to need that though, i'd think. i've only used it once |
| 15:06 | puredanger | yup |
| 15:07 | kanobe_ | ` |
| 15:07 | hiredman | I've been fiddling with a lisp interpreter in emacs lisp (to get csp style concurrency, to avoid callbacks, to write an nrepl client, to shave a yak) they are fun |
| 15:14 | amalloy | my one use of destructure, if anyone is curious, since it came up: https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L224-L253 |
| 15:14 | bodie_ | anyone have a preferred testing kit for clojurescript? I was looking at maybe jasmine-cljs or specljs |
| 15:14 | justin_smith | amalloy: very cool |
| 15:15 | bodie_ | specifically I'm working with Om so I don't know if there's something better or worse suited to that |
| 15:15 | bodie_ | I'm kinda new to cljs, so any thoughts are welcome :) |
| 15:15 | amalloy | justin_smith: version one only supported delaying symbol bindings; at some point i realized i can use destructure to reduce the destructuring cases to N symbol bindings |
| 15:16 | justin_smith | looks like a very useful macro |
| 15:17 | gfredericks | CSP == "Continuation Stassing Pyle" |
| 15:18 | hiredman | continuation stashing program maybe |
| 15:18 | bodie_ | continuation style passing |
| 15:18 | bodie_ | :P |
| 15:19 | hiredman | which is basically what it is, to "block" on putting to a channel you basically stash a continuation of the program in the channel, and when someone comes along and takes it restarts the continuation |
| 15:20 | hiredman | csp as in the core.async kind of stuff |
| 15:29 | bacon1989 | amalloy: thanks, maybe i'll try and reimplement let, and read through the oreilly macros section some more |
| 15:55 | sdegutis | What's the prevaling concurrent philosophy on templating engines in Clojure? |
| 15:55 | sdegutis | Is Hiccup still the champain? |
| 15:55 | justin_smith | concurrent philosophy? |
| 15:55 | sdegutis | I mean modern. |
| 15:56 | amalloy | contemporary, perhaps |
| 15:56 | sdegutis | Oh, contemporary. |
| 15:56 | sdegutis | Yes, thank you. |
| 15:56 | sdegutis | Does Hiccup still rain supreme? |
| 15:56 | xemdetia | rain=reign |
| 15:56 | justin_smith | I have never tried hiccup, but I doubt it tastes like champaign |
| 15:57 | jeffterrell | Though champagne has been known to incur hiccups. |
| 15:57 | cbp | i left the template score list in my other pants |
| 15:57 | sdegutis | What is this, criticism our? |
| 15:57 | justin_smith | sdegutis: in all seriousness, I use something mustache derived, because the frontend guys don't do clojure and they write the templates |
| 15:57 | borkdude | sdegutis who still renders html on the server? ;) |
| 15:58 | sdegutis | borkdude: where else do you render it, friend? |
| 15:58 | borkdude | sdegutis in javascript |
| 16:00 | sdegutis | borkdude: heresy sir! |
| 16:01 | sdegutis | That would be slow as heck. |
| 16:01 | sdegutis | or, wait.. is it? |
| 16:02 | borkdude | sdegutis this is what react apps do all the time |
| 16:02 | justin_smith | om is faster than the equivelent number of page loads you would need to do to see the same amount of page update |
| 16:02 | jeffterrell | I think it's not that bad actually. |
| 16:02 | arohner | om is way faster than an HTTP request |
| 16:03 | sdegutis | Hmm. |
| 16:03 | justin_smith | clearly sdegutis just isn't up to speed with web 2.0 |
| 16:03 | sdegutis | wait I thought we were at web 3.5 already |
| 16:03 | borkdude | 3.11 |
| 16:03 | justin_smith | sdegutis: some of us are |
| 16:03 | sdegutis | just not me? :( |
| 16:03 | jeffterrell | Single-page apps like trello.com have a really thin static DOM but a big fat javascript file, and the JS creates the page. Cf. http://blog.fogcreek.com/the-trello-tech-stack/ |
| 16:03 | borkdude | sdegutis even when not using react it can be feasible to render in js |
| 16:03 | sdegutis | look, whatever, my hands are fricken cold in this awesome autumn weather so thats that |
| 16:04 | danneu | using a websocket as an event bus with React was a lot cooler until i realized i need to pay Cloudflare $5000/mo for websocket ddos protection |
| 16:04 | justin_smith | sdegutis: if you were rendering more in-browser your notebook could be warming your hands! |
| 16:04 | sdegutis | but wait, dont you still need to make ajaj calls? |
| 16:04 | arohner | sdegutis: only for side-effects |
| 16:04 | sdegutis | doesnt that diminish the upside of rendering clientside? |
| 16:04 | sdegutis | well also for loading sensitive per-user data |
| 16:05 | arohner | GET logic is all client-side |
| 16:05 | sdegutis | or something |
| 16:05 | sdegutis | we're still using jquery :( |
| 16:05 | arohner | but the page still *renders* way faster |
| 16:05 | arohner | you put up a spinner, and you transfer less data |
| 16:05 | pandeiro | sdegutis: if you are dynamically building the initial HTML payload you can stick data in there; otherwise yes, 1 or more ajax calls to get your stuff |
| 16:06 | justin_smith | pandeiro: the downside there is for anything that needs to be updatable without a refresh, you can end up duplicating render logic, so even then you end up passing in some json and the javascript that renders it |
| 16:07 | borkdude | justin_smith not with react |
| 16:07 | pandeiro | justin_smith: (defn get-data [f] (if inlined-data (f inline-data) (get-ajax-data f))) |
| 16:07 | justin_smith | borkdude: pandeiro: yes - but you aren't using something like hiccup for this |
| 16:08 | pandeiro | justin_smith: what do you mean? why not? |
| 16:08 | borkdude | justin_smith you can have hiccup style templating in clojurescript |
| 16:08 | pandeiro | you could easily inline data into the server-side hiccup vectors if need be, right? |
| 16:08 | borkdude | reagent has it out of the box, om + sablono or non react: crate |
| 16:09 | justin_smith | pandeiro: borkdude: OK, I did not realize hiccup templating in cljs was a thing |
| 16:09 | borkdude | justin_smith light table uses crate for cljs templating |
| 16:10 | justin_smith | or perhaps even worse I knew this once because I actually used it and I totally forgot |
| 16:10 | justin_smith | cool |
| 16:10 | pandeiro | justin_smith: of course :) |
| 16:11 | sdegutis | borkdude, justin_smith, pandeiro: how do you handle clients that disabled JS? |
| 16:11 | borkdude | sdegutis haha, you don't |
| 16:11 | sdegutis | !? |
| 16:11 | pandeiro | the state of the art is doing the client as a SPA with React and rendering it on the server in Java 8's js env -- i know people have started doing that but i'm sure it's still thorny |
| 16:11 | clojurebot | CLABANGO! |
| 16:11 | justin_smith | sdegutis: this is clearly the downside of doing so much in the client |
| 16:11 | pandeiro | sdegutis: yeah that's a different app |
| 16:11 | sdegutis | lol clojurebot what the crap? |
| 16:12 | justin_smith | !? |
| 16:12 | borkdude | pandeiro I rendered a a component to a string yesterday in chrome and then just pasted the initial html in the static html file: works :) |
| 16:12 | clojurebot | ! is suddenly |
| 16:12 | pandeiro | borkdude: yeah that's something else though |
| 16:13 | borkdude | pandeiro what do you mean? |
| 16:13 | pandeiro | i'm talking about rendering the string in the jdk's js env, not a browser env |
| 16:13 | borkdude | pandeiro what does it matter, it's only for initial page load right? |
| 16:14 | sdegutis | true |
| 16:14 | pandeiro | borkdude: ah yeah sure, if it's not going to change |
| 16:14 | pandeiro | but here's what i was getting at (kinda): http://augustl.com/blog/2014/jdk8_react_rendering_on_server/ |
| 16:15 | borkdude | 'There's a glaring problem here. If you create React components that invokes 3rd party code, such as jQuery plugins, Bootstrap's JS components, and so on, you're in for trouble." |
| 16:15 | borkdude | a no go for me then |
| 16:15 | pandeiro | borkdude: yeah the issue is the missing browser stuff i imagine |
| 16:15 | pandeiro | document.getElementById |
| 16:15 | pandeiro | localStorage |
| 16:15 | pandeiro | that kind of stuff |
| 16:16 | sdegutis | What JS lib do you use for rendering HTML? |
| 16:16 | justin_smith | sdegutis: web 2.0 has been pretty terrible for accessibility, and the whole concept of browsing the web without js |
| 16:16 | sdegutis | I use Hiccup in Clojure right now. |
| 16:16 | sdegutis | justin_smith: ... go on |
| 16:16 | pandeiro | sdegutis: React is what everyone* is using |
| 16:18 | borkdude | sdegutis I know someone who uses crate for non react stuff, but reagent for everything else |
| 16:18 | sdegutis | Anyone here comfortable telling how much they make? I'm wondering how much someone who does a job like I do would get paid. |
| 16:18 | borkdude | sdegutis but you are just building a simple app without lots of interactivity server side hiccup is fine, just do what works for you |
| 16:19 | sdegutis | borkdude: I thought people were using Om for React within Cljs? |
| 16:19 | borkdude | sdegutis there are also lots of people using the more minimalistic reagent |
| 16:19 | pandeiro | there are at least three React wrappers in cljs |
| 16:19 | borkdude | om, reagent, quiescent in descending popularity |
| 16:20 | sdegutis | so om is the most popular but reagent is the best? |
| 16:20 | borkdude | sdegutis there is no best, it depends |
| 16:20 | borkdude | sdegutis om is very good at undo-able snapshottable apps |
| 16:20 | borkdude | sdegutis provided you aren't using local state |
| 16:21 | pandeiro | reagent's api is much more idiomatic for people used to clojure; om has a bunch of new vocabulary |
| 16:21 | borkdude | sdegutis you can have the same effect in reagent, but it may require more thinking, because reagent doesn't enforce using only one atom |
| 16:21 | sdegutis | oh |
| 16:21 | sdegutis | thanks everyone |
| 16:21 | borkdude | sdegutis that said, reagent is much simpler to learn, less verbose |
| 16:21 | joelt | and there's hoplon which isn't reactjs based. |
| 16:22 | sdegutis | so react is the foreseeable future? |
| 16:22 | borkdude | sdegutis react changes the clojurescript landscape quite a bit I think, if I'm right |
| 16:22 | borkdude | sdegutis pedestal app development stopped because of om |
| 16:23 | sdegutis | wonderful |
| 16:23 | joelt | reactjs is fundamentally more "correct" and funcitonal-like |
| 16:24 | joelt | while on this reactjs thread... has anyone written an HTML -> om/template (or reagent/template) converter? |
| 16:24 | sveri | borkdude: you have any sources for this? |
| 16:24 | borkdude | sveri on what? |
| 16:24 | borkdude | this requires context, just like in javascript :P |
| 16:24 | sveri | borkdude: that pedestal development stopped because of om |
| 16:24 | pandeiro | the pedestal thing was mentioned on the pdestal google group |
| 16:25 | borkdude | sveri yes, the pedestal-users mailing list |
| 16:25 | pandeiro | https://groups.google.com/forum/#!topic/pedestal-users/jODwmJUIUcg |
| 16:26 | mr_rm | does anyone know how to tell ring to add app server specific deployment descriptors to the WEB-INF folder? |
| 16:26 | justin_smith | mr_rm: put them in your :resource-path |
| 16:26 | sveri | borkdude: pandeiro thanks, didn't know that |
| 16:26 | justin_smith | mr_rm: wait, that may not be it... |
| 16:28 | mr_rm | justin_smith: yes i don't want it in WEB-INF/lib but rather at WEB-INF. alongside web.xml |
| 16:29 | mr_rm | i've pored over the docs but just not seeing it |
| 16:29 | ssa | hey does anyone know how to *not* require a library in a library i want to depend on |
| 16:29 | moquist | borkdude: thx for the om, reagent, quiescent list. I didn't know about the latter two and I'm glad I now do. |
| 16:29 | pandeiro | ssa: :exclusions |
| 16:29 | justin_smith | pandeiro: that excludes a dep version |
| 16:29 | ssa | e.g., A -> B -> C (where -> is a dependency) |
| 16:30 | justin_smith | pandeiro: that can't prevent a lib from requiring other clojure code |
| 16:30 | TimMc | sdegutis: Hiccup doesn't have anything to help you avoid JS injection attacks, by the way. |
| 16:30 | pandeiro | ah yeah of course |
| 16:30 | pandeiro | derp |
| 16:30 | ssa | justin_smith is right :) |
| 16:30 | justin_smith | ssa: provide another version of the namespace and exclude the dep? dunno, at that point why not rewrite the problematic lib |
| 16:30 | ssa | yeah, so i have the exclusion, but B will still bail because it tries to find C |
| 16:31 | justin_smith | ssa: you can create the ns such that it will be found rather than the other version, but this is a huge hack |
| 16:31 | pandeiro | TimMc: hiccup.util/escape-html ? |
| 16:31 | ssa | justin_smith: yeah, that's what i was trying to avoid :/ |
| 16:31 | mr_rm | i tried add :web-content pointing to a folder with WEB-INF under that but it doesn't get included either. so far the only way i found is to manually add the deployment descriptor :\ |
| 16:32 | technomancy | clojurebot: terminal quirks |are| a long, sad list of historical reasons why paredit's bindings don't work inside a terminal http://catern.com/posts/terminal_quirks.html |
| 16:32 | clojurebot | c'est bon! |
| 16:32 | ssa | the problematic require is not used anywhere in the lib, which is why i can exclude it |
| 16:32 | ohpauleez | This is where I'll jump in and just say - everyone should give Pedestal Service a look when building out web-based services |
| 16:33 | ssa | ok, was hoping there was an easy solution, but maybe not! |
| 16:33 | justin_smith | mr_rm: the ns in question is pretty small https://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/war.clj |
| 16:33 | justin_smith | mr_rm: any funcitonality you need should be in there - I couldn't see it though |
| 16:33 | justin_smith | mr_rm: but I only skimmed |
| 16:34 | justin_smith | ssa: sounds like some codomain to monkey patching |
| 16:34 | justin_smith | ssa: monkey-surgery? |
| 16:35 | mr_rm | justin_smith: yes, sadly, my quick skimming looks like it doesn't do anything extra for other files except "web.xml" |
| 16:35 | justin_smith | mr_rm: the ugly way to do it would be to just add the file manually |
| 16:35 | justin_smith | mr_rm: it's just a zip file after all |
| 16:35 | mr_rm | justin_smith: unfortunately i am forced to deploy this into weblogic and i need to make it prefer my local jars |
| 16:36 | TimMc | pandeiro: If you have to call a fn to escape output, you've already lost. |
| 16:36 | justin_smith | mr_rm: isn't this what uberwar is for? |
| 16:36 | mr_rm | justin_smith: right, i already know that works. it just seems like this is basic functionality and i thought i must be missing something |
| 16:36 | sdegutis | TimMc: oh no! |
| 16:36 | mr_rm | justin_smith: uberwar will put all the jar files there, that's true. however weblogic has an old version of the jar file in question and it before mine in teh classpath |
| 16:36 | justin_smith | mr_rm: weavejester tends to err on the side of leaving features out. On the plus side the things he leaves in tend to be really solid. |
| 16:37 | mr_rm | justin_smith: i have to tell weblogic to prefer my classes from WEB-INF/lib |
| 16:37 | pandeiro | TimMc: really? can't you predict where user-generated content might show up in your templates? |
| 16:37 | pandeiro | TimMc: your gripe is that should be the default? |
| 16:37 | justin_smith | mr_rm: maybe it calls for a jar-surgery lib (if we don't have such a thing already) |
| 16:37 | TimMc | pandeiro: Exactly. |
| 16:38 | technomancy | pandeiro: people make mistakes, unfortunately |
| 16:38 | pandeiro | sure makes sense |
| 16:38 | TimMc | It's unsafe by default, and we're not getting any reliability upgrades for people any time soon. |
| 16:38 | technomancy | better to have the mistake be embarassing than catastrophic |
| 16:38 | TimMc | technomancy: That's well-put -- & is not so bad if you compare it to the laternative. |
| 16:39 | pandeiro | was the reason against it performance-related or? |
| 16:39 | TimMc | Time to do my yearly check if my old employer's site still has that double-escape bug... |
| 16:39 | sdegutis | |
| 16:40 | Bronsa | technomancy: which keybindings are you talking about? I use emacs -nw and it all works fine |
| 16:40 | pandeiro | Bronsa: C-arrows |
| 16:41 | Bronsa | pandeiro: they work fine for me |
| 16:41 | pandeiro | Bronsa: xterm? |
| 16:41 | Bronsa | i might have unmapped them though |
| 16:41 | Bronsa | pandeiro: urxvt |
| 16:41 | sdegutis | pandeiro, Bronsa: st |
| 16:41 | TimMc | pandeiro: I would assume neglect or complacency. Almost every templating library has this proble, though. |
| 16:41 | technomancy | Bronsa: urxvt has a few nonstandard tricks that work locally but not inside tmux/ssh |
| 16:41 | Bronsa | sdegutis: what? |
| 16:42 | sdegutis | I thought we were randomly naming linux browsers. |
| 16:42 | Bronsa | technomancy: ah I don't use tmux/screen |
| 16:42 | sdegutis | I mean terminals. |
| 16:42 | technomancy | Bronsa: but yeah, it's not a limitation of terminal emulators per se, but rather the standards for representing keycodes across the wire. |
| 16:42 | Bronsa | gotcha |
| 16:43 | Bronsa | technomancy: isn't there an emacs something to edit files over ssh though? that could be a nice work-around :P |
| 16:43 | technomancy | Bronsa: you'd think ... =) |
| 16:43 | justin_smith | xterm / rxvt can also hand pointer events to ncurses clients that know how to use them. For obvious reasons this doesn't work over a multiplexer / the wire either |
| 16:43 | technomancy | but since Emacs isn't concurrent it's pretty brutal in the presence of network lag |
| 16:43 | pandeiro | yeah I still don't see the point of emacs' M-x term |
| 16:44 | justin_smith | Bronsa: yeah, tramp is awesome |
| 16:44 | mr_rm | justin_smith: actually i do have my own private jar surgery library |
| 16:44 | Bronsa | technomancy: .. yeah I notice that when my network drops & erc tries to reconnect |
| 16:44 | justin_smith | mr_rm: haha, nice |
| 16:44 | sdegutis | I will hold my tongue on the subject of Emacs. |
| 16:44 | mr_rm | justin_smith: guess i need that extra step :) |
| 16:44 | sdegutis | I will hold it so tightly it will bleed tears. |
| 16:44 | joobus | sdegutis: those are blood tears of love right? |
| 16:45 | llasram | sdegutis: Your tongue has tears for blood...? |
| 16:45 | Gurkenmaster | using emacs over LAN with a forwarded X server works surprisingly well |
| 16:45 | sdegutis | I see this channel has never been christened to the concept of hyperbole yet. |
| 16:46 | justin_smith | sdegutis: it's less the hyperbole and more the surreality of said hyperbolic image |
| 16:46 | sdegutis | justin_smith: whatever I don't know English things I just like mixing things that almost work together but don't quite |
| 16:47 | joobus | sdegutis: that's the dumbest thing I've ever heard... |
| 16:47 | sdegutis | justin_smith: most fun hobby. try it every day. |
| 16:47 | sdegutis | joobus: Sir, you seem to be irate, please do explain why? |
| 16:47 | technomancy | finely-tuned nonsense is an art form |
| 16:47 | technomancy | a la Pavement |
| 16:47 | sdegutis | I'm glad /someone/g agrees with me |
| 16:48 | sdegutis | Did you see I snuck a regular exp in the emphasis? |
| 16:48 | justin_smith | technomancy: sdegutis: the Residents have a song with the lyrics "smelly tongues look just like they feel", I like it because if you include the medium of the data it encompasses all five of the primary senses |
| 16:51 | sdegutis | joobus: the proper way to express such outspoken disagreement is to challenge someone to a duel with a glove slap |
| 16:51 | sdegutis | joobus: please note this for future posterity |
| 16:52 | TEttinger | get a glove, sdegutis |
| 16:52 | TEttinger | gloves can help you grab things, like oven mitts help grab hot things |
| 16:52 | TEttinger | fun fact for the day |
| 16:52 | sdegutis | Why isn't /trout working |
| 16:53 | sdegutis | TEttinger: i use driving gloves to grab the steering wheel |
| 16:53 | sdegutis | otherwise i would miss |
| 16:53 | justin_smith | sdegutis: most of the world has not caught up to the optional fish-slap extension to the irc protocol |
| 16:53 | sdegutis | tricky things those wheels are |
| 16:54 | sdegutis | this has been a fun afternoon, thank you all |
| 16:54 | justin_smith | sdegutis: even if implemented, the client may only dispense canned tuna at best |
| 16:54 | sdegutis | i count it as R&D |
| 16:54 | sdegutis | because i learned about react.js |
| 16:54 | sdegutis | and got good feedback on it |
| 16:54 | sdegutis | justin_smith: related to http 418 ? |
| 16:55 | justin_smith | sdegutis: no, that's just silly |
| 16:58 | sdegutis | i do a really good Bane voice |
| 17:10 | sdegutis | brainproxy: Hi :) |
| 17:23 | sdegutis | technomancy: you're a nerd, right? |
| 17:23 | SagiCZ1 | is there some way to write functiona arguments that the function would accept both [a b c d e] and [a b [c d e]] ? without overloading? some destructuring magic? |
| 17:24 | sdegutis | technomancy: I am thinking of getting a foot pedal with a usb hookup, and making it send a "ctrl" key while pressed |
| 17:24 | sdegutis | the firmware should be significantly simpler than https://github.com/sdegutis/atreus-firmware |
| 17:25 | technomancy | sdegutis: guilty as charged |
| 17:25 | technomancy | sdegutis: wait, are you on a macintosh computor? |
| 17:25 | sdegutis | yes |
| 17:25 | sdegutis | haha! i like how you slightly spelled computer differently for effect! |
| 17:25 | sdegutis | very well done |
| 17:25 | technomancy | macintoshes don't support having modifiers pressed on one device affecting keycodes from another device |
| 17:25 | technomancy | thank you |
| 17:25 | sdegutis | well im sure i can hack it in |
| 17:26 | sdegutis | im a programmer, see... |
| 17:26 | technomancy | a what? |
| 17:26 | sdegutis | that means i can create anything i can imagine |
| 17:26 | sdegutis | watch this |
| 17:26 | sdegutis | see? did you see that? |
| 17:27 | sdegutis | i created something just now |
| 17:27 | technomancy | inconceivable |
| 17:27 | sdegutis | oh contrare. |
| 17:28 | sdegutis | so im thinking all i have to do is find a big switch and a microcontroller |
| 17:28 | sdegutis | then ill be able to use emacs without being in pain all the time! :D |
| 17:29 | technomancy | you would probably have to modify your OS's keyboard driver or something |
| 17:29 | sdegutis | i have my ways sir |
| 17:29 | sdegutis | CGEventTapRef or something |
| 17:29 | sdegutis | ill map out every ";" at the hardware level to be Ctrl |
| 17:29 | sdegutis | (who uses ; anyway) |
| 17:30 | Bronsa | sdegutis: so you don't write comments |
| 17:30 | sdegutis | ok fine & |
| 17:30 | sdegutis | nobody uses & |
| 17:31 | Bronsa | no varargs? |
| 17:31 | sdegutis | oops i mean F16 |
| 17:31 | technomancy | just use the arrow keys |
| 17:31 | technomancy | those are lame |
| 17:31 | Bronsa | I use them :( |
| 17:31 | sdegutis | thanks everyone for your feedput |
| 17:35 | sdegutis | Oh wow, Sticky |
| 17:36 | sdegutis | Keys is great! |
| 17:39 | SagiCZ1 | any ideas for my question? |
| 17:39 | TimMc | technomancy: Wait, they don't? So those Kinesis foot pedals are useless on a Mac? |
| 17:40 | Bronsa | SagiCZ1: why no overloading? |
| 17:40 | Bronsa | SagiCZ1: you can do (fn x ([a [b c]] (x a b c)) ([a b c] (do-stuff))) |
| 17:42 | SagiCZ1 | Bronsa: its easy with overloading.. i was thinking about the '& more' thing.. if it can be used to recognize that im putting in a collection as 'more' and not wrap it in a list as usual |
| 17:42 | technomancy | TimMc: they plug into the keyboad itself; they're not independent deivces |
| 17:43 | TimMc | huh |
| 17:44 | sdegutis | I actually know how to write the Stick Keys feature on OS X. |
| 17:44 | sdegutis | Perhaps I should use that knowledge to build something similar but better, and sell it. |
| 17:47 | Bronsa | SagiCZ1: do you have a use case in mind or? |
| 17:54 | sdegutis | The website I write gets between 2k and 4k page views per day. I could probably use SQLite3 with WAL and get a significant performance improvement over using Datomic. |
| 17:55 | SagiCZ1 | Bronsa: my function foo uses & varargs so it is convinient when calling like this (foo 42 "name" :a :c :d ..) instead of (foo 42 "name" [:a :b :c ...]) note that there can be any number of arguments after "name".. another function -bar- uses foo internally and receives :a :b :c .. in the same way as foo but that wraps it in a list so i cant call (foo 42 "name" other-arguments) in this function.. maybe i should just use 'apply' and be d |
| 18:04 | the_danko | amigos, i have a little recur question if anyone is feeling bored |
| 18:04 | the_danko | (defn triang ([] (triang 0 1)) |
| 18:04 | the_danko | ([presum n] |
| 18:04 | the_danko | (let [newsum (+ presum n)] |
| 18:04 | the_danko | (cons newsum (lazy-seq (recur newsum (inc n)))) )) |
| 18:05 | the_danko | so this doesn't work |
| 18:05 | the_danko | i need to change the recur to triang |
| 18:05 | the_danko | it looks like it is trying to recur to the let [] |
| 18:05 | the_danko | and it gets an argument count mismatch |
| 18:06 | the_danko | so recur goes to the closest assignment block, i.e. []? |
| 18:06 | the_danko | maybe i have already answered my own question . . . |
| 18:06 | cfleming | the_danko: No, it won't go to the let |
| 18:07 | cfleming | the_danko: The problem is that recur has to be in tail position in your function, and you have it inside a lazy-seq |
| 18:07 | the_danko | CompilerException java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 2, compiling:(/private/var/folders/df/0z098cs56496gxlycxf2688c0000gn/T/form-init5659419162470671422.clj:4:29) |
| 18:07 | the_danko | cfleming: thanks! |
| 18:08 | cfleming | the_danko: I'm actually not sure why you're getting that particular error, but recur will definitely not work inside lazy-seq. |
| 18:08 | Bronsa | that confusing exception is because lazy-seq wraps the body in a fn |
| 18:08 | cfleming | Bronsa: Ah right, of course. |
| 18:09 | the_danko | Bronsa: cfleming: ahh. by the body, you mean? (recur newsum (inc n) |
| 18:09 | dbasch | the_danko: you’re not in tail position |
| 18:09 | Bronsa | ,(macroexpand-1 '(lazy-seq 1)) |
| 18:09 | clojurebot | (new clojure.lang.LazySeq (fn* [] 1)) |
| 18:09 | dbasch | you can’t recur from there |
| 18:09 | TimMc | Bronsa: Imagine how mcuh worse it would be if lazy-seq's wrapper fn took more than 0 args. |
| 18:10 | dbasch | oh, cfleming already said it |
| 18:10 | Bronsa | TimMc: yep. it would be useful if there was a primitive that acted like ^:once fn* but did not set a recur point |
| 18:10 | Bronsa | macros could use that & error messages could be better |
| 18:10 | TimMc | ^:passover |
| 18:11 | Bronsa | probably :once would be fine aswell |
| 18:11 | the_danko | Bronsa: cfleming: dbasch: thanks a lot! i'll be getting to macros soon and thus will understand then. |
| 18:11 | dbasch | the_danko: replace recur by triang and it should work |
| 18:11 | cfleming | So I'd like to write a macroexpander that takes a form and expands it step by step |
| 18:12 | TimMc | It would be nice if macros and specials highlighted differently from fns. |
| 18:12 | Bronsa | TimMc: yeah it doesn't really make any sense to recur a ^:once fn* |
| 18:12 | Bronsa | cfleming: sounds like tools.analyzer might help you there |
| 18:12 | TimMc | Bronsa: I guess it is only called once, for that matter. |
| 18:12 | cfleming | So each time I call it I pass it the results of the previous step, and it will recurse down into the form until it can perform a macroexpand-1, and then return the results of doing the expansion at that point. |
| 18:13 | Bronsa | , ((let [a (Long. 2)] (^:once fn* [] (when a (println a) (recur))))) |
| 18:13 | clojurebot | 2\n |
| 18:13 | cfleming | Bronsa: how would t.a help? |
| 18:13 | cfleming | It's a surprisingly tricky problem - neither Riddley nor tools.macro are well structured to do it. |
| 18:14 | Bronsa | cfleming: you want to macroexpand subforms too right? |
| 18:14 | cfleming | Bronsa: Right. I'm going to make an interactive macro stepper for Cursive. |
| 18:14 | TimMc | Bronsa: freeeaky |
| 18:15 | Bronsa | e.g. (let [a (when 1 2)]) => (let* [a (when 1 2)]) => (let* [a (if 1 (do 2))]) cfleming ? |
| 18:15 | Bronsa | TimMc: well that's the whole point of ^:once :P |
| 18:15 | cfleming | Bronsa: Exactly. |
| 18:16 | the_danko | cfleming: boom! go cursive! ha, i am sure i'll get and appreciate what you are suggesting soon. |
| 18:16 | Bronsa | cfleming: well t.a.jvm saves all the macroexpansion steps for every expr so if you don't mind macroexpanding everything even if you only need n steps, it should be trivial to use t.a.jvm for that |
| 18:17 | TimMc | Bronsa: I was vaguely aware that there was some kind of optimization, but I didn't realize it was that one. |
| 18:17 | cfleming | Performance isn't a huge concern, so I could potentially recurse down into the form like tools.macro and just try all the potential expansion points until I find one that actually expands. |
| 18:17 | Bronsa | TimMc: it basically tells the compiler "the body is only going to be evaluated once so you're free to clear all the closed over vals" |
| 18:18 | Bronsa | s/vals/locals |
| 18:19 | cfleming | Bronsa: Yeah, that would be fine - I was thinking about modifying tools.macro to do something like "perform n macroexpand-1's on this form" which would give me what I want. |
| 18:19 | cfleming | But the stateful iteration is quite ugly. |
| 18:19 | seangrove | "Languages with static typing that don't need validation (e.g. Om in ClojureScript), and production level compilers will be able to generate these objects inline instead of going through the validation step. This optimization will allow significant performance improvements in React. |
| 18:20 | cfleming | Bronsa: Any pointers as to where I should look in the t.a.jvm code? |
| 18:20 | seangrove | Om doesn't bring any static typing to the table, does it? Definitely the production-level compiler |
| 18:20 | cfleming | the_danko: Hopefully it'll help you understand macros better! |
| 18:20 | cfleming | the_danko: When it's done, that is. |
| 18:20 | seangrove | I wonder if they put the Om reference after the wrong point |
| 18:22 | Bronsa | cfleming: a bunch of pointers: - t.a's macroexpander is swappable, - if present in a node, :raw-forms holds the macroexpansion steps for the original :form of that node |
| 18:22 | Bronsa | cfleming: also passes.jvm.emit-form might help, it's an AST to clojure code compiler |
| 18:23 | Bronsa | cfleming: it's late-ish now but if you want I can write a quick POC of how that might work by tomorrow |
| 18:24 | cfleming | Bronsa: Ok thanks. It's morning here, I'll see what I can come up with today and if that would be helpful I'll drop you a mail. |
| 18:24 | cfleming | Bronsa: I suspect there's a fairly simple solution in there somewhere, I just haven't seen it yet. |
| 18:25 | cfleming | Bronsa: BTW while I have you, can you see any problems with this? https://github.com/cursiveclojure/cursive/issues/567 |
| 18:26 | Bronsa | cfleming: the same problems we have for eastwood: you can't attach metadata to everything |
| 18:26 | cfleming | Bronsa: I remember some discussion on the mailing list between Ambrose and Andy Fingerhut about this WRT Eastwood and Dynalint |
| 18:27 | cfleming | Bronsa: Right, I guess in the worst case your exclusion scope is too big |
| 18:27 | Bronsa | yeah |
| 18:27 | cfleming | Bronsa: Ok, I'll investigate that a bit more, thanks. |
| 18:28 | cfleming | Bronsa: Does Eastwood have anything like this now? I should use the same mechanism if so. |
| 18:28 | Bronsa | cfleming: no it's still an open question |
| 18:28 | cfleming | Bronsa: Ok, thanks. |
| 18:28 | Bronsa | cfleming: the only 100% accurate solution is to put the directive in a #_comment before the form to affect but that requires dropping the reader and using a parser |
| 18:29 | cfleming | Bronsa: Ok, I can do that trivially in Cursive, thankfully |
| 18:29 | cfleming | Bronsa: Since I'm working from source |
| 18:29 | Bronsa | cfleming: well if you can do that than I'd use #_{:suppress [whatever]} syntax |
| 18:31 | cfleming | Bronsa: Ok, I'll look into that - that's pretty trivial for me, although it's a little ugly too. I can probably fold it though. |
| 19:04 | mr_rm | justin_smith: remember that question i had about WEB-INF/weblogic.xml? |
| 19:04 | justin_smith | mr_rm: yeah |
| 19:05 | mr_rm | justin_smith: :war-resources-path is the answer. i'm such a retard at times :) |
| 19:05 | justin_smith | mr_rm: oh, I thought that was just the same as :resource-path when I looked at it |
| 19:05 | justin_smith | mr_rm: good to know! |
| 19:05 | justin_smith | wonder if it's worth a pr on the ring docs? |
| 19:05 | mr_rm | justin_smith: :resources-path puts stuff on the classpath so it will go under WEB-INF/classes |
| 19:07 | mwfogleman | justin_smith: I just found out that the bug I've been having is in core |
| 19:07 | mwfogleman | justin_smith: http://dev.clojure.org/jira/browse/CLJ-1413 |
| 19:07 | mr_rm | justin_smith: well it's in there toward the bottom. it would be nice if it mentioned something about app server specific descriptors to give you an easy search. really that's exactly what you need when you're deploying to JEE servers with a lot of special config |
| 19:08 | mr_rm | justin_smith: i'll try to tweak it a bit and offer a PR and see |
| 19:09 | justin_smith | mwfogleman: weird - so what exactly are the combination of factors that make this happen? |
| 19:11 | mwfogleman | justin_smith: in user.clj, trying to require a namespace with a defrecord |
| 19:12 | mwfogleman | it's nice to know i'm not the only one ;) |
| 19:12 | mwfogleman | i've felt kind of crazy, especially since fixing the hyphens didn't fix it. |
| 19:12 | justin_smith | yeah, the weirdest bugs are the worst when you have less experience with the language |
| 19:13 | justin_smith | because you have more reasons to second guess your own code |
| 19:13 | mwfogleman | exactly. |
| 19:14 | mwfogleman | what have you folks been working on in here? |
| 19:16 | justin_smith | mwfogleman: some features updates on a client web site |
| 19:16 | AeroNotix | mwfogleman: I just wrote a dispatcher/multiplexer thing for Amazon SQS messages |
| 19:16 | AeroNotix | and a payments system using auth.net |
| 19:16 | AeroNotix | also, messing with riemann |
| 19:16 | justin_smith | they wanted routing to be based on freeform strings from db data rather than unique identifiers (ugh) |
| 19:17 | justin_smith | AeroNotix: that sounds so much nicer than messing with routing to pages based on db data |
| 19:17 | AeroNotix | justin_smith: it does indeed |
| 19:17 | AeroNotix | :) |
| 19:18 | justin_smith | AeroNotix: has anyone written "core.async for multiple servers" yet? |
| 19:18 | mwfogleman | :D |
| 19:18 | AeroNotix | justin_smith: I think I saw that some where. "net chan" or something |
| 19:19 | AeroNotix | it's kind of broken doing that. It's cool that you get the same API n all. But network failures aren't part of the "api" for core.async |
| 19:19 | AeroNotix | Still, I'd probably use it for certain things |
| 19:19 | justin_smith | AeroNotix: my intuition is that once you have the layers on the network in place on both ends, not much else about core.async would have to change |
| 19:19 | AeroNotix | justin_smith: I saw a really nice library for using Zookeeper backed atoms |
| 19:20 | justin_smith | AeroNotix: it's cool as long as you never use watches |
| 19:20 | AeroNotix | justin_smith: why? |
| 19:20 | justin_smith | the watches in that lib are pathologically broken |
| 19:20 | justin_smith | AeroNotix: the watch api for zookeeper lets you set a watch, but that watch is removed immediately when it is triggered |
| 19:20 | AeroNotix | gotcha, noted. I was gonna use it a couple of months ago for a linearly scalable STUN design we ended up not needing |
| 19:20 | AeroNotix | justin_smith: ah yes, you need to reset the watch. I thought that was very odd. |
| 19:21 | justin_smith | AeroNotix: the semantics just do not agree with the clojure semantics, and so things you would expect to work just break |
| 19:21 | AeroNotix | justin_smith: yeah, the raw ZK library doesn't make you do that. |
| 19:21 | justin_smith | AeroNotix: and the watch resetting could miss changes that happen between trigger and reset ... |
| 19:21 | AeroNotix | yupp, it's messed up doing that. |
| 19:21 | justin_smith | AeroNotix: but if you just want a reference type over the network, without watches, yeah, that seems to work in my experience |
| 19:22 | AeroNotix | justin_smith: I didn't use it in anger. I was just prototyping a couple of designs for scalable STUN. |
| 19:22 | AeroNotix | Ended up looking at riak_core in the end. Then that project got shit-canned |
| 19:22 | AeroNotix | and never mind that STUN itself is ridiculously scalable even on a single node. |
| 19:23 | AeroNotix | I wouldn't mind a proper automation tool written in Clojure for AWS. |
| 19:23 | justin_smith | this stun? http://en.wikipedia.org/wiki/STUN |
| 19:23 | AeroNotix | justin_smith: yeah |
| 19:24 | justin_smith | AeroNotix: I have a multi-part-stream-upload patch for clj-aws-s3 that I mean to resubmit upstream as soon as I have time to clean it up |
| 19:24 | AeroNotix | nice! |
| 19:24 | AeroNotix | What i mean is some kind of declarative way to describe your infrastructure, ec2/elb/sec groups etc |
| 19:24 | justin_smith | AeroNotix: I was doing streaming transforms on file data, and decided putting it on my own disk was a waste |
| 19:24 | AeroNotix | but in EDN or something |
| 19:25 | justin_smith | AeroNotix: ahh, cool |
| 19:25 | AeroNotix | and the Clojure library would parse that and make the necessary changes |
| 19:25 | AeroNotix | justin_smith: yeah if you're in EC2 there's no point putting stuff on your own disk that you want |
| 19:25 | AeroNotix | that you want to keep* |
| 19:26 | justin_smith | yeah - the disk usage was just a temp file - but I was like "why can't I just use an inputstream and an outputstream with my algo in the middle?" so that's what I did, but multi-part-upload that doesn't use files was a pre-req for that |
| 19:27 | AeroNotix | Gotcha. I find the java streams stuff a of a crappy API |
| 19:27 | AeroNotix | You can do a lot of neat stuff with them though |
| 19:27 | AeroNotix | a of a? |
| 19:27 | AeroNotix | a bit of a* |
| 19:28 | seancorfield | org.clojure/java.jdbc 0.3.6 is coming soon - fixes JDBC-100, JDBC-101, JDBC-102 (all minor stuff) |
| 19:28 | justin_smith | AeroNotix: also, the existing multi-part-upload impl in clj-aws-s3 seems to be trying to do parallel upload of chunks - but I intend to benchmark that and prove that there is no situation where out of order chunked upload from a disk (ssd or hd) is faster than linear access |
| 19:28 | AeroNotix | from a disk you're probably right |
| 19:29 | justin_smith | AeroNotix: and the API demands a File |
| 19:29 | justin_smith | so it all seems a bit silly to me :) |
| 19:29 | AeroNotix | does seem it |
| 19:29 | justin_smith | I guess a File object could be on a ramdisk partition... |
| 19:30 | justin_smith | but that seems like a big iff |
| 19:30 | AeroNotix | I find those kind of optimizations are often just done for the sake of it |
| 19:30 | AeroNotix | "optimizations" |
| 19:30 | justin_smith | AeroNotix: ;; this is the part where we turn optimization up to 11 |
| 19:30 | AeroNotix | justin_smith: haha |
| 19:40 | Bronsa | cfleming: http://sprunge.us/JLdM?clj this is hackish and totally not efficient, but it should work fine as a POC |
| 19:43 | amalloy | Bronsa: i totally don't have the context to comment on the meat of that code, but it seems weird to me that you're writing (concat asts [a]) when asts appears to be a vector throughout the process, and you even do (conj asts a) to append to it in a different spot. is there something i'm missing there? |
| 19:45 | Bronsa | amalloy: no, I was doing something else before where asts was a seq rather than a vector and just left it that way |
| 19:46 | Bronsa | amalloy: there are other things worse than concat in that code, I just threw it together to see how it might work |
| 19:53 | amalloy | Bronsa: it's a feature i'd be happy to have, though, and it's great the analyzer is powerful enough you can throw it together in a short time. i don't really think i need a stepping macroexpansion debugger, because if i write a macro complex enough that i can't do it in my head i'm making a mistake, but i can see this being really useful for someone with less practice |
| 19:54 | Bronsa | amalloy: yeah it's definitely something I wish I had when I started learning lisps |
| 19:56 | Bronsa | cfleming: http://sprunge.us/KMgD?clj a less inefficient version |
| 19:59 | justin_smith | Bronsa: cfleming: now add colorization so that each expanded form gives its color highlighting to its expansion in the next form down, put it in a box, wrap it in a bow, and bob's your uncle |
| 20:01 | lazybot | why not try using MONADS!? |
| 20:02 | amalloy | Bronsa: i judged it but found it a reasonable enough approach to not criticize you |
| 20:03 | amalloy | lazybot: thanks, man. good idea |
| 20:03 | Bronsa | hah |
| 20:03 | Bronsa | (inc lazybot) |
| 20:03 | lazybot | ⇒ 31 |
| 20:03 | amalloy | Bronsa: i set that monad timebomb 24 hours ago and had forgotten all about it. i do enjoy surprising myself with these things |
| 20:05 | Bronsa | I just panicked thinking I found a t.a.j bug |
| 20:05 | Bronsa | turns out it's just a clojure bug so all is good |
| 20:05 | justin_smith | haha |
| 20:05 | amalloy | oh yeah? |
| 20:05 | justin_smith | "my platform is broken, that's so much better" |
| 20:05 | Bronsa | ,'^{:foo (println "foo")} [] |
| 20:06 | clojurebot | [] |
| 20:06 | Bronsa | it's CLJ-something in JIRA |
| 20:07 | amalloy | Bronsa: http://dev.clojure.org/jira/browse/CLJ-1137? http://dev.clojure.org/jira/browse/CLJ-1017? |
| 20:08 | amalloy | http://dev.clojure.org/jira/browse/CLJ-1235 |
| 20:08 | amalloy | http://dev.clojure.org/jira/browse/CLJ-1187, apparently |
| 20:08 | Bronsa | http://dev.clojure.org/jira/browse/CLJ-1093 actually |
| 20:09 | amalloy | yes, i just got there as well |
| 20:09 | Bronsa | what a wild ride |
| 20:09 | amalloy | following the chain of "x closed as dupe of Y by Bronsa" |
| 20:10 | Bronsa | amalloy: there are a number of similar but slightly different issues related how the compiler handles empty collections |
| 20:10 | amalloy | yes. and also how it handles reader meta applied to "runtime" objects vs "compile-time" objects |
| 20:10 | Bronsa | yup |
| 20:11 | amalloy | personally, i choose to never use ^ to apply metadata to objects i want my program to manipulate, and always use with-meta instead. then ^ is only for information i want to give the compiler, and i avoid such ambiguities |
| 20:11 | Bronsa | amalloy: yeah that's a more than reasonable stance |
| 20:12 | Bronsa | I've spent a good number of hours trying to come up with a fix for all the edge-cases in the Compiler, then gave up |
| 20:14 | amalloy | http://dev.clojure.org/jira/browse/CLJ-1017 is a weird one from bbloom |
| 20:15 | bbloom | amalloy: side effects in metadata expressions? psha, who needs those? |
| 20:18 | justin_smith | I decided to back up and read up about the general concept of metadata |
| 20:19 | justin_smith | it seems that an alternate name for metadata as we use it in clj is metacontent |
| 20:19 | bbloom | i've flip flopped on whether or not metadata is a good idea so many times, i've lost track |
| 20:19 | justin_smith | (the destinction being according to some that metadata is about data structures / architecture, and metacontent about a particular piece of data) |
| 20:19 | bbloom | which i guess means that it's motivated by genuine use cases, but not quite the right solution yet |
| 20:20 | justin_smith | bbloom: got any good articles or papers to recommend on the subject? |
| 20:20 | bbloom | not really, no |
| 20:20 | bbloom | if you find any, please share |
| 20:20 | justin_smith | it seems like there must be at least one good 40 page dissertation on metadata in compiler implementation out there somewhere |
| 20:20 | bbloom | there's lots of related stuff, like writing about the "identity crisis" with respect to proxy objects |
| 20:20 | bbloom | i'm sure there's something about alists in CL somewhere |
| 20:22 | justin_smith | http://www2.informatik.uni-freiburg.de/~keilr/papers/pos2013-proxy.pdf a paper about the proxy identity crisis in js |
| 20:25 | dbasch | that paper confuses schizophrenia and multiple identity disorder |
| 20:25 | bbloom | heh |
| 20:26 | dbasch | a schizophrenic proxy would be quite strange |
| 20:26 | dbasch | get array -> “here’s the rhinoceros you asked for” |
| 20:26 | justin_smith | dbasch: a proxy that fundamentally does not "get* the protocols it is expected to implement |
| 20:26 | AeroNotix | dbasch: lots of people confuse the two |
| 20:28 | justin_smith | dbasch: body without organs / code without datastructures (?) |
| 20:36 | amalloy | dbasch: a rhinoceros is just an array of cells anyway, right? |
| 20:37 | dbasch | amalloy: don’t tell that to the next rhinoceros you meet |
| 20:37 | dbasch | especially if it just came through a proxy over the wire |
| 20:39 | amalloy | dbasch: incidentally, you caused me to realize that rhinoceros is a word i have no idea how to spell. the first half is super-easy, but after that it seems i'm completely lost |
| 20:41 | havenwood | rhinawserous |
| 20:41 | justin_smith | cute rhino https://www.youtube.com/watch?v=0bL02GyIsKw |
| 20:42 | justin_smith | he tries to pronk like his friend |
| 20:42 | mlb- | I've got a list of functions and want to execute them all, is there something cleaner than: (->> fun-list (map (fn [f] (f))) dorun) ? |
| 20:43 | justin_smith | (dorun (map #(%) fun-list)) |
| 20:43 | justin_smith | actually (doseq [f fun-list] (f)) |
| 20:43 | justin_smith | that's the right way |
| 20:45 | gfredericks | I know why I like doseq better. it doesn't create a sequence for no reason. |
| 20:45 | dbasch | mlb-: curious about the situation in which you have to execute a bunch of functions with no arguments for side effects |
| 20:45 | justin_smith | yup |
| 20:45 | TimMc | &(format "lib-%04d" (rand-int 1e4)) |
| 20:45 | lazybot | ⇒ "lib-1113" |
| 20:46 | TimMc | thanks lazybot! |
| 20:46 | gfredericks | ^ great lib name |
| 20:46 | TimMc | Isn't it? |
| 20:46 | TimMc | You have the best naming scheme. |
| 20:47 | justin_smith | ,(format "lib-%s" (java.util.UUID/randomUUID)) |
| 20:47 | clojurebot | "lib-9ae7bac8-3c4f-4f4a-ade0-ef92fae94649" |
| 20:47 | gfredericks | too hard to remember |
| 20:47 | dbasch | thx-1138 |
| 20:47 | gfredericks | doesn't roll off the tongue |
| 20:47 | gfredericks | ~lib-1113 is the new hotness |
| 20:47 | clojurebot | In Ordnung |
| 20:47 | justin_smith | ,(format "lib-%s-jure" (java.util.UUID/randomUUID)) |
| 20:47 | clojurebot | "lib-9e5e6624-24aa-45e4-8ca8-d9b15fb4c211-jure" |
| 20:47 | gfredericks | lol |
| 20:48 | TimMc | ha! |
| 20:48 | gfredericks | (inc justin_smith) |
| 20:48 | lazybot | ⇒ 106 |
| 20:49 | TimMc | ,(apply str "lib-" (map char (repeatedly 15 #(rand-int 65536)))) |
| 20:49 | clojurebot | "lib-彖ổ?쑡몀⧹鯏䢭艠ᐑ뤪ﶒ枌" |
| 20:50 | gfredericks | oh dear |
| 20:50 | justin_smith | ,(lib-彖ổ?쑡몀⧹鯏䢭艠ᐑ뤪ﶒ枌.core/summon-old-one) |
| 20:50 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: lib-彖ổ?쑡몀⧹鯏䢭艠ᐑ뤪ﶒ枌.core> |
| 20:50 | TimMc | phew |
| 20:54 | justin_smith | TimMc: who am I kidding, it would be a java lib, and I would need to invoke the static AbstractOldOneSummonerFactory method, then use that to do the summoning with |
| 20:54 | justin_smith | after inheriting from the proper classes etc. |
| 20:54 | TimMc | NoneuclidianAbstractSingletonProxyFactoryBean would *definitely* be involved. |
| 20:55 | dbasch | someone should put together a lib to generate clojure library names, all you need is a list of obscure characters from tolkien books and similar |
| 20:55 | TimMc | .ia().ia().ia() |
| 20:55 | justin_smith | (inc TimMc) |
| 20:55 | lazybot | ⇒ 76 |
| 20:56 | TimMc | All those incantations probably use builder methods. |
| 20:58 | dbasch | CamelCaseNamesForJavaClassesWhoCantReadGoodAndWantToDoOtherStuffGoodTooFactory |
| 20:59 | nwolfe | Heh, www.classnamer.com gives you some good ones :D |
| 21:49 | arrdem | justin_smith: I would totally use a lob with an AbstractOldOneSummonerFactory. Not nearly enough tentacles and too much sanity in my code. |
| 21:49 | arrdem | s/lob/lib/g |
| 21:58 | justin_smith | arrdem: the prophecy will be revealed and then it shall come to pass, nyalothep will gaze upon our code and find it unwanting, and his indifference will delete it, and along with it all of the bugs it held. So it shall be. |
| 21:59 | arrdem | arrdem: http://www.marlborotech.com/Zalgo.html <- I would use the crap out of a Clojure lib that did that |
| 21:59 | justin_smith | arrdem: my buddy patchwork made one |
| 21:59 | arrdem | justin_smith: https://www.youtube.com/watch?v=FOHJUrcVdJk |
| 21:59 | arrdem | as long as we're off topic.. |
| 22:00 | arrdem | justin_smith: clojars or it didn't happen |
| 22:00 | justin_smith | arrdem: I introduced him to zalgo, and he was like, awesome, bam https://github.com/prismofeverything/zalgo |
| 22:00 | justin_smith | arrdem: clojars as requested https://clojars.org/zalgo |
| 22:01 | arrdem | justin_smith: whelp... I guess Grimoire 0.3.10 is totally gonna have a zalgo mode now |
| 22:07 | justin_smith | arrdem: the obvious extension is zalgoize-stacktrace |
| 22:08 | justin_smith | when you know clojure too well, and the stacktraces actually seem useful... |
| 22:08 | arrdem | AHAHAHA |
| 22:08 | justin_smith | for the nostalgia, of course |
| 22:08 | arrdem | that would be an amazing cider module |
| 22:08 | arrdem | hum... https://github.com/clojure-grimoire/grimoire/issues/131 |
| 22:08 | arrdem | should this be a feature? I'm torn |
| 22:08 | arrdem | I should fix it, since it's broken, but should it be a feature. |
| 22:09 | justin_smith | offline mode is a good thing |
| 22:09 | celwell | Hi, how can I test a coll to determine if all the value in it are equal? |
| 22:09 | gfredericks | (apply = coll) |
| 22:09 | celwell | ah, nice |
| 22:11 | celwell | works well thanks |
| 22:12 | arrdem | justin_smith: so my thing with the "offline" build is that you can totally clone Grimoire and run it locally |
| 22:12 | arrdem | justin_smith: as time goes by the static HTML build makes less and less sense |
| 22:12 | justin_smith | hmm |
| 22:21 | bbloom | how do people feel about crazy language embeddings, such as https://github.com/pallet/stevedore ? |
| 22:25 | justin_smith | bbloom: woah, how well does that actually work? |
| 22:26 | bbloom | justin_smith: *shrug* i guess that's the real question |
| 22:26 | bbloom | i've seen it in use, and my initial reaction is horror |
| 22:26 | justin_smith | yeah, can't say just from the source / unit tests, would have to use it |
| 22:26 | bbloom | but then i realize i'm writing cljs, which is basically the same idea |
| 22:26 | bbloom | so i'm not sure where the horror comes from |
| 22:26 | bbloom | or how to characterize it |
| 22:27 | justin_smith | bbloom: I think my default horror comes not from the act of translation (which we know can be done well) but from the known pitfalls of half-assed or overambitious translation |
| 22:28 | bbloom | justin_smith: yeah, i guess that's it |
| 22:28 | justin_smith | bbloom: but it takes real usage or significant examples to know which is going on (unless you are a language-converting tool master of some sort I guess) |
| 22:29 | bbloom | so i mention stevedore b/c i experienced it in a production system, but i'm actually more interested in other metaprogramming/cross-compiling tasks |
| 22:29 | justin_smith | bbloom: it's like - if my buddy says "I'm gonna jump out the second story window, it's gonna be awesome", I am going to try to stop him. But if a guy at the circus jumps from an equivalent height, I kind of figure he has that under control |
| 22:29 | bbloom | justin_smith: heh, intersting analogy |
| 22:30 | bbloom | i have a far-far-far from complete version of https://github.com/Constellation/escodegen in clojure built on my Fipp library |
| 22:30 | justin_smith | of course this means rich hickey = evel knevil |
| 22:31 | justin_smith | bbloom: fascinating - what's the use case for that, js as compiler backend? |
| 22:31 | bbloom | yeah |
| 22:32 | bbloom | i wanted to do a compile to js language and i wanted to implement the compiler in clojure |
| 22:32 | bbloom | but i was hand crafting ast nodes like {:head :if :test {...} :then {...} :else {....}} and it was just veeeerbose compared to (if a b c) |
| 22:33 | bbloom | so i started to create a ns of factory methods and an elaboration pass that basically macroexpands things like "foo" in to things like {:head :string :value "foo"} |
| 22:33 | bbloom | but after using this for 20 minutes, i immediatley got annoyed that the factory syntax didn't cover a corner case and i got annoyed |
| 22:34 | bbloom | hence my question about stevedore, etc |
| 22:34 | justin_smith | out of left field thought seeing those ast data structures: I wonder how useful it would be if a tool like t.a.jvm transformed clojure code into a "normalized" form where each symbol is replaced by a map with a :value key or something similar alongsize the metadata (with a reverse translation available as well, of course) |
| 22:35 | bbloom | i'm not sure i follow |
| 22:35 | justin_smith | folks were talking about how many bugs there are in metadata handling |
| 22:36 | justin_smith | so what about a transformation of clojure code into a form where the data is embedded in a map with the metadata |
| 22:36 | justin_smith | this would be inefficient |
| 22:36 | justin_smith | but it could also be a more explicit form where the metadata is now regular data, and is part of the printed representation etc. |
| 22:37 | justin_smith | it's total speculation, probably not actually useful |
| 22:38 | bbloom | the other frustrating thing is that these little embedded languages never compose |
| 22:38 | bbloom | stevedore is basically lexical macro |
| 22:39 | justin_smith | well, that two way transformation thing would fix that, but I guess you need to design in a very particular way for the translation to be reliably two-way |
| 22:40 | bbloom | how does a two way transformation help? |
| 22:40 | justin_smith | bbloom: it's composible when you bring it back into the common format |
| 22:40 | justin_smith | then transform to the other one, doing the operations native to that format? |
| 22:40 | justin_smith | maybe this is silly |
| 22:41 | bbloom | what's the common format? |
| 22:41 | justin_smith | bbloom: haha, I guess that's the problem, I assumed such a thing would just be natural |
| 22:41 | bbloom | when your meta language and your object language are both a lisp, things are easy |
| 22:42 | justin_smith | bbloom: having to do with what I was talking about above, a normalized, extremely explicit (if less efficient) form |
| 22:42 | justin_smith | bbloom: but then metadata (or in older lisps, plists) kind of complicate that |
| 22:43 | bbloom | i'm not worried about metadata at all |
| 22:43 | justin_smith | OK |
| 22:44 | bbloom | i'm worried about constructing syntax trees and emitting code with minimal mental gymnastics of an incomplete translation and an idiosyncratic factory library |
| 22:48 | justin_smith | yeah, I was going off on a tangent tying this to the previous discussion |
| 22:48 | justin_smith | bbloom: but I think the benefits of lispyness are undeniable for what you want to do |
| 22:49 | bbloom | well, unfortunately, js is not a lisp :-P |
| 22:49 | bbloom | i don't particularly want to invent a js-in-clojure embedding just to write a compiler for another language to that intermediate language |
| 22:50 | justin_smith | bbloom: if we had a single reliable two way transformation that did not lose information, between ecmascript and something lispy, other tools could leverage that |
| 22:50 | bbloom | but i guess that's what i really do have to do if i don't want to write ASTs long form |
| 22:50 | bbloom | the other idea is to go all the way on concrete syntax |
| 22:51 | bbloom | implement a js parser too, extend it with an unquote operation |
| 22:51 | bbloom | basically like js* in the cljs compiler, if you're familiar |
| 22:51 | justin_smith | right, I've seen it (though not looked at the impl) |
| 22:51 | justin_smith | bbloom: is that parsing js, or embedding js in the output? |
| 22:52 | bbloom | i'm saying you'd basically parse a variant of js that supports an operator like #{...clojure code here....} |
| 22:52 | bbloom | and then define a syntax-quote style operator that takes a string |
| 22:53 | justin_smith | ahh, so the inverse |
| 22:53 | bbloom | (let [x 2 y 3] (js "console.log(#{x} + #{y})")) would produce a JS AST with 2 and 3 substituted in |
| 22:53 | bbloom | you'd still need an "elaboration" pass that returns something like {:head :binop :left 2 .... in to something like {:head :binop :left {:head :number :value 2 ..... |
| 22:55 | justin_smith | that makes it almost sound like a kind of templating or string interpolation |
| 22:55 | cfleming | justin_smith: (re: macroexpansion a couple of hours ago) that's my plan - single step macro expansion, and highlight what's changed in each one. |
| 22:55 | bbloom | syntax-quote is templating :-P |
| 22:56 | cfleming | justin_smith: The bow would be a nice touch though. |
| 22:56 | bbloom | but yeah, the idea is to basically make js-syntax-quote by adding interpolation to a js grammar |
| 22:56 | justin_smith | cfleming: very nice |
| 23:00 | bbloom | justin_smith: i think i realize what my big objection to something like stevedore is though |
| 23:00 | justin_smith | do tell |
| 23:00 | bbloom | speaking concretely, stevedore tries to make shell look like clojure |
| 23:00 | bbloom | mimicking another language is the problem |
| 23:00 | bbloom | not translation |
| 23:00 | bbloom | b/c when the embedded object language mimicks the metalanguage, you get in to an uncanny valley sort of situtation |
| 23:01 | bbloom | where it doesn't look or feel right |
| 23:01 | bbloom | the closer it gets w/o being the metalanguage, the stranger it seems |
| 23:01 | justin_smith | bbloom: another way to put it maybe is syntactic translation (trivial) vs. semantic (nearly impossible to get right) |
| 23:01 | bbloom | but stevedore doesn't try to put clojure semantics in to your shell |
| 23:02 | bbloom | other than some superficial stuff like namespacing locals or whatever |
| 23:02 | bbloom | it is mostly a syntactic translation |
| 23:02 | justin_smith | bbloom: I would assume it at least gets the three parts of an if right, etc. |
| 23:02 | justin_smith | but that's the semantics that overlaps |
| 23:03 | bbloom | cljs is a major semantic AND syntactic shift from js, but it's not so awkward b/c cljs looks like clj and works like clj, rather than looking sorta like clj and working sorta like js |
| 23:03 | bbloom | that's the problem w/ stevedore and many other embeddings, i think |
| 23:03 | bbloom | looking sorta like the meta language and working mostly like the object language |
| 23:03 | justin_smith | bbloom: that uncanny valley thing is also why I find trailing parens in a lisp / sticking ones in a non-lisp so annoying - I can read faster when there are no ambiguous clues about which language type I am looking at |
| 23:03 | bbloom | hm |
| 23:04 | bbloom | coffeescript for example looks like something totally different and works exactly like js |
| 23:04 | bbloom | no uncanny valley |
| 23:04 | justin_smith | right |
| 23:05 | bbloom | amusingly, this exists: https://github.com/Gozala/wisp |
| 23:07 | sx | Are there popular lisps besides clojurescript which compile to javascript? |
| 23:07 | bbloom | sx: i don't know how popular it is, but there's http://common-lisp.net/project/parenscript/ |
| 23:07 | sx | bbloom: thx checking it out |
| 23:08 | justin_smith | sx: I am sure someone has made a scheme -> js compiler. I mean it has to have happened. |
| 23:08 | sx | justin_smith: true. i guess I said "popular" since the underlying languages undergo changes and it is not always easy for a compiler to keep up |
| 23:08 | justin_smith | :) |
| 23:09 | sx | it looks like parenscript latest release is more than two years old. so unlikely to support new ecmascript features |
| 23:09 | justin_smith | sx: scheme has the advantage of having standards, on that front, and tools that verify compliance to said standards |
| 23:10 | justin_smith | ahh, features in the target language |
| 23:10 | justin_smith | that's different, yeah |
| 23:10 | sx | yeah in this case |
| 23:11 | justin_smith | so, this exists https://github.com/jashkenas/coffeescript/wiki/list-of-languages-that-compile-to-js |
| 23:11 | sx | justin_smith: sweet. thats what i was just about to google for.. |
| 23:12 | justin_smith | clojure-like, scheme-like, other are the lisp subheadings :) |
| 23:12 | sx | yes a lot more than I expected. good stuff |
| 23:13 | bbloom | justin_smith: i probably should have checked that list, there's likely something i could use :-) |
| 23:13 | justin_smith | sx: it would be nice to have a version of that page annotated with project activity levels, adoption rates |
| 23:14 | TEttinger | Ki looked good, justin_smith -- uses clojurescript data structures but can be used as js macros within js code |
| 23:14 | sx | yes I am looking at Ki now.. caught my eye too |
| 23:14 | TEttinger | so you have stuff like map, filter, apply, -> with a different name |
| 23:14 | TEttinger | justin_smith, yeah, I have https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS bookmarked |
| 23:15 | TEttinger | it used to reside at http://altjs.org , but I think it's been taken |
| 23:15 | TEttinger | yep |
| 23:18 | bbloom | justin_smith: https://github.com/krisajenkins/yesql embodies the parser approach, only they don't have a particularly sophisticated parser (they just look for questions, mostly) |
| 23:19 | bbloom | maybe better to call it the "interpolation" approach |
| 23:19 | justin_smith | bbloom: yeah, another kind of macro that looks a lot like templating |
| 23:19 | justin_smith | right, interpolation is the word |
| 23:20 | bbloom | i think i like this approach much better than what i started to do |
| 23:20 | bbloom | b/c what i started to do basically amounts to designing both an AST as an "API" aaaaand a language as embedded in clj |
| 23:20 | bbloom | then also implementing a code generator for that language w/ a js backend |
| 23:20 | justin_smith | bbloom: what I like about yesql is it isn't a hinderance to someone who knows some actual sql |
| 23:20 | justin_smith | bbloom: unlike so many sql interaction libs |
| 23:21 | bbloom | yeah, my goal isn't to make the prettiest programs ever that all feel perfectly uniform |
| 23:21 | bbloom | my goal is nicely formatted js compiler output w/o breaking my desk via head banging in trying to generate precisely the js i want |
| 23:21 | bbloom | any embedding of js is going to be the uncanny valley thing |
| 23:25 | bbloom | ok, but that involves a parser too ... of some kind |
| 23:25 | bbloom | heh, a task for another day |
| 23:28 | joshhead | sx: lispyscript looks pretty cool. I think it keeps mostly javascript semantics but with different syntax and macro support |
| 23:28 | joshhead | no idea who uses it |
| 23:29 | justin_smith | joshhead: an amazing thing with lisp is you can find a small obscure thing and even though it is not popular you can actually do stuff with it |
| 23:29 | justin_smith | joshhead: I made some cool things with lush, which nobody here has likely heard of |
| 23:30 | TEttinger | justin_smith, the lisp shell? |
| 23:30 | TEttinger | am I confusing it with fish? |
| 23:30 | justin_smith | (a lisp that compiles to c, with an emphasis on linear algebra, dsp, and the ability to do things without gc) |
| 23:30 | justin_smith | TEttinger: the lisp one |
| 23:30 | TEttinger | oh yeah, that sounds familiar |
| 23:30 | justin_smith | though I think the shell part is misleading here |
| 23:31 | TEttinger | fish is an array programming language IIRC |
| 23:31 | justin_smith | there is also a shell called fish |
| 23:31 | justin_smith | statements which are totally absurd out of context for 100, alex |
| 23:31 | bodie_ | what is a cursor? |
| 23:31 | justin_smith | bodie in om? |
| 23:32 | bodie_ | yeah |
| 23:32 | bodie_ | I'm reading the swannodette breakdown on it, and it just made it worse |
| 23:32 | bodie_ | I want to either not understand it at all, or actually understand it, lol |
| 23:32 | justin_smith | IIRC the general concept is it tracks a place for update, but deeper than that I can't help you |
| 23:32 | bodie_ | yeah, I think it's a reference to a location |
| 23:33 | bodie_ | .... I think |
| 23:33 | bodie_ | but he refers to lenses and zippers and I think my brain exploded |
| 23:33 | puredanger | first poll done by Rich on what people wanted in Clojure (Sept 2008): https://groups.google.com/d/msg/clojure/BUlpZTDMvQ0/ko-5Q7mtoDAJ |
| 23:33 | justin_smith | bodie_: a lense is named after the fact that it can be a microscope or a telescope |
| 23:34 | bodie_ | hm |
| 23:34 | justin_smith | bodie_: it lets you insert a value into a nested place, or extract one out, with the same abstract construct |
| 23:34 | joshhead | justin_smith: do you think obscure projects are more likely to be useful if they leverage a lisp? :) |
| 23:35 | justin_smith | joshhead: that is my theory but I cannot prove it |
| 23:36 | justin_smith | joshhead: often the problem with these small obscure things is they are incomplete |
| 23:36 | justin_smith | joshhead: a lisp self-evidently contains the tools to round itself out as needed, within your program |
| 23:39 | TEttinger | puredanger, it's somewhat entertaining that almost everyone mentions error messages. have there been any improvements other than core.typed? |
| 23:40 | hiredman | there have been many |
| 23:41 | puredanger | sure, every release makes improvements to error messages |
| 23:41 | TEttinger | I mostly just infer what the error message probably means from experience, and look for whatever line numbers are in my code |
| 23:41 | justin_smith | bodie_: OK, I am reading the docs, and yeah it is like a lens |
| 23:41 | clojurebot | In Ordnung |
| 23:41 | hiredman | https://github.com/clojure/clojure/commit/b8181b7e424230b8d43008f86d03645dbef8edb0 is maybe the most recent commit that improves error messages |
| 23:41 | puredanger | if y'all would just stop making errors, this wouldn't be an issue |
| 23:41 | joshhead | bodie_: An om cursor has an interface similar to an atom. you can dereference it you get dome value, and you can apply a function to it to update the value |
| 23:42 | justin_smith | bodie_: or very similar to the way you can use the same path in get-in / assoc-in / update-in |
| 23:42 | bbloom | puredanger: the part that stands out to me is map-same |
| 23:42 | justin_smith | bodie_: I can go into more detail about any of that if you like |
| 23:42 | bbloom | ,(defn map-same [f coll] (into (empty coll) (map f coll))) |
| 23:42 | clojurebot | #'sandbox/map-same |
| 23:42 | bbloom | ,(map-same inc [1 2 3 4]) |
| 23:42 | clojurebot | [2 3 4 5] |
| 23:42 | puredanger | hiredman: look at https://github.com/clojure/clojure/blob/master/changes.md for error message changes |
| 23:42 | bbloom | but he didn't try lists! |
| 23:42 | bbloom | ,(map-same inc '(1 2 3 4)) |
| 23:42 | clojurebot | (5 4 3 2) |
| 23:42 | bbloom | :-( |
| 23:43 | bbloom | i've encountered that problem several times |
| 23:43 | joshhead | bodie_: but the data that an atom references actually lives lives at a path in an atom or another cursor. when you update the curso, the changes are reflected in the atom as well |
| 23:43 | puredanger | bbloom: heh |
| 23:44 | bbloom | seems like it might be possible to create a sort of concat-ing lazy seq thing |
| 23:45 | bbloom | but of course stack overflows would strike |
| 23:55 | numberten | does anyone know why the implemention of core/pmap adds 2 to the number of availableprocessors? https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L6465 |
| 23:56 | justin_smith | numberten: perhaps related to the fact that the agent thread pool multiplies by 2 and adds 42 |
| 23:56 | bodie_ | justin_smith, joshhead, thanks for that, didn't see your responses :) |
| 23:56 | bbloom | numberten: first, regarding pmap... |
| 23:56 | bbloom | ~pmap |
| 23:56 | clojurebot | pmap is not what you want |
| 23:57 | bbloom | numberten: second, the reason it adds 2 is probably purely heuristic for dealing with the operating system scheduler |
| 23:57 | bodie_ | justin_smith, if you could tell me which docs you're looking at for cursors, that's probably the best I could get. I assume clj home |
| 23:58 | bodie_ | thanks again fellas |
| 23:58 | numberten | bbloom: alright thanks |
| 23:58 | bbloom | really, if you had exactly the same number of threads as processors, you'd want that, but other threads are running on the machine, so in reality 1-to-1 doesn't work out quite right |
| 23:58 | bbloom | i'd imagine 2 just happens to work for some cases (maybe not even *many* cases) |
| 23:58 | joshhead | bodie_: good luck |
| 23:58 | numberten | i see |
| 23:59 | bbloom | but pmap is horribly broken since lazy seq chunking and other such changes to clojure... but it was always more of a cool demo than a useful function |
| 23:59 | puredanger | N + 2 is the perfect number of threads |
| 23:59 | puredanger | for all values of N |