2015-02-27
| 01:05 | devll | Hi, how to get current profile name in clojure? |
| 01:06 | devll | I can get around by evaluating profile specific value,but is there an elegant way to do this? |
| 01:14 | devll | ls |
| 01:14 | lazybot | bin dev etc home lib media opt sbin sys var |
| 01:24 | tcrayford____ | the ring-jetty9 adapter has a new CVE/security fix: https://github.com/sunng87/ring-jetty9-adapter/pull/20 |
| 01:24 | tcrayford____ | y'all should upgrade to 0.8.2 as fast as you can |
| 01:47 | Kneiva | yay, my first own macro: https://www.refheap.com/97841 Do you have any pointers for improvement? |
| 01:56 | sm0ke | so is there a hack to add a folder to lein's classpath? |
| 01:56 | justin_smith | Kneiva: why is it a macro? |
| 01:57 | sm0ke | the folder contains jar files |
| 01:57 | sm0ke | i tried adding to resource-paths , but no lucj |
| 01:57 | justin_smith | sm0ke: each individual jar in the folder needs to be added |
| 01:58 | sm0ke | i did a ["resources" "lib_managed/*"] justin_smith |
| 01:58 | justin_smith | oh, it accepts globs? |
| 01:58 | sm0ke | java does |
| 01:58 | sm0ke | java -cp "lib/*:..." works |
| 01:59 | Kneiva | justin_smith: can I repeat stuff for for's binding vector some other way? |
| 02:02 | justin_smith | Kneiva: ahh, right. The function can be written without using a macro, but this approach (generating a binding vector) requires one |
| 02:03 | dysfun | tcrayford____: hrm, i wonder if such a thing affects aleph |
| 02:05 | justin_smith | sm0ke: I don't doubt that java supports that, I am just not sure that lein implements it. I've never seen it done, and there is no instance of doing it that way in the project.clj. |
| 02:05 | justin_smith | *the example project.clj |
| 02:06 | Kneiva | hmm, I could probably bind the aseq to a constant so the data does not get repeated in binding vector |
| 02:14 | sm0ke | justin_smith: thanks i will verify by adding individually |
| 02:14 | sm0ke | `inc` is promised if it works :P |
| 02:16 | sm0ke | justin_smith: holy shit! |
| 02:16 | sm0ke | justin_smith: wildcard works! |
| 02:16 | sm0ke | adding "lib_managed/*" to resource-paths works |
| 02:17 | sm0ke | i was adding it to java-source-paths before |
| 02:17 | slipset | justin_smith: really enjoyed your conversation with csd_ earlier |
| 02:17 | slipset | about functions having different responabilities |
| 02:18 | justin_smith | slipset: thanks |
| 02:18 | slipset | I've been searching for a name to put on this "pattern", but never came up with anything |
| 02:18 | slipset | the closest I've come is to mention one of the functions as an orchrestator(sp?) |
| 02:19 | justin_smith | interesting |
| 02:20 | justin_smith | I'm turning in for the night, but I am sure there is a name for this (other than just "functional programming") that is escaping me today |
| 02:20 | justin_smith | one keyword would probably be "referential transperency" |
| 02:21 | slipset | my thought being that the one organizing the coupling between the logic and the side-effecter is the orchestrator, and it (the orchestrator), as you mention, needs very little testing, since it's logically very simple |
| 02:21 | slipset | btw, how can you be turning in? my day is just starting? |
| 02:21 | justin_smith | ~ugt |
| 02:21 | clojurebot | ugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html |
| 02:21 | slipset | I know :) |
| 02:22 | slipset | Interestingly, I was explaining this pattern to a co-worker just yesterday. |
| 02:22 | slipset | Also, the thing of sending the side-effecting function as a param to the logic-function |
| 02:23 | jballanc | anyone know of a library of Clojure form transformations? e.g. I want to refactor a list of calls into a threaded form |
| 02:23 | slipset | jballanc: please elaborate? |
| 02:24 | jballanc | I often find myself writing something like `(map join (partition 2 (interleave ['a 'b 'c] (some-call))))` |
| 02:24 | slipset | so you want the threading macro? |
| 02:24 | jballanc | and I'd like to refactor that to `(->> (some-call) (interleave ['a 'b 'c]) (partition 2) (map join))` |
| 02:25 | slipset | like -> or ->> |
| 02:25 | jballanc | right |
| 02:25 | jballanc | but automatically |
| 02:25 | slipset | clj-refactor might have this? |
| 02:25 | jballanc | i.e. I built up the first form either in the REPL or in my editor, but once I get 3-4 forms deep I'd like to re-order |
| 02:25 | jballanc | hmm...I'll have a look |
| 02:26 | slipset | yepp, it does |
| 02:26 | slipset | tf :) https://github.com/clojure-emacs/clj-refactor.el |
| 02:26 | julianleviston | I have some data. I'd like to look up each entry by one of THREE keys! (and have each entry to have 3 values) Oh, the craziness! Is there a way to do that? I can't think of a way, really... |
| 02:26 | slipset | or tl |
| 02:26 | jballanc | slipset: ah, indeed...and as I feared its in elisp :-/ |
| 02:27 | slipset | jballanc: yak-shave for the weekend elisp2clj |
| 02:28 | julianleviston | I should say, I want all 3 values out when I look up a key. Should I build a new type of data? I often seem to need n-way maps, actually… not really sure how to go about implementing that. |
| 02:29 | slipset | julianleviston: care to share a gist? |
| 02:29 | julianleviston | slipset: I don’t have a gist. |
| 02:30 | tcrayford____ | dysfun: it might have the same vuln, I guess, but that patch is jetty specific. writing http servers is hard :/ |
| 02:30 | julianleviston | slipset: because I haven’t started to build it yet… I’m currently re-implementing it based on these new requirements… and I’m presently using a map, which is a 1-1 version of this data structure. |
| 02:30 | jballanc | slipset: probably just quicker to hand-convert to clj...then I just have to hook it into vim-fireplace somehow |
| 02:33 | julianleviston | slipset: I’ll make up a syntax here because there’s no such syntax… (get <:a 1 :b 2 :c 3, :a 5 :b 10 :c 15> {:a 1}) should yield {:a 1 :b 2 :c 3} |
| 02:34 | julianleviston | slipset: I *could* just use a set of n maps, but that’s ugly and takes a LOT of overhead to manage, and I don’t like it. |
| 02:35 | julianleviston | slipset: the use case is I’d like to be able to say “look in the store for the one where :a is 1, and give me the value of :b”… where :a and :b are arbitrarily any of the keys. |
| 02:37 | slipset | julianleviston: but what's the relation between :a and :b? |
| 02:37 | raspasov | julianleviston: so you want a value to be "discoverable" by n different keys, and not just one? |
| 02:37 | julianleviston | slipset: if you want to know my use case, it’s :dom-id, :database-record-id and :parent-dom-id |
| 02:38 | julianleviston | raspasov: yeah :) |
| 02:38 | raspasov | is this for Clojure or ClojureScript? |
| 02:38 | julianleviston | raspasov: kind of like a map with 2 way lookup instead of 1-way lookup, but actually 3-way. |
| 02:38 | julianleviston | raspasov: CLJS |
| 02:38 | raspasov | julianleviston: hm ok, does CLJS have STM? |
| 02:38 | julianleviston | raspasov: yes |
| 02:38 | raspasov | I can't recall |
| 02:38 | slipset | so something like (get-by m keys) ...) |
| 02:39 | raspasov | I mean the refs |
| 02:39 | ro_st | cljs does not have STM |
| 02:39 | julianleviston | raspasov: no |
| 02:39 | raspasov | it doesn't have the refs, does it? |
| 02:39 | julianleviston | raspasov: just atoms |
| 02:39 | ro_st | cljs has atom and var. clj has those and ref, agent |
| 02:39 | raspasov | yea, with the STM you would be able to have three different maps |
| 02:39 | raspasov | and synchronize them |
| 02:39 | julianleviston | raspasov: wow that sounds delicious! |
| 02:39 | raspasov | julianleviston: is this irony or you're serious? :) |
| 02:40 | julianleviston | raspasov: I’m serious. Sounds neat. |
| 02:40 | raspasov | julianleviston: ok :) well you can do it with atoms as well I believe |
| 02:40 | julianleviston | raspasov: I’m not sure how tho…? |
| 02:40 | raspasov | not sure in CLJS though, since there's no threads... |
| 02:41 | julianleviston | raspasov: isn’t the problem to do with structuring the data, not the synchronisation? Or am I missing stuff? |
| 02:41 | raspasov | well, I was thinking about a kinda hacky solutions with refs |
| 02:41 | slipset | julianleviston: so, do you want all the matches or just the first? |
| 02:41 | raspasov | where you copy the data over three (or n times) |
| 02:41 | raspasov | in different maps |
| 02:42 | julianleviston | slipset: how do you mean? sorry? |
| 02:42 | raspasov | also how big is the data structure you're going to be accessing? I can think of many ways to do this with linear time lookup |
| 02:42 | julianleviston | raspasov: well I can build a hacky solution myself. I was asking here because I wanted to know if there’s an actually efficient way to do map-like data structures with n-way lookup |
| 02:43 | raspasov | doing it the proper way will prob require some more thought and potentially a new kind of data structure |
| 02:43 | julianleviston | raspasov: yeah I can think of those too… |
| 02:43 | slipset | say you have a map {:a 1 :b 2 :c 3} and you ask for the keys [:a :b], should the return value be 1, 2 or [1 2]? |
| 02:43 | raspasov | yea :) |
| 02:43 | julianleviston | raspasov: ah ok… that’s what I was interested in |
| 02:44 | raspasov | slipset: from my understanding he wants :a to be discoverable not just by :a but also by n other different keys |
| 02:44 | julianleviston | slipset: um… no think of it more like a vector of records all of the same type… which you can look up by any of the values in the records, but that enforces the uniqueness of ONE of the key values |
| 02:44 | julianleviston | raspasov: yep. |
| 02:44 | slipset | Ah, I see |
| 02:45 | julianleviston | slipset: it’s actually a bit annoying, because there can be dupes of the dom-ids and the parent-dom-ids, but not the database-ids |
| 02:46 | julianleviston | I guess I should use a relational algebra… probably. |
| 02:46 | julianleviston | yeah. |
| 02:47 | julianleviston | ok thanks guys! |
| 02:47 | raspasov | how about something like (def map-1 {:a atom-1 :b atom-2 :c atom-3}) |
| 02:47 | raspasov | and then (def map-2 {:a-1 atom-1 :b-2 atom-2 :c-2 atom-3}) |
| 02:47 | raspasov | I mean, it's still hacky |
| 02:47 | julianleviston | raspasov: erm… I’m not sure how the associations work there… at all... |
| 02:48 | julianleviston | raspasov: also these things will be stored in an atom already, so that’d be like… atoms stored in atoms… seems… bad? |
| 02:48 | raspasov | well atom-1 is discoverable by either :a or :a-1 |
| 02:48 | raspasov | yes it's not 100% pretty and idiomatic :) |
| 02:48 | raspasov | it's like a ... 50% hack lol |
| 02:48 | julianleviston | erm… I think you’ve missed my point really… but it’s cool… nevermind |
| 02:48 | julianleviston | I’ll go brush up on my relational algebra like stuffs. |
| 02:49 | raspasov | julianleviston: alright :) |
| 02:49 | julianleviston | Didn’t occur to me until just now… plus I just can’t remember the functions at the moment. |
| 02:53 | julianleviston | be so much easier if there was some kind of pattern matching facility |
| 02:55 | dysfun | tcrayford____: once something involves the network, it's time to give up and let someone else do it |
| 03:06 | slipset | core.logic? |
| 03:12 | dysfun | slipset: what about core.logic? |
| 03:24 | julianleviston | dysfun: it was meant for me |
| 03:24 | dysfun | oh right |
| 03:24 | dysfun | in that vein, also core.match |
| 03:25 | julianleviston | I just meant this: pseudo-relational algebra support for 'relations', which are simply sets of maps - select/index/rename/join |
| 03:25 | julianleviston | particularly join... |
| 03:26 | julianleviston | dysfun: thanks |
| 03:26 | dysfun | i think R can do that, incidentally |
| 03:26 | dysfun | which means incanter probably can |
| 03:26 | julianleviston | dysfun: is it effecient over 2000+ item sets I wonder... |
| 03:27 | dysfun | they're in memory. if you weren't doing it in your app you'd be doing it in the database which would probably have to read off disk |
| 03:27 | dysfun | so i'd expect it's "fast enough" |
| 03:28 | julianleviston | dysfun: maybe. I’m expecting this to be comparable to a map lookup... |
| 03:28 | julianleviston | dysfun: because I’m doing like… thousands of these and I’d like it to be very fast. |
| 03:29 | dysfun | i expect you probably want some sort of index data structure |
| 03:29 | dysfun | or, y'know, a database |
| 03:29 | julianleviston | dysfun: guh. This is a simple data structure. |
| 03:30 | dysfun | then you don't have to worry about performance until you've demonstrated a problem |
| 03:30 | dysfun | i can assure you that thousands of operations are not a problem for the combined might of the jvm and a decent machine to run it on |
| 03:31 | julianleviston | dysfun: CLJS |
| 03:31 | dysfun | client side or server side? |
| 03:31 | julianleviston | dysfun: client |
| 03:31 | dysfun | why are you doing all of these operations on the client? |
| 03:31 | julianleviston | dysfun: it matters. I’ve demonstrated that it slows things down |
| 03:32 | julianleviston | dysfun: it’s not a huge amount of operations. |
| 03:32 | julianleviston | dysfun: my point… it should be as fast/efficient as map lookup. |
| 03:32 | julianleviston | dysfun: because this is a master mapping index of in-memory records. Suggesting I put it in a db is kinda… self-defeating. |
| 03:33 | pepijndevos | What are my options for a websocket server? It seems Aleph and http-kit. How do they compare? Both seem to use their own channel-ish things. |
| 03:33 | julianleviston | dysfun: I just need it to be able to be looked up by 3 keys, is all. |
| 03:34 | zot | just curious: is there another idiom for (mapcat identity coll)? |
| 03:34 | dysfun | julianleviston: i think you probably want javascript workers then |
| 03:34 | julianleviston | zoldar_: concat ? |
| 03:35 | julianleviston | dysfun: errrr… it’s not THAT much work… is it? Not knowing anything about what JS workers are |
| 03:35 | dysfun | pepijndevos: aleph is fantastic if you're running websocket-y stuff. http-kit is fantastic if you're doing client-y stuff. i'd probably use aleph for both these days |
| 03:35 | pepijndevos | dysfun isn't websockety stuff also clienty stuff? |
| 03:36 | julianleviston | dysfun: I *had* a 2 key version which I just used a map-invert when I needed the other direction… but the requirement just changed to having a 3 way lookup, and I’m investigating good ways to implement that… |
| 03:36 | julianleviston | dysfun: all good I’m going to try with this join thing first and see what happens after that |
| 03:37 | julianleviston | zot: sorry… I mistyped - concat ? |
| 03:37 | julianleviston | zot: seeing as mapcat maps a function across a coll, then concats the result… no need to do the map part. |
| 03:38 | dysfun | pepijndevos: sorry, i meant "http client" here, so if you're wanting to *initiate* connections |
| 03:38 | pepijndevos | ah |
| 03:40 | zot | julianleviston: apply concat would be the same i suppose |
| 03:40 | zot | i was curious if there's a completely standardized idiom for it |
| 03:40 | zot | and identity is *such* a long word :) |
| 03:42 | hyPiRion | Wish it was named `id` |
| 03:43 | julianleviston | (def id identity) |
| 03:43 | julianleviston | pretty easy |
| 03:43 | dysfun | i'd use 'apply concat' |
| 03:43 | julianleviston | zot: given the source of mapcat USES apply concat, I think what you want is silly… just write your own function if you don’t want to repeat yourself |
| 03:44 | zot | lol. point taken :) |
| 03:44 | julianleviston | (defn catty [& args] (apply concat args)) |
| 03:44 | julianleviston | I have loads of these shortcuts of my own… and a lot are in contrib... |
| 03:47 | julianleviston | zot: sorry I didn’t mean to be rude. Shouldn’t have used the word silly… “trivial” might have been a better word. :) |
| 03:48 | zot | julianleviston: no worries dude, i'm a big boy, and didn't take any offense in the first place. but it's great to see you speak up; not enough adults act like it, these days :) |
| 04:42 | Glenjamin | ~mapply |
| 04:42 | clojurebot | You have to do something like (defn mapply [f & args] (apply f (apply concat (butlast args) (last args)))), which just goes to show why unrolled keyword args are a bad idea |
| 04:43 | Glenjamin | zot: ^ is that the scenario? |
| 04:45 | zot | Glenjamin: not really. but your suggestion has a bonus: seeing 'butlast' for the first time :) |
| 05:03 | dysfun | what's the library that has a reloader for lein repl called? |
| 05:07 | pepijndevos | wut... my Aleph websocket is closed instantly. |
| 05:08 | zot | dysfun: https://github.com/stuartsierra/reloaded ? |
| 05:09 | noncom|2 | Raynes ping |
| 05:09 | Raynes | sup brotha |
| 05:09 | dysfun | zot: no, there's another module i'm thinking of. that does a quick scan of changed files. although i'm using reloaded workflow so i should probably figure out reloaded repl |
| 05:10 | noncom|2 | i've just got a cery strange error within conch |
| 05:10 | Raynes | That's a shame |
| 05:10 | zot | dysfun: if you figure it out, please share :) i've had mixed luck w/ reloaded |
| 05:11 | noncom|2 | i use lein 2.x and when i don't say :aot [main.namespace], it works ok (except that lein complains that i should be explicit). when i do say than, an exception comes up: https://www.refheap.com/97846 |
| 05:11 | noncom|2 | the line that causes the exception is marked in the source sample |
| 05:12 | noncom|2 | i think this is not conch error, but it is so strange one.. |
| 05:12 | noncom|2 | why would that happen? |
| 05:12 | noncom|2 | (sorry for typos) |
| 05:13 | Raynes | That's something wrong with your environment. |
| 05:13 | Raynes | I see ci related stuff in there |
| 05:13 | Raynes | Does this happen in a repl? |
| 05:13 | noncom|2 | no, a teamcity ci agent runs the jar |
| 05:14 | noncom|2 | it works ok, if i remove the explicit :aot clause in project.clj.. but afaik lein does just that automatically if i don't say it.. the main ns also has the (:gen-class) ns parameter.. |
| 05:15 | noncom|2 | and how drop-last is different from any other clojure.core function... ? |
| 05:17 | dysfun | zot: hrm, i've just gotten reloaded repl working, but working is a strong thing to say because the moment i get an error, my repl module drops out of usability and i can't call the refresh function |
| 05:18 | zot | dysfun: sounds like exactly the fun i've experienced :) |
| 05:20 | dysfun | well i can figure out how to get around that. I just need to hook it into cider and bind a keycombo to eval (require '[clojure.tools.namespace.repl :refer [refresh]]) (refresh) |
| 05:21 | dysfun | i wonder what other horrors it has lurking |
| 05:21 | zot | i copy gladly. i had other issues with it (namely files w/ protocols always breaking, and sometimes having it run alllllll unit tests, despite my best efforts). |
| 05:21 | zot | i haven't spent enough time to understand it better |
| 05:21 | pepijndevos | Hmmmm it seems closing a manifold closes the whole chain. How do I stop this? |
| 05:22 | pepijndevos | I'm trying to do something like this: https://www.refheap.com/97849 |
| 05:24 | dysfun | pepijndevos: pass downstream? false to connect |
| 05:25 | pepijndevos | dysfun thanks |
| 05:25 | dysfun | yw |
| 05:25 | pepijndevos | as a keyword, or just like that? |
| 05:26 | dysfun | you pass a map as the last arg if you want to provide some |
| 05:26 | dysfun | and keyword |
| 05:26 | dysfun | (s/connect foo bar {:downstream? false}) |
| 05:27 | pepijndevos | cool |
| 05:27 | dysfun | what are you building, out of interest? |
| 05:28 | pepijndevos | dysfun, connecting a Game Boy to the internet. |
| 05:28 | dysfun | cool! |
| 05:28 | dysfun | how does that work then? |
| 05:32 | pepijndevos | dysfun, with a teensy and a WebRTC connection. Quite tricky. https://www.youtube.com/watch?v=0X6RxmUK6jA |
| 05:33 | dysfun | oh wow |
| 05:34 | dysfun | 'TCPokemon' heh |
| 05:34 | pepijndevos | I'm now making the Chrome app that talks to the Teensy a little more robust. |
| 05:34 | pepijndevos | Yea, that's what it's called for now, kinda cheesy, but hey. |
| 05:35 | pepijndevos | So I'm using Aleph to do chat and initiate the peer connection |
| 05:35 | dysfun | nice |
| 05:35 | dysfun | why are you doing it in browser though? |
| 05:36 | dysfun | i suppose you could build a gameboy social trading network |
| 05:36 | pepijndevos | because that is the only platform that has easy access to USB hardware AND peer to peer connections. |
| 05:36 | dysfun | 'easy access to usb hardware' wouldn't be my first guess :) |
| 05:37 | pepijndevos | think again https://developer.chrome.com/apps/hid |
| 05:37 | dysfun | cool |
| 05:37 | daniel` | anyone can point me to the easiest way of getting a headless cljs setup with repl? |
| 05:38 | daniel` | lein template of some kind |
| 05:38 | pepijndevos | If there was a good HID lib and WebRTC lib for clojure.... I'm not that big of a fan of chrome and webdev. |
| 05:39 | dysfun | pepijndevos: well actually, i might be able to help you there |
| 05:39 | dysfun | pepijndevos: i've been using |
| 05:39 | dysfun | libwebkitgtk+ to embed webkit. so you can have the same apis through gobject introspection |
| 05:40 | dysfun | i haven't tried the clojure bindings myself because JNI is horrible |
| 05:40 | dysfun | well, the java bindings |
| 05:40 | dysfun | also i'm building something that wouldn't benefit terribly from the jvm |
| 05:52 | pepijndevos | dysfun, I don't know. I think a chrome app makes sense and is not terrible. I'm not sure if some webkit hack is worth the effort |
| 06:00 | dysfun | it is for me because i find javascript enormously tedious and clojurescript leaves a little to be desired on the 'instant feedback' front |
| 06:00 | dysfun | and i won't ever need to provide it over the web |
| 06:39 | pepijndevos | staartuuuupp tiiiiimeeeee! (I can type this whole mesage between lein run and something happening) |
| 06:40 | noncom|2 | probably we could rewrite lein in python to make it faster.. |
| 06:40 | noncom|2 | (joke :) ) |
| 06:43 | dysfun | wow, tetrisql looks cool :) |
| 06:43 | dysfun | https://github.com/zilti/tetrisql |
| 07:05 | noncom|2 | when creating an app with luminus template, what advantage is of http kit over the default ring-server do i get if i specify +http-kit ? |
| 07:10 | noncom|2 | in other words, what is the difference between using ring and httpkit? |
| 07:17 | dysfun | httpkit is asynchronous so you can handle more connections concurrently |
| 07:18 | dysfun | in theory, anyway |
| 07:19 | samflores | noncom|2: I think you wanna know the diff between *jetty* and httpkit, right? |
| 07:20 | noncom|3 | samflores: oh, i know that: jetty is java io server, which makes a thread for every connection, and httpkit (i looked at the sources) uses java nio, correct? |
| 07:21 | noncom|3 | so that's the only difference, looks like using httpkit is the better option anyway |
| 07:26 | dysfun | or you can use aleph, which uses jetty's asynchronous features |
| 07:26 | samflores | well, I wouldn't say it *is* the better option, but as dysfun said, it theoretically can handle more concurrent connections |
| 07:26 | samflores | I tend to use http-kit due to its WebSocket support |
| 07:27 | dysfun | aleph also supports websockets :) |
| 07:28 | dysfun | pick the one you like the sound of better, tbh. they're both written by smart people |
| 07:29 | samflores | true that |
| 07:29 | dysfun | i quite like ztellman's other libraries which integrate quite nicely with aleph |
| 07:30 | dysfun | i also use a lot of ptaoussanis' modules, but they're fairly silo'd |
| 07:33 | samflores | it was ptaoussanis' sente that led me to http-kit :p |
| 07:33 | samflores | now it works with immutant too. I need to try that |
| 07:35 | dysfun | sente is cool, been meaning to play with it |
| 08:35 | Eremox | Is a function which references a global but immutable variable considered referentially transparent? And not if mutable? |
| 08:36 | justin_smith | Eremox: that sounds about right. Also, if it captures the variable at time of definition it can be pure even if the variable was mutable. |
| 08:37 | justin_smith | Eremox: sometimes you can change a clojure function from pure to impure by changing fn-name to #'fn-name because the later is always delayed to be looked up at runtime. This can be useful when redefining things during development. |
| 08:38 | Eremox | U mean a closure? But what if is a ref then I would have to capture the value not the ref |
| 08:38 | justin_smith | Eremox: all clojure vars are mutable |
| 08:38 | justin_smith | that's what I mean |
| 08:39 | Eremox | Do you OK sorry I misunderstood but I get it |
| 08:40 | Eremox | And do you mean I define the fn with #'name or that I call (#'name)? |
| 08:40 | justin_smith | the latter |
| 08:41 | justin_smith | in normal code, vars will be looked up at runtime, but if you bind something as a function arg or in a let block you need the #'foo form for runtime lookup, otherwise you capture and close over a value |
| 08:42 | Eremox | Thanks for the info ;) |
| 08:43 | justin_smith | of course code which changes vars during a normal run isn't idiomatic. During dev you want to change vars though. |
| 08:44 | Eremox | Do you know a good article i can read to understand the reader. And what happens behind the scenes? |
| 08:45 | justin_smith | Eremox: have you looked at the clojure.org docs for the reader? http://clojure.org/reader |
| 08:46 | mavbozo | Eremox, there's a video How Clojure Works https://www.youtube.com/watch?v=8NUI07y1SlQ |
| 08:46 | Eremox | Yeah was reading now. Great I will watch that video. Thanks. |
| 09:23 | ila1222221 | In cls I'd like to make objects implement ISeqable... |
| 09:23 | ila1222221 | How do I find out what the methods are to override? |
| 09:23 | ila1222221 | clojuredocs has no entry for it |
| 09:23 | ila1222221 | (ISeqable) |
| 09:24 | puredanger | the only method is (seq [this]) |
| 09:25 | julianleviston | ila1222221: http://swannodette.github.io/2015/01/12/lazy-contracts/ |
| 09:25 | julianleviston | has an example of implementing it |
| 09:26 | dnolen | ila1222221: it's not documented anywhere, another good idea for a community maintained wiki page though! |
| 09:27 | ila1222221 | ok... so what is the path to discover the methods of any arbitrary protocol. is it something that can be done at runtime, or do you go through cljs or clj source code? |
| 09:33 | ila122221 | blech crash. |
| 09:37 | justin_smith | ila122221: protocols are implemented in clojure code, which means you can use clojure.repl/source to see their code |
| 09:37 | puredanger | Seqable is a Java interface. you will probably inevitably have to look through the Clojure source itself for the details of everything. |
| 09:37 | justin_smith | also you can use clojure.repl/doc to see just the doc string |
| 09:37 | puredanger | there is also a great scaffold generator …. looking |
| 09:37 | justin_smith | puredanger: ahh yeah, fair point. |
| 09:37 | puredanger | https://gist.github.com/semperos/3835392 |
| 09:38 | puredanger | that's a pretty useful tool for this |
| 09:38 | justin_smith | so, pedantically you can see "the source for an arbitrary protocol" but ISeqable isn't a protocol :) |
| 09:38 | justin_smith | (inc puredanger) |
| 09:38 | lazybot | ⇒ 32 |
| 09:38 | justin_smith | that's cool |
| 09:39 | puredanger | you also may find this tool to be good for exploring the internal class structure of the Clojure impl https://github.com/stuartsierra/class-diagram |
| 09:41 | ila122221 | oh wow that tool is awesome. i tried source and doc in a lein repl and it gives me nil, maybe a lein setting? i'll probably prefer stuarts lib though. |
| 09:41 | justin_smith | ila122221: source and doc work for protocols |
| 09:41 | justin_smith | ila122221: but ISeqable is not a protocol, it is an interface |
| 09:41 | ila122221 | ah duh the I ok. |
| 10:30 | trideon | does anyone know what is wrong with this code? http://pastebin.com/KpcMVZyD |
| 10:34 | justin_smith | trideon: get does not work on lazy-seqs |
| 10:34 | justin_smith | ,(get (range 10) 2) |
| 10:34 | clojurebot | nil |
| 10:34 | justin_smith | you would need nth |
| 10:34 | justin_smith | ,(nth (range 10) 2) |
| 10:34 | clojurebot | 2 |
| 10:35 | trideon | thanks |
| 10:36 | justin_smith | the NPE happens in the > call (getting a value that is nil thanks to get) |
| 10:36 | justin_smith | ,(> nil Math/PI) |
| 10:36 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 10:37 | justin_smith | also, as a style thing, you might like (pos? (mod % p)) better than (not= (mod % p) 0) |
| 10:37 | justin_smith | but that's six / half-dozen |
| 11:37 | mmitchell | Is there a default timeout value for deref? |
| 11:38 | stuartsierra | mmitchell: no, it will block forever |
| 11:38 | mmitchell | ok thanks stuartsierra |
| 11:42 | justin_smith | mmitchell: but deref does take a timeout arg optionally of course |
| 11:43 | justin_smith | (I frequently forget this) |
| 11:43 | mmitchell | yeah nice feature |
| 11:43 | Glenjamin | (doc deref) |
| 11:43 | clojurebot | "([ref] [ref timeout-ms timeout-val]); Also reader macro: @ref/@agent/@var/@atom/@delay/@future/@promise. Within a transaction, returns the in-transaction-value of ref, else returns the most-recently-committed value of ref. When applied to a var, agent or atom, returns its current state. When applied to a delay, forces it if not already forced. When applied to a future, will block if computation not complete. When applied to a promise |
| 11:43 | Glenjamin | (inc justin_smith) |
| 11:43 | lazybot | ⇒ 198 |
| 11:44 | Glenjamin | i'd never noticed that before |
| 12:02 | mmitchell | anyone here familiar with http-kit's :timeout option? |
| 12:02 | mmitchell | client |
| 12:14 | pepijndevos | What is the key for in add-watch? |
| 12:16 | Glenjamin | pepijndevos: it's just a name |
| 12:16 | Glenjamin | you can use it to replace a watch |
| 12:16 | Glenjamin | or remove-watch |
| 12:18 | pepijndevos | thanks |
| 12:22 | justin_smith | mmitchell: it cancels the request if the server takes too long to respond. Do you have a more specific question about it? |
| 12:25 | mmitchell | justin_smith: yeah, just that it doesn't seem to behave consistently. I have a test server setup that blocks for 5 seconds. I set the :timeout option to 3000, and wrap that with the time macro. |
| 12:25 | mmitchell | My test server blocks for 5 seconds, and I get the response successfully |
| 12:25 | justin_smith | oh, weird |
| 12:25 | mmitchell | the time macro reports just a little over 5 seconds |
| 12:25 | mmitchell | yeah it is |
| 12:26 | justin_smith | mmitchell: oh, are you using conn-timeout or socket-timeout? |
| 12:27 | justin_smith | because socket-timeout is a socket pool option (for pooling client connections for reuse) |
| 12:27 | mmitchell | good question. I'm not sure. it's just the :timeout option. |
| 12:28 | justin_smith | and the timeout logic may be more about timing out on initial handshake, rather than timing out on getting the result |
| 12:28 | mmitchell | yeah that would make sense |
| 12:28 | justin_smith | mmitchell: I don't even see a unqualified "timeout" key being used https://github.com/dakrone/clj-http/blob/master/src/clj_http/core.clj#L207 |
| 12:30 | justin_smith | mmitchell: and as you can see here, all the client methods are just calls to that request function https://github.com/dakrone/clj-http/blob/master/src/clj_http/client.clj#L838 |
| 12:30 | mmitchell | justin_smith: oh this is http-kit - http://www.http-kit.org/ |
| 12:30 | mmitchell | sorry |
| 12:30 | justin_smith | argh, I'm sorry |
| 12:30 | mmitchell | no worries! |
| 12:34 | xemdetia | MORE SORRY |
| 12:37 | justin_smith | mmitchell: and this is an async request? because the docs for clj-http.client/request suggest that for synchronous requests you should instead use deref with the optional timeout args |
| 12:38 | mmitchell | yeah, this is using http-kit's "request" function. It has a :timeout option here - https://github.com/http-kit/http-kit/blob/master/src/org/httpkit/client.clj#L135 |
| 12:38 | justin_smith | mmitchell: right, that's the doc I am reading |
| 12:38 | justin_smith | it suggests using deref for sync |
| 12:38 | justin_smith | and :timeout for async |
| 12:39 | mmitchell | ahh I see. The deref w/timeout works as expected (sync) |
| 14:02 | fellipebrito | [noob/starting here] Reading The Joy of Clojure yesterday. On a single example the guy moved things inside the main defn as much as he could. |
| 14:02 | fellipebrito | It is completely the opposite of OO, when you try to use few lines inside your method, and organize it better with the principle of a method executes only one action. |
| 14:03 | agarman | @fellipebrito functions should do one thing only |
| 14:03 | agarman | @fellipebrito just like methods in OO |
| 14:03 | fellipebrito | I've studied and pushed my team to write a great code, following best practices and tons of other things that are out there on the ruby community. |
| 14:03 | agarman | @fellipebrito beginner books don't always demonstrate the best examples up front |
| 14:04 | fellipebrito | @agarman sure thing |
| 14:04 | fellipebrito | @agarman maybe I'm too raw, I will keep reading the book, but would ike to hear from you guys |
| 14:04 | agarman | btw, what page are you referencing? |
| 14:06 | fellipebrito | @agarman I will look for it later and get back to you |
| 14:07 | fellipebrito | @agarman thank you! |
| 14:08 | fellipebrito | By the way. I have the book Clean Code here. How you guys see it being applied to Clojure? |
| 14:10 | agarman | @fellipebrito I like Agile PPP in C# by same author. SOLID & YAGNI apply to well written programs. |
| 14:13 | justin_smith | fellipebrito: some things that are slightly different with Clojure - for immutable data (which is what most things should be), there is less benefit for making it private or encapsulating. So well written idiomatic Clojure code will often pull things out of a private or closed over scope to be an immutable global. |
| 14:14 | fellipebrito | @justin_smith Thank you! For me it is still a "huge mess". I love the code as data idea, but everytime I open a file It takes some minutes until I feel comfortable reading the code. I'm used to read any well-written ruby code in seconds.... I will keep studying and pushing hard to get the 'clojure-way' |
| 14:15 | justin_smith | fellipebrito: also, because the clojure compiler demands that definitions be declared or bound before being accessed, the quickest way to read a normal namespace is usually from the bottom of the file to the top |
| 14:16 | agarman | ,(declare maybe) |
| 14:16 | clojurebot | #'sandbox/maybe |
| 14:16 | justin_smith | every once in a while you will see code that is organized top to bottom with declare |
| 14:16 | justin_smith | but that's rare in practice |
| 14:16 | justin_smith | so you should not expect it as a reader of code |
| 14:17 | fellipebrito | @justin_smith I will buy some mangas alongside my new clojure books :) |
| 14:17 | justin_smith | haha |
| 14:17 | TimMc | "declare" usually means "lots of mutually recursive code ahead" |
| 14:17 | justin_smith | it's just a rule of thumb that works well for me when I decide to read clojure code - I take a peek at the top, and most of the time the next step is to jump to the bottom of the file and scroll up |
| 14:17 | agarman | yep, declare is a spaghetti crossing sign |
| 14:17 | fellipebrito | I do not want to write "ruby code" in clojure. I am trying to "get the groove"... the community helps a lot. Thank you guys |
| 14:17 | justin_smith | if I see a nice big comment block at the top of the file, and / or usage of declare, then I read top down |
| 14:18 | TimMc | fellipebrito: IRC convention doesn't use the @ sign, by the way. |
| 14:18 | fellipebrito | thanks TimMc |
| 14:18 | agarman | @TimMc I started that above...my bad :-p |
| 14:18 | TimMc | If you leave it off, people are more likely to be notified by their IRC clients that you're talking to them. |
| 14:18 | TimMc | hah |
| 14:19 | fellipebrito | TimMc you see... you started above, but if I read bottom - top, I will not see the error and I will start the right way. |
| 14:19 | pepijndevos | Can I somehow auto--reload an Aleph app? the startup time is killing me. I could have written another app in Java it the time spent waiting. |
| 14:19 | fellipebrito | Thank you justin_smith agarman and TimMc |
| 14:19 | TimMc | justin_smith: I usually read from the top when I'm reviewing code, although I don't know that that's really the most efficient approach. |
| 14:20 | agarman | pepijndevos: can't you just recompile files into running app? |
| 14:20 | pepijndevos | agarman, maybe? How? |
| 14:20 | justin_smith | TimMc: often there are one or two functions that are kind of "the reason this namespace exists", and it helps me to see those defs before looking at the details, and they are very likely to be at the bottom of the file |
| 14:21 | agarman | pepijndevos: I just reload file through emacs |
| 14:21 | Glenjamin | thats my biggest bugbear in clojure, that i have to read from the bottom of the file |
| 14:21 | pepijndevos | uh... emacs? |
| 14:21 | justin_smith | pepijndevos: if you have a repl open, (require 'some.ns :reload) |
| 14:21 | Glenjamin | not that it's a big issue really |
| 14:21 | agarman | pepijndevos: if your in Intellij, using Cursive, you can do the same thing |
| 14:21 | pepijndevos | I see... |
| 14:21 | agarman | pepijndevos: or exactly what justin_smith said |
| 14:22 | justin_smith | pepijndevos: most editors have some "reload project" function, but it's just going to call that one liner I posted anyway |
| 14:22 | pepijndevos | :) |
| 14:22 | agarman | pepijndevos: or :reload-all if there's a whole lot of changes |
| 14:22 | justin_smith | yes, that's a good point too |
| 14:23 | agarman | in my own web app, I (stop) (require 'core.stuff :reload-all) (start) |
| 14:23 | justin_smith | I should have said "reload namespace" rather than "reload project" above |
| 14:23 | TimMc | which is great until there are defrecords or protocols or multimethods :-P |
| 14:23 | justin_smith | hello, component |
| 14:23 | agarman | yeah TimMc got some of those and it super not fun |
| 14:23 | TimMc | justin_smith: ssshhhhh |
| 14:23 | agarman | yep |
| 14:23 | TimMc | ssshhhh |
| 14:24 | TimMc | (One of these days I will get around to using that.) |
| 14:24 | agarman | same |
| 14:24 | agarman | still less time wasted than would probably take to migrate everything into component or similar |
| 14:46 | fellipebrito | Any of you guys trying to use clojurescript + Phonegap (or something like that) = nativeapps? |
| 14:58 | dysfun | lighttable is a native app using node-webkit. but i'm guessing you meant for phones. the phonegap desktop stuff is... a little sketchy |
| 14:58 | nkoza | fellipebrito: if you google "clojurescript phonegap" you can see some examples |
| 14:59 | nkoza | fellipebrito: there is also ongoing work to integrate Clojurescript with React Native, so you can use iOS/Android from CLJS |
| 14:59 | fellipebrito | dysfun nkoza my main goal are iphone and android native apps, but not using only a webview... you know apple hates it. |
| 15:00 | dysfun | there's a clojure->ios thingy |
| 15:00 | nkoza | fellipebrito: check this: https://code.facebook.com/videos/786462671439502/react-js-conf-2015-keynote-introducing-react-native-/ |
| 15:00 | nkoza | fellipebrito: and this: https://github.com/omcljs/ambly |
| 15:00 | fellipebrito | nkoza Praise the lord |
| 15:01 | dysfun | ooh, nice |
| 15:10 | ToxicFrog | Does pprint have the same guarantee as prn in that it emits something the reader can consume? |
| 15:13 | gfredericks | eehch |
| 15:17 | chouser | ToxicFrog: prn doesn't have that guarantee either, as far as I know. |
| 15:17 | chouser | ,(pr-str (Object.)) |
| 15:17 | clojurebot | "#<Object java.lang.Object@7799cdd5>" |
| 15:17 | amalloy | prn produces something the reader can consume when it can |
| 15:17 | chouser | ,(read-string (pr-str (Object.))) |
| 15:17 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unreadable form> |
| 15:17 | ToxicFrog | chouser: (doc pr) says it does |
| 15:17 | justin_smith | ,(doc pr) |
| 15:17 | clojurebot | "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader" |
| 15:18 | ToxicFrog | I mean, obviously this isn't universally possible, but it guarantees that it will if it can |
| 15:18 | ToxicFrog | So I know I can throw a map full of keywords and strings at it and get something that I can read back in later. |
| 15:19 | chouser | Yeah. I think that should work approximately as well with pprint as with prn |
| 15:20 | mikerod | Does it matter if type-hints are Symbols representing classes or actual Class objects themselves? |
| 15:20 | amalloy | mikerod: they should be symbols |
| 15:21 | hexa | Hi, I have this weird problem if I do like (do (map println '(1,2,3))) with lein-exec plugin , nothing prints out.... , without map all is fine,,, ideas?? |
| 15:21 | lazybot | hexa: Definitely not. |
| 15:21 | amalloy | ~lazy |
| 15:21 | clojurebot | lazy is hard |
| 15:21 | amalloy | er |
| 15:21 | amalloy | ~map |
| 15:21 | clojurebot | map is hard |
| 15:21 | amalloy | sure |
| 15:21 | justin_smith | hahaha |
| 15:21 | justin_smith | hexa: map is lazy |
| 15:21 | hexa | haaaa domap...? or similar |
| 15:21 | justin_smith | doall |
| 15:21 | hexa | righ thx!! |
| 15:21 | mikerod_ | ,(-> #'str meta :tag type) |
| 15:21 | clojurebot | java.lang.Class |
| 15:21 | hexa | I was getting crazy since it worked ok on the repl hehe |
| 15:22 | justin_smith | hexa: or dorun since you likely aren't using the return value |
| 15:22 | mikerod_ | amalloy: this seems inconsistent |
| 15:22 | justin_smith | hexa: right, printing forces laziness |
| 15:22 | mikerod_ | I thought it should be symbols too |
| 15:22 | mikerod_ | but I see a mix |
| 15:22 | hexa | :) |
| 15:22 | justin_smith | (and Print is the P in rePl) |
| 15:23 | mikerod_ | ,(-> #'realized? meta :arglists first first meta :tag type) |
| 15:23 | clojurebot | clojure.lang.Symbol |
| 15:23 | mikerod_ | I'm guessing the compiler is dealing with symbols and classes interchangably |
| 15:24 | mikerod_ | it is always awkward in situations where you have to chose which one is right for a type hint, if you are doing something like writing a macro. |
| 15:24 | amalloy | mikerod: the hints on arglists are not the same as hints on vars. the compiler does not treat them the same; i wouldn't try comparing them |
| 15:24 | amalloy | mikerod_: it is very easy. always choose a var |
| 15:24 | amalloy | er, a symbol |
| 15:24 | mikerod_ | amalloy: I see... :) |
| 15:25 | mikerod_ | I see some places in the compiler explicitly referring to `tag` fields with type Symbol, so that does seem to be the wise choice |
| 15:25 | amalloy | the :tag metadata on vars may be symbols, it may be classes, who cares - the important thing is that in the *source code* the compiler reads, it should be symbols |
| 15:26 | hiredman | strings |
| 15:26 | mikerod_ | oh |
| 15:26 | amalloy | well. sure. that's fine too i guess |
| 15:26 | amalloy | but a human being can type a string or a symbol into source code, and they can't type a Class object out and save it in their .clj file |
| 15:26 | amalloy | the compiler is supposed to consume stuff you could have typed |
| 15:28 | hiredman | ,((fn [^foo/String x] (.toString x)) "Foo") |
| 15:28 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: foo/String, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:29 | hiredman | ,((fn [^foo/java.lang.String x] (.toString x)) "Foo") |
| 15:29 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: foo/java.lang.String, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:29 | mikerod | amalloy: I'm able to not fail though with classes |
| 15:29 | mikerod | like (eval (let [sym (with-meta 'a {:tag String})] `(let [~sym "a"] (-> '~sym meta :tag type)))) |
| 15:29 | mikerod | I'd think that would break |
| 15:29 | mikerod | its fine, I'll stick to symbols |
| 15:29 | mikerod | I'm just curious how it keeps working out for me to use embedded classes instead |
| 15:29 | amalloy | mikerod: sure, some things work. you can add #_#_#_#_#_3 anywhere in your source code and it works fine |
| 15:30 | amalloy | likewise (eval (fn [])) works, but you're not supposed to do it |
| 15:31 | gfredericks | (defn set-foo [x] (def foo x)) also works fine and you're also not supposed to do it |
| 15:32 | gfredericks | FSVO "supposed" |
| 15:32 | hiredman | fsvo of works fine |
| 15:32 | mikerod | :D |
| 15:32 | justin_smith | gfredericks: also, (System/exit 42) can replace any program |
| 15:33 | justin_smith | it's a proven fact |
| 15:33 | chouser | (swap! x prn) ; fsvo works fine |
| 15:33 | mikerod | all good points |
| 15:33 | hiredman | e.g. if people do that expecting scheme's local defines, that doesn't work |
| 15:33 | gfredericks | yeah true |
| 15:34 | hiredman | if you do that, and expect clojure to still throw an error compiling forms that reference foo because you haven't run the function yet, that doesn't work |
| 16:02 | oskarth | Using secretary, is there something I have to do server-side in order to get dispatch to work when changing the URL? Adding `(defroute foo "/bar" [] ...)` and clicking a link `href="#/bar` doesn't do anything, but running `dispatch!` manually in browser-repl works. |
| 16:18 | oskarth | problem was with listening to 'navigate' event |
| 16:25 | augustl | is there a canonical setup for using clojurescript to develop code for running in node.js? |
| 16:44 | nuwanda_ | oskarth: yeah, I've only used secretary on a small project and i didn't have time to figure out what I was doing wrong so I simply had those links directly dispatch |
| 16:45 | nuwanda_ | I'm sure there's another (proper) way to do it though |
| 16:55 | augustl | emacs indents clojure like in "actual.clj". How do I make it indent the way it is in "want.clj"? :) https://gist.github.com/augustl/7b028e1cadc498809e56 |
| 16:55 | augustl | I don't want nested data structures to align to the opening symbol, I want it to indent like normal code |
| 17:00 | justin_smith | augustl: hanging open symbols aren't very popular in this language family |
| 17:00 | justin_smith | *open delimiters |
| 17:00 | amalloy | your "want" is weird as heck. it doesn't look like "normal code"; normal code in clojure looks like actual |
| 17:01 | augustl | is it really that weird? The code is from David Nolen's leiningen templates |
| 17:02 | augustl | I found the extra spaces that emacs added when I indented the generated project.clj pretty unhelpful |
| 17:03 | augustl | the rule seems pretty simple to me, indent nested data structures the way builtins like "do", "if", etc are indented |
| 17:03 | justin_smith | augustl: that's not what it is though. It's indenting based on trailing open delimiters C style |
| 17:04 | hiredman | gross |
| 17:04 | TimMc | Here's a thing I think I'd like to be able to do: https://www.refheap.com/97878 |
| 17:04 | amalloy | augustl: do you have a link to whatever code from dnolen you copied? |
| 17:04 | TimMc | Basically, "footnotes" in functions so that I can attach logging statements and the like unobtrusively. |
| 17:05 | augustl | amalloy: sure, https://github.com/swannodette/mies-node-template |
| 17:05 | augustl | specifically https://github.com/swannodette/mies-node-template/blob/master/src/leiningen/new/mies_node/project.clj |
| 17:05 | amalloy | that is really weird. i don't know why he is writing it that way |
| 17:06 | augustl | perhaps it's an intellij thing or something |
| 17:06 | TimMc | The syntactic transform would look like this: https://www.refheap.com/97879 |
| 17:08 | amalloy | TimMc: it's less featureful/flexible, but for simple cases flatland.useful.debug/? does similar stuff |
| 17:09 | turbofail | i feel like that indentation style does make some amount of sense for maps |
| 17:09 | augustl | turbofail: not sure what's not to like about it :) |
| 17:09 | turbofail | it's nice to be able to keep the keys and values together without having them push too far to the right |
| 17:10 | turbofail | that said i still use the emacs default style |
| 17:11 | turbofail | and i don't know if there's any straightforward way to make emacs do that |
| 17:11 | TimMc | amalloy: The forms I'm looking to attach do all sorts of things: Logging, debug printlns, metrics, debug response headers... basically, I want to get all that crap out of the main control flow and logic. |
| 17:12 | amalloy | TimMc: it sounds kinda like you are looking for haskell's where instead of let? |
| 17:12 | TimMc | I know that dire does some of that, but it only applies at var boundaries. |
| 17:12 | TimMc | Tell me about this "where". |
| 17:12 | amalloy | TimMc: it's just a let with the bindings after their use instead of before it |
| 17:13 | TimMc | Nah, I want to be able to intercept values within an expression and have the intercept logic be all shoved down to the end of the fn. |
| 17:14 | hiredman | I do something like that in my raft implementation |
| 17:14 | amalloy | TimMc: but like, your example is just defining a function named † and calling it |
| 17:14 | hiredman | https://github.com/hiredman/raft/blob/master/src/com/manigfeald/raft/rules.clj#L101-L115 bindings at the end |
| 17:15 | amalloy | with the definition of † at the end of your "primary" function instead of at the beginning |
| 17:15 | TimMc | amalloy: Ah! The transformed version, yeah. |
| 17:15 | hiredman | oh, nope |
| 17:15 | hiredman | (I just saw "haskell's where") |
| 17:17 | TimMc | My coworkers might kill me if I put non-ASCII in our source files. |
| 17:17 | amalloy | as well they should |
| 17:18 | amalloy | they might symbolically leave a flaming 💩 on your doorstep |
| 17:19 | TimMc | hah |
| 17:19 | TimMc | Oh man, this looks so much nicer, though. |
| 17:19 | TimMc | (defmacro essentially [& args] `(let ~(last args) ~@(butlast args))) |
| 17:21 | TimMc | https://www.refheap.com/97879 so good |
| 17:21 | amalloy | TimMc: that is *definitely* just where |
| 17:21 | TimMc | yeah |
| 17:21 | amalloy | which is fine, where is cool |
| 17:21 | TimMc | I *could* do *1, *2, *3 and so forth, even though it shadows clojure.core stuff. |
| 17:22 | TimMc | Those don't get used in main source, right? And they're lexical, so there's not even a warning. |
| 17:22 | amalloy | you'd get a warning from eastwood |
| 17:22 | TimMc | What doesn't. |
| 17:52 | TimMc | amalloy: Not quite good enough, upon further reflection. This doesn't give me the ability to use the lexical scope of the places the spy expressions are referenced. What I really want to do is inject aspects... |
| 17:53 | TimMc | Am I reinventing Spring? Please tell me if I'm reinventing Spring. I don't want to be that kind of person. |
| 18:50 | crazydiamond | Hi. How to check what kind of value I'm dealing with? E.g. is it map, vector/list or scalar-like? I tried like (instance? (class {}) v), but failed 'cause (not= clojure.lang.PersistentHashMap clojure.lang.PersistentArrayMap) |
| 18:50 | justin_smith | crazydiamond: map? |
| 18:50 | justin_smith | ,(map? {}) |
| 18:50 | clojurebot | true |
| 18:50 | crazydiamond | yep :) |
| 18:50 | crazydiamond | thanks |
| 18:50 | amalloy | crazydiamond: but don't use list? |
| 18:51 | crazydiamond | amalloy, why? |
| 18:51 | justin_smith | ~list? |
| 18:51 | clojurebot | excusez-moi |
| 18:51 | amalloy | crazydiamond: seq? is a function that does what you actually *want* list? to do, whereas list? does something that is not useful |
| 18:51 | Bronsa | ,(list? (cons 1 nil)) |
| 18:51 | clojurebot | true |
| 18:51 | justin_smith | ,(list? (list 1 2 3)) |
| 18:51 | clojurebot | true |
| 18:51 | Bronsa | ,(list? (cons 1 ())) |
| 18:51 | clojurebot | false |
| 18:52 | crazydiamond | yep, I see |
| 18:52 | crazydiamond | ,(list? []) |
| 18:52 | clojurebot | false |
| 18:52 | crazydiamond | thanks! |
| 18:52 | aperiodic | ,(seq? []) |
| 18:52 | clojurebot | false |
| 18:52 | crazydiamond | oops |
| 18:52 | aperiodic | ,(sequential? []) |
| 18:52 | clojurebot | true |
| 18:52 | crazydiamond | :) |
| 18:52 | aperiodic | ,(sequential? (list 1 2 3)) |
| 18:52 | clojurebot | true |
| 18:53 | aperiodic | ,(sequential? (cons 1 nil)) |
| 18:53 | clojurebot | true |
| 18:54 | aperiodic | oh and also ##(vector? []) |
| 18:54 | lazybot | ⇒ true |
| 18:57 | aperiodic | crazydiamond: you should probably study the "type tests" subsection of the "collections" section of the clojure cheatsheet: http:///conj.io |
| 18:57 | crazydiamond | aperiodic, thanks. I believe I should study the whole |
| 19:39 | coventry | Does anyone here use scala with emacs? Does it have anything like cider? I've been playing with ensime, just started looking at sbt-mode. |
| 19:56 | jodaro | coventry: i think M-x sbt-start does something similar |
| 20:22 | crazydiamond | Hi. Is there shorter way to write (fn [x] x)? |
| 20:22 | justin_smith | #(do %) |
| 20:22 | crazydiamond | thx |
| 20:22 | crazydiamond | 'cause #(%) is trying to call the arg |
| 20:22 | justin_smith | of course you can always do (def i identity) and then just use i |
| 20:23 | justin_smith | right |
| 20:23 | amalloy | the shortest way to write something is not usually the best way |
| 20:23 | justin_smith | can't get shorter than a one letter function name |
| 20:23 | justin_smith | amalloy: excellent point |
| 20:23 | amalloy | justin_smith: new programming language: features 0-character identity function, implicitly added before every value |
| 20:24 | justin_smith | hahaha |
| 20:24 | amalloy | analysts amazed that this is indistinguishable from previous languages |
| 20:25 | justin_smith | oooh - you could define a unicode composing character, so when you call it on a value it shows up above or below the first letter of the arg, instead of as a separate word |
| 20:25 | crazydiamond | amalloy, well, in my case I asked that only for experiments in REPL |
| 20:25 | justin_smith | not that this would confuse anyone at all! |
| 20:26 | amalloy | justin_smith: ẍ is (identity x) in this groundbreaking new language |
| 20:28 | justin_smith | right |
| 20:29 | justin_smith | we could use the little tail that Spanish puts on the letter ç for deref (it would be a little tail on the first letter of the binding's name of course) |
| 20:29 | crazydiamond | if ẍ doesn't matter |
| 20:29 | crazydiamond | I mean, if ẍ is a funciton |
| 20:29 | crazydiamond | so x itself doesn't matter |
| 20:31 | amalloy | justin_smith: spanish doesn't use the cedille for anything, you're thinking of french |
| 20:32 | justin_smith | oops |
| 20:32 | amalloy | although apparently it used to, though |
| 20:32 | amalloy | calling it cedilla |
| 20:34 | justin_smith | ahh, used in Portugese too I see |
| 20:34 | justin_smith | I misremembered which one semester middle school foreign language class had introduced that letter |
| 20:34 | nuwanda_ | definitely portuguese too :p çç |
| 20:35 | rpaulo | yup.. |
| 20:36 | rpaulo | justin_smith: "used in Portuguese" is incorrect. It still uses it and will continue to use it for the foreseable future |
| 20:36 | rpaulo | justin_smith: ugh, I misread. |
| 20:36 | justin_smith | rpaulo: I meant the present case |
| 20:36 | justin_smith | it's OK |
| 20:37 | rpaulo | ? |
| 20:37 | rpaulo | looks like my IRC client can't even display it |
| 20:37 | justin_smith | doesn't send it it looks like |
| 20:38 | crazydiamond | ç |
| 20:38 | crazydiamond | äåéëþüúíóöáßðïœøæœ©®bñµç |
| 20:39 | crazydiamond | seems it's displaying fine |
| 20:39 | rpaulo | ç |
| 20:39 | rpaulo | ok, I was using the JIS encoding |
| 21:31 | codesine | Hi all, looking for guidance regarding ring or compojure. |
| 21:32 | codesine | I want to start with learning ring to do webapp development, and have been going through this resource: https://brehaut.net/blog/2011/ring_introduction |
| 21:32 | codesine | Are there any recommendations (possibly more up to date items?) |
| 21:33 | justin_smith | codesine: I don't see anything out of date there, anything else usually is built on ring |
| 21:33 | justin_smith | and a lot of people still use compojure |
| 21:33 | codesine | oh cool, so i can go by that |
| 21:33 | justin_smith | it's definitely a good starting point yeah |
| 21:34 | codesine | see I'm confused as to where ring and compojure stand, is ring just a third party library the same as compojure? |
| 21:34 | justin_smith | ring is an api that wraps various web servers with a common interface |
| 21:34 | justin_smith | compojure is a routing lib |
| 21:34 | codesine | ah got it |
| 21:34 | codesine | Yeah, I was looking at this luminusweb item, but, I get confused because it seems to be doing things for me |
| 21:35 | amalloy | codesine: but yes, it is also a third-party library, not associated with clojure the language |
| 21:35 | codesine | Ah ok. |
| 21:35 | justin_smith | people write various adaptors so that you can use eg. aleph, or jetty, or http-kit or tomcat but via the ring api |
| 21:35 | codesine | is there something in clojure core that does http serving etc? |
| 21:35 | justin_smith | no |
| 21:35 | codesine | ok gotcha both |
| 21:36 | justin_smith | codesine: since the jvm is so "batteries included" and there are so many libs for java that are easy to use via interop, clojure's core tends to be abstract stuff |
| 21:36 | codesine | ah |
| 21:36 | justin_smith | libs for specific pragmatic things will be adaptors or wrappers that are not part of hte core lang |
| 21:36 | justin_smith | typically at least |
| 21:36 | codesine | Yeah, see, I am worried to use luminusweb or compojure -- because I think that it will allow me to take things for granted |
| 21:37 | codesine | so it _is_ ok to start with ring, and do a pure web app in ring |
| 21:37 | justin_smith | so clojure.core is all about data types and protocols etc. |
| 21:37 | codesine | like a todo list to get my feet wet |
| 21:37 | justin_smith | right |
| 21:37 | justin_smith | I think that's a good idea |
| 21:37 | justin_smith | eventually how ring does things will matter |
| 21:37 | justin_smith | (unless you use one of those rare web libs for clojure that don't use ring) |
| 21:37 | codesine | yeah when i looked at the dependencies for luminus and compojure I made :/ face when it was a buncha libraries i'm not familiar with lol |
| 21:38 | codesine | ah |
| 21:38 | codesine | so i'm thinking if I were to do a todo list that would interface with mongodb |
| 21:38 | justin_smith | codesine: luminus is just making a bunch of good default library choices for you |
| 21:39 | codesine | I'd just need something like monger |
| 21:39 | codesine | and ring |
| 21:39 | codesine | and i can do sessions in ring anyways |
| 21:39 | justin_smith | sure |
| 21:39 | codesine | ok |
| 21:39 | codesine | nothing else i might need right? |
| 21:39 | codesine | I'm just not confident lol |
| 21:39 | justin_smith | but looking at the default luminus project.clj, there's nothing in there I have not had to use, and nothing I totally hated. So that's cool. |
| 21:39 | codesine | i will look at the dependencies, and learn some of them little by little |
| 21:40 | justin_smith | you can use monger and ring, sure. As long as you understand the pitfalls of mongodb of course :) |
| 21:40 | codesine | I've always used sql, i just finished one of the 10gen courses |
| 21:40 | codesine | lol |
| 21:40 | codesine | figured i might as well put myself out of my comfort zone |
| 21:40 | codesine | monger ring and selmer (: |
| 21:40 | justin_smith | codesine: after you get your bare bones server running, take a moment to look at the github project (at least the readme) for each luminus dep. They are all useful for a backend web stack. |
| 21:41 | justin_smith | for the bare bones you can even leave out selmer, but you still probably want compojure (or some routing lib) |
| 21:41 | justin_smith | unless you want a case statement with regexes and the :uri key of the request or something |
| 21:41 | codesine | in the lazy sequence blog it details how to do routing with ring |
| 21:41 | justin_smith | follow the guide from brehaut, it is decent |
| 21:42 | codesine | i figured i'll make it hard on me and do it manually from the request mapping |
| 21:42 | codesine | (< |
| 21:42 | justin_smith | codesine: that's not ring, that's compojure, from what I see |
| 21:42 | codesine | at the very top |
| 21:42 | codesine | it is ring |
| 21:42 | codesine | then he shows how to do mustache |
| 21:42 | codesine | and compojure |
| 21:43 | justin_smith | oh, OK, at the very very top |
| 21:43 | justin_smith | yeah, you are right |
| 21:43 | codesine | ya! |
| 21:43 | ob_ | i really enjoy sql for its proximity to the data. is clojure similar in that regard? |
| 21:43 | justin_smith | instead of his usage of moustache, you can swap in selmer |
| 21:44 | justin_smith | ob_: clojure has a very data-first philosophy yes |
| 21:44 | codesine | yeah i heard moustache wasn't used as much? |
| 21:44 | justin_smith | codesine: that may be the one out of date thing in this intro |
| 21:45 | codesine | yeah i'm gonna primarily use only the ring part, and do the routing myself for a learning experience (tedious, but just to instill it more firmly heh) |
| 21:45 | codesine | high5 justin_smith |
| 21:45 | justin_smith | best of luck, I do back end web stuff in clojure as my full time job, and I love it |
| 21:45 | justin_smith | it's a great stack |
| 21:45 | codesine | I do python and django, so i've been just spending 2 hrs a day trying to pick this up |
| 21:46 | codesine | I'm doing that there brave clojure tutorial |
| 21:46 | codesine | I do have the 2nd edition of joy of clojure |
| 21:46 | codesine | but it's over my head |
| 21:46 | justin_smith | I don't think many of the web-specific parts will be new or surprising if you do django already |
| 21:46 | codesine | D: |
| 21:46 | justin_smith | but have fun with the clojure stuff :) |
| 21:46 | codesine | oh and 4 clojure |
| 21:46 | justin_smith | yeah joy of clojure is not introductory level material for most people |
| 21:46 | codesine | thanks |
| 21:46 | codesine | i have the other 2 yr old book, clojureprogramming from oreilly |
| 21:47 | justin_smith | yeah, 4clojure is good too, especially if you look at solutions from more experienced users after you solve it yourself |
| 21:47 | codesine | but damn me if i can focus enough to read 600 pages |
| 21:47 | codesine | ya! |
| 21:47 | justin_smith | haha |
| 21:47 | codesine | exactly |
| 21:47 | codesine | there was some really terse solutions |
| 21:47 | codesine | then i realize |
| 21:47 | codesine | wtf |
| 21:47 | codesine | this is really short but unreadable |
| 21:47 | codesine | then i realized there is code golfing... |
| 21:47 | codesine | D: |
| 21:47 | justin_smith | well, a lot of it is more readable once you know the style / idioms |
| 21:47 | justin_smith | and yeah, some people are golfing (4 is a pun on fore) |
| 21:48 | codesine | haha |
| 21:48 | codesine | yeah i could understand it |
| 21:48 | codesine | but i realized, it was abusing a trick |
| 21:48 | codesine | to be shorter |
| 21:48 | amalloy | justin_smith: the name 4clojure is totally not related to the fore in golf |
| 21:48 | justin_smith | oh? never mind then |
| 21:48 | amalloy | i've never heard anyone make that connection before, actually |
| 21:48 | justin_smith | I totally thought it was a pun |
| 21:48 | codesine | no i think he means |
| 21:48 | amalloy | justin_smith: it's a pun on foreclosure |
| 21:48 | codesine | 4 as a pun on fore |
| 21:49 | codesine | read 4clojure as foreclosure |
| 21:49 | codesine | foreclosure on a home lol |
| 21:49 | justin_smith | right |
| 21:49 | amalloy | but the golfing features were added later on, by a different person than the one who named the site |
| 21:49 | codesine | it's cool some solutions of people i follow (those who answered all 156 questions) |
| 21:49 | codesine | code how i think |
| 21:52 | bashed | Is it possible to import a java class without loading it? It seems like clojure does that. I need to reference some java classes that depend on that. |
| 21:53 | codesine | I'm a clojure beginner but I think (require) does that |
| 21:53 | codesine | maybe someone else can correct me if i'm wrong |
| 21:53 | justin_smith | codesine: require is for namespaces / clojure code |
| 21:53 | amalloy | no, that is not consistent with how classloaders on the jvm work |
| 21:53 | codesine | ohh... so i'm wrong |
| 21:53 | codesine | idk bashed, justin prob knows (< |
| 21:54 | justin_smith | codesine: import is for jvm level classes (usually java code, but maybe also a record or deftype sometimes) |
| 21:54 | justin_smith | or amalloy :) |
| 21:54 | codesine | oh ok, so i'll use import if i ever want to do what bashed does |
| 21:54 | justin_smith | amalloy: is there a behavioral difference between using import or not using import and just using the fully qualified package name? |
| 21:55 | amalloy | justin_smith: no |
| 21:55 | justin_smith | that's what I thought, just double checking |
| 21:55 | justin_smith | amalloy: does referencing a class in a function that gets compiled force some initialization then? |
| 21:56 | amalloy | justin_smith: it causes the class to be loaded when the function is compiled (if it wasn't loaded already), which runs the class's static initializers |
| 21:57 | justin_smith | aha, yeah, I can see where that would be an issue for badly designed classes |
| 21:58 | codesine | I wonder if it's advisable to make an attempt to read o'reilly's clojure programming back to back with coffee as fuel (: |
| 21:58 | justin_smith | you'd probably learn more if you went slower and did things in the repl to test what you think you are learning |
| 21:59 | codesine | yeah i've done it with clojure for the brave and true |
| 21:59 | codesine | just hand typed everything |
| 21:59 | justin_smith | clojure is very repl freindly - more than most languages the interaction in the repl really follows all the same rules as code in files |
| 21:59 | codesine | ok thx for everything |
| 21:59 | codesine | i'll try to be a regular here from now on xD |
| 21:59 | hiredman | http://dev.clojure.org/jira/browse/CLJ-1315 |
| 22:00 | codesine | i just discovered (clojure.walk/macroexpand-all) |
| 22:00 | codesine | this helped me with some questions i had in my head |
| 22:00 | justin_smith | that's a helpful one |
| 22:01 | codesine | how'd you start when you were a clojure padawan |
| 22:01 | codesine | since you do it for work now |
| 22:01 | justin_smith | me? I got hired because an old friend knew I was into FP. |
| 22:01 | justin_smith | and I learned it on the job. |
| 22:01 | codesine | come to think of it for every language i've learned i've never read a book front to back |
| 22:01 | justin_smith | I was mostly using OCaml and Scheme until I got hired |
| 22:01 | codesine | scheme is cool |
| 22:01 | justin_smith | indeed |
| 22:02 | codesine | esp that gambit scheme |
| 22:02 | justin_smith | ml and scheme turned out to be a great combo of things to make learning clojure easier |
| 22:03 | justin_smith | the jvm part took me longest |
| 22:03 | codesine | -_-;;;;;; i started with ansi c and then python |
| 22:03 | codesine | i never learned java tho |
| 22:03 | codesine | i can use the interop with just googling so not worried -- mostly just interested in idiomatic clojure stuff |
| 22:03 | justin_smith | but with some c and python experience, at least the javadoc for the included libs with the jvm should be readable |
| 22:03 | codesine | so this stuff really busts my head |
| 22:03 | codesine | yeah |
| 22:04 | justin_smith | for idiomatic clojure, another thing is to read code by people who know the language well |
| 22:04 | codesine | i take peek at random github repositories and try to understand what i can or the solutions on 4clojure |
| 22:05 | justin_smith | amalloy_: (for example the flatland/useful lib) or seancorfield (who also hangs out here, he works on clojure.java.jdbc among others), stuartsierra |
| 22:05 | justin_smith | sorry, didn't mean to tag amalloy_ there, just listing him as someone with good code to read |
| 22:05 | codesine | i've saved this irc buffer so i don't lose anything |
| 22:06 | justin_smith | hiredman also has some good stuff on github to learn from |
| 22:06 | justin_smith | heh |
| 22:06 | justin_smith | (I've definitely been there) |
| 22:06 | codesine | where i'm at? nonsense |
| 22:06 | justin_smith | codesine: getting suggestions and then just deciding to save the whole irc transcript to go through later? yeah, done that a few times |
| 22:07 | codesine | this is the second time i've used irc, never realized it was so helpful, this is not clojure related but if it'sok to ask, irc just let's you key in a handle and it joins the room with the handle, what's to keep another person from logging in with your name |
| 22:07 | codesine | yeah, in another saved buffer in emacs heh |
| 22:07 | justin_smith | codesine: register with nickserv |
| 22:08 | codesine | kk |
| 22:08 | codesine | ty |
| 22:08 | justin_smith | via nickserv you can boot someone using your handle without permission |
| 22:08 | justin_smith | and people can check if you are registered with nickserv (though how often someone actually does that is another question) |
| 22:09 | codesine | i've just registered |
| 22:09 | justin_smith | codesine: another caveat about that brehaut article - I wouldn't use Korma or ClojureQL |
| 22:10 | codesine | kk |
| 22:10 | codesine | oh crap forms and sessions |
| 22:10 | codesine | i'll figure it out (will prob check luminus dependencies and learn one of those) |
| 22:11 | codesine | ok going to study some more now |
| 22:11 | codesine | *waves all* |
| 22:11 | justin_smith | oh, haha, luminus uses korma. I mean it's not totally terrible, but... |
| 22:11 | codesine | i don't wanna use korma |
| 22:11 | codesine | i just wanna use mongodb |
| 22:11 | codesine | prob that monger thing |
| 22:12 | codesine | do you have a recommendation for postgres then? |
| 22:12 | justin_smith | I like yesql but have not used it in anger |
| 22:12 | justin_smith | it compiles regular sql files into clojure code you can call |
| 22:12 | justin_smith | clojure.java.jdbc is totally usable |
| 22:13 | codesine | justin_smith: got it -- bbl and thanks for all |