2015-09-12
| 00:17 | kavkaz | justin_smith: Ah flyspell-popup is nice, I like it, thanks |
| 00:18 | kavkaz | good for the markdown side of my emacs usage |
| 00:20 | kavkaz | Is it okay to shadow the top-level parameter name with a parameter name in a letfn function definition? Given that they both refer to the same variable of course |
| 00:27 | mungojelly | is the clojure grammar too simple for anyone to have bothered saying it as BNF? i like BNF i'd like to see it just to make sure i'm not missing anything |
| 00:35 | mungojelly | here it is in ANTLR https://github.com/antlr/grammars-v4/blob/master/clojure/Clojure.g4 so i guess i'm satisfied :) |
| 03:52 | felipedvorak | So I have finally succeeded in answering Project Euler problem number 1 with Clojure, but now I was wondering if someone could read the code and criticize it for me. I'm worried if this is functional or not, and if the solution is too bizare. |
| 03:52 | felipedvorak | http://pastebin.com/rYZb8mVT |
| 03:53 | felipedvorak | You must get a sum of the numbers below 1000 that are divisible by 3 or 5. |
| 03:53 | felipedvorak | sorry someo*one but you probably have alerts turned off anyway... |
| 03:54 | kungi | felipedvorak: I can help you a little |
| 03:55 | kungi | ,(reduce + [1 2 3 4]) |
| 03:55 | clojurebot | 10 |
| 03:55 | felipedvorak | kungi: thanks |
| 03:55 | kungi | felipedvorak: you can use + directly in your reduce |
| 03:55 | felipedvorak | wow, I tried that but somehow it didn't work :/ |
| 03:55 | felipedvorak | but I had some problems with paredit earlier, it may be that it was the culprit of the errors |
| 03:56 | kungi | felipedvorak: yes paredit can be a huge problem first |
| 03:56 | kungi | felipedvorak: why does create-range have to return a vector? |
| 03:57 | felipedvorak | kungi: don't know hauhauh |
| 03:57 | felipedvorak | I'm with the impression vectors are more consistent |
| 03:57 | kungi | felipedvorak: consistent? |
| 03:58 | kungi | felipedvorak: instead of (reduce + [1 2 3]) you can also write (apply + [1 2 3]) |
| 03:58 | kungi | felipedvorak: then you don't need the 0 |
| 03:58 | felipedvorak | wow, apply is new to me! |
| 03:58 | kungi | ,(apply + [1 2 3]) |
| 03:58 | clojurebot | 6 |
| 03:59 | felipedvorak | the 0? |
| 03:59 | kungi | felipedvorak: (reduce + _0_ list) |
| 03:59 | felipedvorak | alright! |
| 04:00 | justin_smith | kungi: you don't need the 0 anyway |
| 04:00 | justin_smith | ,(reduce + [1 2 3]) |
| 04:00 | clojurebot | 6 |
| 04:00 | felipedvorak | justin_smith: Yeah, this is something I just realized, I'm always using reduce with an entry value when its not needed |
| 04:01 | justin_smith | felipedvorak: well, better to supply a non-needed initial value than not provide one when needed |
| 04:01 | kungi | I just found my first real world usage of `tree-seq` |
| 04:03 | felipedvorak | kungi: the overall code, you would call this usable in the real world? the structure? sorry, I'm new to programming AND to functional, so I'm a bit (lot) confused hehe |
| 04:04 | kungi | felipedvorak: I would extract the (if (or (mod ... into its own predicate function `mod-3-5?` |
| 04:04 | felipedvorak | hmm |
| 04:05 | felipedvorak | very nice |
| 04:05 | kungi | felipedvorak: And I would use a precondition in add-all-odd to check for the vector instead of using a comment |
| 04:05 | felipedvorak | I still don't know how to do that :) |
| 04:05 | kungi | felipedvorak: And btw. It does not expect a vector. |
| 04:06 | felipedvorak | vector? perhaps hehe |
| 04:06 | felipedvorak | kungi: I see, I'm removing this malformed mental constructo about vectors from my mind immediately. |
| 04:06 | kungi | felipedvorak: let me write it and show you my solution |
| 04:07 | felipedvorak | great |
| 04:08 | kungi | felipedvorak: solution is 233168? |
| 04:08 | felipedvorak | yeah |
| 04:08 | felipedvorak | hehehe |
| 04:09 | kungi | (defn mod-3-5? [x] (or (= (mod x 3) 0) |
| 04:09 | kungi | (= (mod x 5) 0))) |
| 04:09 | kungi | (apply + (filter mod-3-5? (range 1000))) |
| 04:09 | felipedvorak | ok |
| 04:10 | felipedvorak | hehe still a lot to learn :) |
| 04:10 | justin_smith | kungi: use (zero? (mod x y)) |
| 04:10 | kungi | justin_smith: yes |
| 04:10 | kungi | stull a lot to learn :) |
| 04:11 | justin_smith | that's why we are all here, even me believe it or not |
| 04:12 | felipedvorak | thanks both of you! :) 5am, my clojure addiction must come to an end for today |
| 04:13 | kungi | felipedvorak: good night :-) |
| 04:24 | expez | (defn bar [baz] (foo!)), should bar really be bar!? |
| 04:25 | kungi | expez: What are you trying to communicate? -:) |
| 04:25 | expez | kungi: is the bang naming convention transitive? |
| 04:26 | kungi | expez: in my opinion yes it is |
| 04:26 | expez | Or rather, I often see in the wild that it is not, but should it be? |
| 04:26 | kungi | expez: Hmm no wait .... it depends |
| 04:27 | kungi | expez: If you properly hide your impurity in a function then ! may not be transitive |
| 04:27 | clojurebot | excusez-moi |
| 04:28 | justin_smith | kungi: except in clojure.core ! often means not safe in a transaction, and unless you do some intense defensive programming that will be transitive |
| 04:28 | justin_smith | eg. because it combines retries and side effects |
| 04:38 | justin_smith | (doc io!) |
| 04:39 | clojurebot | "([& body]); If an io! block occurs in a transaction, throws an IllegalStateException, else runs body in an implicit do. If the first expression in body is a literal string, will use that as the exception message." |
| 04:55 | amalloy | i don't think transitive is the right word for that |
| 04:55 | amalloy | contagious would be my choice |
| 04:58 | justin_smith | "the flu is a transitive property of humans" |
| 05:03 | amalloy | yes indeed, for any three humans a, b, c, if a flu b and b flu c, then a flu c |
| 05:04 | amalloy | today's achievements: make flu into a verb |
| 05:04 | justin_smith | heh |
| 05:04 | sobel | nomenclature question: if a function has a remote side-effect (e.g. sftp cwd) should it end in ! |
| 05:05 | sobel | or is that more aimed at namespaced vars |
| 05:05 | justin_smith | sobel: I'd say it's safe to skip if it's idempotent, but usually yes it should |
| 05:05 | sobel | hmmm. i like that. |
| 05:05 | justin_smith | sobel: my rule of thumb is "what if someone used the function inside a swap! call and it was done 50 times in a row" |
| 05:05 | justin_smith | would that suck? if so, use !, if it wouldn't matter, no |
| 05:06 | sobel | seems sensible enough. |
| 05:06 | justin_smith | sobel: not that I always follow this advice (handler code is especially egregious here in my codebases) |
| 05:06 | sobel | it's side-effect grey area |
| 05:07 | justin_smith | the kind of bug that's been haunting us lately is double transmits on a websocket in a react app |
| 05:07 | justin_smith | like - sometimes the server gets two requests and it should have gotten one |
| 05:08 | justin_smith | not all our request handlers listening on the websocket are idempotent, so we get weird ass bugs (many coming from weirdness in react it seems (probably because misusing react)) |
| 05:08 | justin_smith | I would just debounce server side, but that only handles the symptom (and increases latency) |
| 05:08 | sobel | i hear that |
| 05:10 | justin_smith | it appears one bug was being caused by a side-effecting button that was acting like an innocent link, so that a pop-up preview caused a double-trigger of the event (maybe) |
| 05:10 | justin_smith | or, I should say "css magic tried to make an innocent link be a side effecting button" |
| 05:11 | amalloy | debounce? is that a common term? |
| 05:11 | sobel | yes |
| 05:12 | justin_smith | amalloy: it is a way to turn sputtering event clusters into a single event, comes from analog electronics, where a switch will literally bounce |
| 05:12 | amalloy | i feel like i've heard it in a past life, and can infer meaning from context, but have no real idea how i would have learned it |
| 05:12 | justin_smith | rebound |
| 05:12 | sobel | yes, it is literally slew-rate limiting |
| 05:12 | amalloy | slew-rate! it's like i have suddenly forgotten how to understand english |
| 05:13 | justin_smith | it's also closely related to how things like double-click are possible (if not technically used) |
| 05:13 | justin_smith | second event during bounce period = this is a double click |
| 05:14 | justin_smith | (also check for confounding parameters like x/y motion that would counterindicate, of course) |
| 05:15 | sobel | so idempotent handlers would prevent the 'bouncing' in the first place |
| 05:15 | justin_smith | right, but some of our handlers create resources for the client, this isn't negotiable |
| 05:15 | justin_smith | also, some idempotent actions are CPU expensive, so triggering twice is bad |
| 05:16 | sobel | so, can't that still be faux-idempotent (create-or-ignore) |
| 05:16 | justin_smith | I was also tempted to invent a higher order function that would return "your function, but refuses to run a second time". I could even abuse memoize for this if I was feeling dirty. But this also only fixes the symptom. |
| 05:16 | sobel | yeah, i wasn't quite clear how memoize wouldn't work |
| 05:16 | TEttinger | runonce to parallel defonce, justin_smith? |
| 05:17 | TEttinger | both rhyming with Beyonce |
| 05:17 | justin_smith | sobel: they are allowed to create two resources with the same parameters, it's a time-dependent thing - it's just that if the amount of time is under 5 seconds they won't get an interesting result |
| 05:17 | justin_smith | TEttinger: haha, awesome idea |
| 05:19 | justin_smith | (defn runoncé [f] ...) |
| 05:19 | sobel | (inc justin_smith) |
| 05:19 | sobel | ,(inc justin_smith) |
| 05:19 | clojurebot | #error {\n :cause "Unable to resolve symbol: justin_smith in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:... |
| 05:20 | sobel | ok |
| 05:20 | justin_smith | sobel: the first one was right, but lazybot is on vacation I guess |
| 05:20 | sobel | clearly |
| 05:21 | sobel | i like the fn, defoncé |
| 05:24 | sobel | (def Brawndo™ [] (basically-mtn-dew) ) |
| 05:24 | sobel | yes, unicode makes programming fun |
| 05:26 | sobel | 🐙 |
| 05:44 | TEttinger | sobel: unicode is fun |
| 05:44 | TEttinger | ,(def def "Pfft, can't take the value of a macro, eh?") |
| 05:44 | clojurebot | #'sandbox/def |
| 05:45 | TEttinger | ,def |
| 05:45 | clojurebot | "Pfft, can't take the value of a macro, eh?" |
| 05:45 | justin_smith | ,(macro? def) |
| 05:45 | clojurebot | #error {\n :cause "Unable to resolve symbol: macro? in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: macro? in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: macro? in t... |
| 05:45 | justin_smith | ,(:macro (meta #'def)) |
| 05:45 | clojurebot | #error {\n :cause "Unable to resolve var: def in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve var: def in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve var: def in this context"\n ... |
| 05:45 | TEttinger | fine special form |
| 05:45 | justin_smith | haha |
| 05:46 | TEttinger | ,(map def '(a b c) [1 2 3]) |
| 05:46 | clojurebot | #error {\n :cause "Unable to resolve symbol: def in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: def in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: def in this conte... |
| 06:25 | noncom|2 | i am thinking about hosting a webserver written in clojure with the frontend written in clojurescript somewhere. the service is a CRM-like thing, i am wondering, what minimal and what recommended machine specs are? |
| 06:25 | noncom|2 | in particular, how much RAM do I need for that? |
| 06:25 | noncom|2 | no huge load is planned, just some document office work |
| 06:33 | wink | noncom|2: I've successfully hosted a soup clone in pure clojure on a 5$ digitalocean box (incl. postgres) |
| 06:34 | wink | noncom|2: sooo... I wouldn't go lower :) but should be enough for a first shot |
| 06:34 | noncom|2 | very nice! |
| 06:35 | wink | I think it will depend on your concurrent users as well |
| 06:35 | noncom|2 | well, for the moment there'll be no more than 100 users with occasional access to forms and documents, so should be ok. 512 or 1024 ram will do then |
| 06:35 | noncom|2 | btw what is soup? :_ |
| 06:36 | noncom|2 | :) |
| 06:36 | wink | soup.io - a microblog with some social functions |
| 06:36 | wink | mostly posting pictures |
| 06:36 | noncom|2 | ah, i see |
| 06:38 | noncom|2 | cool! |
| 06:39 | noncom|2 | wink: btw, have you used hoplon? |
| 06:39 | wink | never even heard that |
| 06:39 | noncom|2 | i'm just picking the framework for now |
| 06:40 | noncom|2 | i worked with luminus, and there's also hoplon.. |
| 06:40 | noncom|2 | so will try hoplon too then |
| 06:41 | wink | I've also mostly used luminus |
| 06:41 | wink | and somethin before that... |
| 06:42 | wink | noir |
| 06:42 | noncom|2 | yeah, noir is deprecated now. luminus builds on the best remaining parts of noir, compojure and stuff |
| 06:42 | noncom|2 | hoplon is more innovative, but idk is it all good or bad or just different |
| 06:43 | noncom|2 | for now it looks very cool, but different |
| 06:43 | noncom|2 | sometimes it is hard to choose between two techologies esp if you see no clear difference between them unless you've made a big project to feel it all through |
| 06:49 | wink | hehe |
| 06:49 | wink | sounds like our rewrite from ember to angular |
| 06:50 | wink | I'm only playing around with clojure web apps, nothing serious |
| 06:50 | wink | so far luminus was fine |
| 06:50 | noncom|2 | yeah, me the same :D |
| 06:50 | wink | and unlike with noir (when it got deprecated) I don't see a good reason to change anything even if it might be a lot better |
| 06:51 | wink | that said, the time will come when I am nosy enough to try my 30th web framework |
| 06:51 | wink | still havent used a rust one for example :) |
| 06:52 | noncom|2 | i did not use any rust even at all yet |
| 06:52 | noncom|2 | tried go though, liked it, but i have no real tasks for that |
| 06:52 | noncom|2 | besides, getting off a lisp is hard.. :/ |
| 06:52 | wink | yeah I needed a small windows gui for ffmpeg |
| 06:53 | wink | that's where I had my problem to solve |
| 06:53 | noncom|2 | haha, i worked with ffmpeg through java-cv, so i was able to do it in clojure :D |
| 06:53 | noncom|2 | java-cv is cool |
| 06:54 | noncom|2 | thanks for the info! gotta go now, cheers! :) |
| 06:54 | wink | bye |
| 07:45 | crocket | hi |
| 07:45 | crocket | Is there an alternative to datomic? |
| 07:48 | ianhedoesit | https://github.com/tonsky/datascript |
| 07:53 | muhuk | it's in-memory only AFAIK. |
| 07:56 | msw | Is there a quick (clj) repl command to check in which protocol(s) a given method (say .. toString) is (potentially) defined? |
| 07:57 | Bronsa | msw: toString is not a protocol method |
| 07:58 | Bronsa | msw: for actual protocol methods, (:protocol (meta #'proto-method)) |
| 07:58 | crocket | datascript is not an alternative to datomic. |
| 07:59 | ianhedoesit | that's the closest I'm aware of |
| 08:01 | msw | I see, thanks Bronsa. |
| 08:09 | Bronsa | woah datascript now supports clojure too, neat |
| 08:25 | crocket | What makes datomic special? |
| 08:27 | muhuk | crocket: special in what way? |
| 08:27 | crocket | I don't know |
| 10:05 | blucas | %n |
| 10:23 | tmtwd | how do I empty a whole channel in core async? |
| 11:50 | justin_smith | tmtwd: keep reading until you can't read any more in a loop? |
| 11:52 | mungojelly | is that really the idiom? i too was wondering if i should say like take-all or something |
| 11:54 | mungojelly | btw i'm running that ants.clj from rich's talk "clojure for java developers" or w/e that's one of the most popular talks on clojure, this is an awesome toy, someone should have linked me to this when i asked, this looks fun |
| 12:08 | expez | 1.7 is such a breaking change it's not even funny |
| 12:08 | expez | Even library author now rewriting their libraries to use reader conditionals effectively forcing all consumers to also run 1.7 if they want patches |
| 12:08 | expez | Every* |
| 12:10 | Bronsa | expez: 1.7 is a breaking change? |
| 12:10 | expez | Is there any reason at all to ship cljc files to the consumer over two platform specific files? |
| 12:10 | expez | Bronsa: effectively yeah |
| 12:11 | Bronsa | expez: every release has had additional features over the previous ones, what's special about 1.7? |
| 12:12 | expez | Bronsa: I suppose the previous releases were nice to haves, but a lot of people seem to think cljc is essential. |
| 12:13 | expez | I get the allure of only maintaining a single file, but that should be an implementation detail and I'd prefer if people still shipped clj and cljs files :/ |
| 12:14 | Bronsa | cljc *is* essential if you want to use reader conditionals |
| 12:15 | expez | obviously? |
| 12:16 | expez | You don't *have* to write your library with reader conditionals, though. And if you do I'd prefer if you processed those files as part of deployment and also shipped platform specific files so I don't have to upgrade to 1.7 to receive patches! |
| 12:16 | justin_smith | expez: why can't you use 1.7? |
| 12:17 | expez | justin_smith: *I* can, but I don't want to force everyone using CIDER and clj-refactor to use 1.7 :/ |
| 12:17 | Bronsa | expez: oh come on, having to maintain both a clj and a cljs version of a library is *so much worse* than using reader conditionals |
| 12:18 | expez | Bronsa: Sure, but you can process those files and put the clj and cljs files in the jar along with the cljc file... |
| 12:19 | Bronsa | expez: that's what people did with cljx before clojure had native support for reader conditionals |
| 12:20 | expez | Guess I'm done here if nobody sees a problem |
| 12:20 | expez | Just needed to vent |
| 12:20 | Bronsa | expez: why can't cider/clj-refactor just process the cljc files internally to strip the reader conditionals? |
| 12:21 | kavkaz | How come the REPL is not letting me do (map Integer/parseInt <some-seq>) but it lets me do (map #(Integer/parseInt %) <some-seq>) |
| 12:21 | kavkaz | ? |
| 12:21 | justin_smith | kavkaz: methods are not first class |
| 12:23 | kavkaz | justin_smith: So it's not a function object? |
| 12:23 | kavkaz | like (fn []), (defn [] ...) or #() |
| 12:23 | justin_smith | no, Integer/parseInt is a static method |
| 12:24 | justin_smith | another way to put it is that functions are objects, Integer/parseInt is not an object |
| 12:24 | kavkaz | justin_smith: Oh i see |
| 12:24 | kavkaz | Now that I think about it from a Java perspective |
| 12:27 | justin_smith | kavkaz: and since a static method is not itself a class, it isn't actually a thing that you can place on a call stack - in order to do so, clojure would have to implicitly create the anonymous function version for you |
| 12:28 | justin_smith | *not itself an object* - sorry |
| 13:43 | Narfinger | hiho, i am just starting out to learn clojure and i wonder if there is a similar library for xml parsing as hxt for haskell |
| 13:43 | Narfinger | for anybody who does not know, you basically define your structure of elements and it does the reading and writing according to the structure |
| 13:53 | justin_smith | Narfinger: we don't actually need something that strict, since we don't have Haskell's type system |
| 13:53 | justin_smith | Narfinger: not to say it doesn't exist - it might, but there is less motivation |
| 14:06 | justin_smith | Narfinger: if your data source is actual XML, clojure.data.xml might work (though it does have its limitations related to namespaces iirc) |
| 14:14 | noncom|2 | justin_smith: once you said "i prefer websockets where available" - so, where are they not yet available? |
| 14:14 | Narfinger | ok i will look around thanks |
| 14:17 | justin_smith | noncom|2: some http servers / some clients, depends on what you are required to deploy to / support |
| 14:18 | justin_smith | noncom|2: though sente has a nice feature where it works with a post based fallback if websockets are not supported client side |
| 14:19 | noncom|2 | but all general browsers do have support... i just wander, what a client today would not support it.. but i think i'm not gonna get in this situation... |
| 14:19 | justin_smith | noncom|2: http://caniuse.com/#feat=websockets |
| 14:20 | justin_smith | so unless you need to support android 4.3 or ie 9, you are probably good? |
| 14:21 | noncom|2 | justin_smith: wow, that was exactly what i was looking for! |
| 14:21 | noncom|2 | thanks! |
| 14:33 | mungojelly | -> and ->> are fun but also they seem random, it seems like semantics is given sometimes to the positions to try to unrandomify it with partial success, i thought of maybe something that threads through maps by key or something so it could be more explicitly semantic |
| 14:34 | noncom|2 | mungojelly: they are not random in any degree |
| 14:34 | noncom|2 | mungojelly: what is your original task? |
| 14:34 | noncom|2 | mungojelly: maybe you're looking for get-in? |
| 14:34 | mungojelly | noncom|2: hm? i'm just learning clojure. what i mean is that you're threading through the first/last argument, which gives those positions special powers |
| 14:35 | justin_smith | mungojelly: you can use ->> inside -> |
| 14:35 | justin_smith | and if you need a position that isn't first or last, you can use as-> inside -> |
| 14:35 | mungojelly | which is almost like having a semantics, and then there's things like um, the sequences it said somewhere are all sequence last, so then that approaches semantic order to it so you can thread through the last which happens to be a sequence, yay |
| 14:35 | mungojelly | oh cool i don't know as-> yet what's that? |
| 14:35 | oddcully | ,(doc as->) |
| 14:35 | justin_smith | ,(-> 1 inc (-> as n (* n n))) |
| 14:35 | clojurebot | "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form." |
| 14:35 | clojurebot | #error {\n :cause "Unable to resolve symbol: n in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: n in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: n in this context"\n ... |
| 14:36 | justin_smith | ,(-> 1 inc (as-> n (* n n))) |
| 14:36 | clojurebot | 4 |
| 14:36 | justin_smith | ,(-> 1 inc (as-> n (* n n) (inc n))) |
| 14:36 | clojurebot | 5 |
| 14:37 | mungojelly | so -> threads at the beginning, ->> at the end, and as-> in the middle, it's beautiful, i'm not saying it's not beautiful |
| 14:37 | mungojelly | but also you're like manually building something, i'd rather they were more like magic magnetic connectors and you wave them at one another and they fall in line good |
| 14:37 | noncom|2 | mungojelly: correction: -> threads at the second place |
| 14:38 | noncom|2 | mungojelly: well, these are core macros and are intended to be very simple |
| 14:38 | oddcully | as-> with the varname/position as you like (not only once, not only in the middle) |
| 14:38 | noncom|2 | mungojelly: also, take a look at the swiss arrows clojure library :) |
| 14:39 | noncom|2 | mungojelly: the core functions/macros must not have magic. they all have very simple meanings. magic can be created in libraries |
| 14:40 | mungojelly | ha well this is all very magic to most programmers still but i do think i see what you mean |
| 14:40 | noncom|2 | mungojelly: also, in most cases it is sufficient to use just -> or ->> or, rarely, their combination, as justin points out |
| 14:41 | mungojelly | are you saying you don't like my idea :p |
| 14:41 | noncom|2 | mungojelly: if you find yourself in need of more, it can be a sign that you need a (let) form with clearly labeled subresults |
| 14:41 | noncom|2 | mungojelly: nono, it's not that i don't like the idea |
| 14:41 | mungojelly | i want to thread semantically too, if the things i'm threading through have arguments with semantic names and i can say "thread through the :foo arguments" then i can take a random collection of stuff and throw it together more carelessly |
| 14:43 | mungojelly | or like you could take the same chains and thread them through various ways, like what are the chances a chain that works with -> is also going to work with ->> because it's haphazard but if they had semantically marked arguments they could easily happen to work with multiple ones |
| 14:43 | mungojelly | maybe i'm just talking about monads again idk |
| 14:44 | noncom|2 | mungojelly: yes, this looks like modals, and you could have such functionality here, but really, it is far from basic |
| 14:44 | noncom|2 | mungojelly: it is not always clear for the compiler, what do you really want to do and when it should signal you an error |
| 14:45 | noncom|2 | mungojelly: with that much guessing it can quickly break things |
| 14:45 | noncom|2 | since lisp is very fluid |
| 14:45 | noncom|2 | mungojelly: here's what - why don't you try to write such a macros youself? |
| 14:46 | mungojelly | well because i just learned clojure's macros yesterday, i suppose. i made a few simple things and it went fine as soon as i got used to all this # business. ;) |
| 14:47 | noncom|2 | mungojelly: actually, in the end you may come up with a pretty useful library, that's serious and a good excercise |
| 14:47 | noncom|2 | congrats with learning the stuff :) |
| 14:48 | mungojelly | here's something i'm thinking of writing, i want an abstraction that's a grid of tiles, like the tiles each know how to draw themselves and there's a display context that asks the tiles in its field of view to draw themselves, etc |
| 14:48 | mungojelly | is there something like that already, a generic tiles interface? |
| 14:50 | mungojelly | it seems to me like that would be a friendly context for beginners to start making things in, because they just need to make a few tiles that know how to be tiles, and then ideally there'd be various pretty viewers and tools that they're compatible with |
| 14:50 | noncom|2 | mungojelly: never heard of such a thing. how are you going to draw them, what graphics api to use? or you mean just data rendering of an n-dimensional grid? |
| 14:50 | mungojelly | there's a zillion games written with tiling systems but none of the ones i've read yet have the tiles written as a separate abstraction :( |
| 14:51 | mungojelly | noncom|2: weeeeeeeeell i could target a particular graphics api, or i could target some intermediate abstraction, what do you think would be useful?? |
| 14:51 | mungojelly | like they could just say a list of polygons to paint on their tile, and then various viewers could translate that into various graphics apis |
| 14:51 | noncom|2 | mungojelly: ah, i see. yep, you could very well do that. i would ofcourse decouple data rendering from the drawing api. and for the draving api in your particular case i'd pick the quil library that bases over processing |
| 14:52 | mungojelly | i saw something about quil and it looked awesome but i haven't tried it yet |
| 14:53 | mungojelly | one way i think would make sense to do it is to have tiles that know how to draw themselves in a zillion different ways, like they can make a tiny little version of themselves for zoomed out views, and say how to paint themselves as ascii, etc |
| 14:54 | noncom|2 | quil is a very simple, friendly and powerful tool that will let you do things reaaaally quick without boring stuff. then, when you have your engine functional, you can plug in other renderers |
| 14:54 | mungojelly | then if you make a tile set that implements all the different ways of viewing it you can view the same game made with those tiles through all those lenses |
| 14:54 | noncom|2 | mungojelly: interesting |
| 14:57 | noncom|2 | mungojelly: with that idea you could create tiles described by a certain dsl with symbols that draw themselved in various ways |
| 14:58 | mungojelly | i'd think of implementing that like tiles are a map with :ascii goes to a function that paints the ascii, etc., so like {:ascii paint-ascii :polygons paint-polygons} is that clojurey |
| 14:58 | noncom|2 | you mean ascii and polygons are two different renderers? |
| 14:58 | noncom|2 | well, it's not about clojure i think, its about the concept more |
| 14:59 | noncom|2 | i think more clojuric and functional would be to have a single language (a DSL) to describe a tile and then have interpreters of that DSL for every renderer |
| 15:00 | mungojelly | i was wondering earlier in general, is that what you do in clojure is fill data structures with functions you want to use, i thought of putting fields in my things and tucking functions into them but maybe i'm just messily recreating some object system i should use? |
| 15:01 | noncom|2 | mungojelly: hm, you could have functions stored in datastructs if you need that. but i am not sure about your specific cases. when i started clojure i was constantly finding myself recreating OOP |
| 15:01 | noncom|2 | after a period it gone, OOP and clojure (FP that it is) got separated completely, not i can use them independetly |
| 15:02 | noncom|2 | s/not/now |
| 15:02 | mungojelly | well i mean the dsl is that there's tiles with attributes, so not much to it, {:name "I'm a happy tile!" :tiny-ascii "***\n*!*\n***\n"} etc, but then i think of tucking code(-like data) into them somewhere to make them pop |
| 15:02 | noncom|2 | mungojelly: having fns in datastructs is perfectly fine if you really need this |
| 15:03 | noncom|2 | mungojelly: if you're asking about having a function stored within it to render it like ((:renderer tile) (:data tile)) then that's recreating OOP :) |
| 15:04 | noncom|2 | is this what you mean? |
| 15:04 | justin_smith | yeah, you don't need to recreate OOP in clojure, we've got protocols/records/multimethods for this |
| 15:04 | justin_smith | actual OOP! |
| 15:05 | noncom|2 | yeah, and even going futher than justin is saying, i almost never use protocols/records/multimethods in my programs :D so i went even that far |
| 15:05 | mungojelly | i read that there's something called protocols, but i haven't understood yet how they go |
| 15:06 | noncom|2 | not that it is a good example, many people use them, but that's just how it can possibly be too |
| 15:06 | mungojelly | so many facts about clojure are stirring my head and making it feel soupy |
| 15:06 | justin_smith | mungojelly: in pure clojure, the only way to have a method is to implement a method is to implement some protocol defining that method |
| 15:06 | mungojelly | clojure does seem to cohere though, there's some sense to it, the words are all somewhat memorable (a blessed rarity among lisps) |
| 15:07 | noncom|2 | mungojelly: yeap, clojure is that type of soup that is used to make crystals |
| 15:07 | justin_smith | oh wow that was a mess |
| 15:07 | justin_smith | the only way to implement a method is to implement some protocol defining that method |
| 15:08 | mungojelly | it just turns into actual normal java method dispatch right? so i get to copy my intuitions from there. that's part of what makes this language so learnable. |
| 15:08 | mungojelly | it's so hard to tell because of course every language is easier to learn than the last but it really does feel like a very easy language to learn. |
| 15:08 | justin_smith | mungojelly: pretty much, aside the fact that we don't really do concrete inheretence (only interfaces) |
| 15:09 | mungojelly | it's an odd thing in computer science, that inheritance didn't turn out to be very useful. in theory it seemed like it was going to be useful. hm. |
| 15:11 | noncom|2 | nah, inheritance is a very artificail concept, that's why it did not work |
| 15:11 | noncom|2 | does not go well hand-in-hand with the rest of the type theory |
| 15:11 | noncom|2 | well, it works, but in a much more limited application that many anticipated |
| 15:12 | mungojelly | clojure though scares me it's so much the other way, by which i mean nothing has any defined structure at all you're just biting at keywords in things :/ |
| 15:13 | justin_smith | mungojelly: it's possible to have more structure - via things like defrecord, even deftype, protocols, prismatic/schema and core.typed |
| 15:13 | justin_smith | it's all optional though |
| 15:13 | noncom|2 | well, it's just a lisp with unstrict typing |
| 15:13 | noncom|2 | yeah and what justin says |
| 15:14 | noncom|2 | there are ways to impose total control of your structures |
| 15:14 | noncom|2 | turns out you don't need them most of the time though |
| 15:14 | noncom|2 | but sometimes yeah |
| 15:14 | mungojelly | yeah of course it's possible, but i mean just in general as a habit it seems to be the code here just works with bare data structures and secretly understands the semantics of them |
| 15:14 | noncom|2 | because in lisp there's actually not much semantics :) |
| 15:15 | mungojelly | of COURSE my thingamabob has a doohickey as its third whatzit, what else would it have |
| 15:15 | noncom|2 | :) |
| 15:17 | noncom|2 | my story was this: i wanted to learn a lisp for a very long time, but did not understand. then i became java, then, as a soft OOP->FP transition i was scala... was storming lisp walls several times never getting a grasp. i simply could not understand. then at one moment i understood that there's nothing to understand. it's just simple and it works.. was a revelation of sorts |
| 15:18 | mungojelly | i still don't understand common lisp, the concepts are fine but put them all together with that WEIRD VOCAB and i can't follow a thing. but i learned scheme from SICP, which is fantastic. |
| 15:20 | noncom|2 | hmmm maybe :D |
| 15:21 | noncom|2 | but there's just lambda and variable names.. |
| 15:25 | noncom|2 | mungojelly: so, if you're going to explore the tiling system or write the intellectual threading macro, cool! if you have some progress later, we're glad to witness and try it out :) |
| 15:26 | noncom|2 | as i am programming games myself, i am especially excited about the tiling system excersise.. |
| 15:26 | mungojelly | what are you up to? any code up i can read? i need to read a bunch of clojure |
| 15:28 | mungojelly | ugh if my tiles want to move should they request to move from a board manager or what sigh |
| 15:29 | mungojelly | i definitely feel like i'm not thinking clojure-y enough |
| 15:29 | justin_smith | IMHO unless you have a strong reason to do things otherwise, a tile should be pure data, and you should have a function that takes a board of tiles and returns a new board of tiles (including any moves needed) |
| 15:30 | noncom|2 | mungojelly: well, actually lately i am using a game engine (JMonkeyEngine 3) to create software for audio-visual installations, mappings and stuff... unfortunately it is protected by my employers contract but i can share the wrapper for JME3, if you later come to it |
| 15:30 | justin_smith | so the board is a big container, tiles are smaller containers inside it, and the logic is in a function that transforms boards by moving tiles |
| 15:31 | noncom|2 | mungojelly: yes, you have data and separately - functions that manipulate it |
| 15:31 | mungojelly | justin_smith: yes that's sorta what i was thinking but then.. do i ask every tile every time if they want to move? :/ |
| 15:31 | noncom|2 | mungojelly: but i also be happy to answer any game programming related questions you might have regarding clojure specific stuff... and other people here too do games |
| 15:32 | noncom|2 | mungojelly: you just update the whole board at once |
| 15:32 | noncom|2 | mungojelly: like push the board through the monad |
| 15:32 | mungojelly | well what i don't know is what you already have. do you have anything? is there anything i can play with? i mean like little abstractions, toys |
| 15:32 | justin_smith | mungojelly: it depends on what your ruleset is? if it's like chess, the "player" abstraction should decide what should move, if it's like conway's life, you should process one group of 9 at a time, each time determining the fate of the one in the middle... |
| 15:33 | mungojelly | justin_smith: i'm just making a general abstraction for building various toys and games and experiments on. maybe serious things too i suppose w/e. |
| 15:34 | mungojelly | it's like a toybox that comes with some generic empty boards and some sets of tiles and then you can build from there |
| 15:34 | mungojelly | take the alphabet tiles, make a word game |
| 15:34 | justin_smith | mungojelly: well, in that case you'll probably need to support both those models (plus others) |
| 15:34 | noncom|2 | mungojelly: eh, sorry, no real functional code to play with :/ all is protected by the contract :/ |
| 15:37 | justin_smith | mungojelly: one cool design which is very popular in the game world, and fixes a lot of the problems introduced by OO in games, is ECS |
| 15:37 | justin_smith | entity component systems |
| 15:38 | mungojelly | the whole time i've been learning to program i've been reading programs for games with tiles in them hoping for something i can pick up and play with but it's always, for row, for col, row * width * hope you got the rotation right, draw the imperative sequence of things :( |
| 15:38 | justin_smith | it's like you took the object graph, and made a normalized database out of it - you have a list of ids representing all entities in the game, and each property is actually a table mapping from an id to a value |
| 15:38 | mungojelly | justin_smith: everyone's saying ECS over and over but i don't understand what the big deal is. they weren't doing that already? wtf? |
| 15:39 | justin_smith | mungojelly: the difference is with ecs the player doesn't have a color |
| 15:39 | justin_smith | the game has a table of colors, that maps the player id to a color |
| 15:39 | justin_smith | so it's not OO at all in the layout |
| 15:39 | justin_smith | closer to sql |
| 15:40 | mungojelly | ..which they weren't already doing? every basic programming text tells you not to hardcode numbers. do we not understand that colors are numbers and you can't do that with colors either. hardcoded numbers everywhere. |
| 15:40 | justin_smith | mungojelly: the point is, there is no player object |
| 15:40 | justin_smith | and before ecs they were doing OO, where your entities are objects |
| 15:41 | mungojelly | i've been so irritated the whole time i've been learning by the lack of anything for me to play with and it's my theory there's no good reason for it at all, which i now will have to back up with some code, but i don't see what the problem is, i really don't, just give beginners any toys at all. :( |
| 15:42 | mungojelly | i want to give them some boards, like maybe finite boards and infinite boards, and then some tiles to put on the board |
| 15:42 | justin_smith | then do that |
| 15:42 | justin_smith | the problem with easy tools for beginners is that too often big systems are built with those tools, as if you had a temple made of tinker toys. What works in the small isn't the same as what works in the large. |
| 15:43 | mungojelly | and then there's an example game and what it says is, give me some tiles and arrange them like this, so then of course you can make a different program that arranges them differently, or different tiles to plug in |
| 15:43 | mungojelly | yeah like these incredible movies people have been making in scratch, have you seen those?! |
| 15:44 | mungojelly | i checked it out because TIOBE said that Scratch is one of the top languages so i checked out what people are making with it lately. give people any tools they can use at all, even if it's difficult, and they'll do it. they'll do difficult as long as they can observe incremental progress. |
| 15:44 | tmtwd | http://pastebin.com/qrvqc90E what is the .. in this function? and the -target and -value? |
| 15:44 | justin_smith | sure, and my job would be a living hell if I had to make things in scratch |
| 15:45 | justin_smith | but it's a great tool for learning, and a great toy |
| 15:45 | justin_smith | (doc ..) |
| 15:45 | mungojelly | unlike those users, you'd quickly add new blocks |
| 15:45 | clojurebot | "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand." |
| 15:45 | noncom|2 | tmtwd: yes, one of the java interop things |
| 15:46 | justin_smith | tmtwd: .. is like -> but only for methods |
| 15:46 | tmtwd | oh |
| 15:46 | mungojelly | (doc ...) |
| 15:46 | clojurebot | Pardon? |
| 15:46 | mungojelly | just wondering |
| 15:46 | justin_smith | tmtwd: so -target is actually property access (.-target e) |
| 15:46 | tmtwd | oh I see |
| 15:47 | tmtwd | (.-target e) and (.-value ) |
| 15:47 | tmtwd | right I get it |
| 15:47 | justin_smith | right, the whole form is actually (.-value (.-target e)) |
| 15:49 | augustl | anyone else suddenly getting "error in process filter: Wrong number of arguments: (1 . 1), 0" in emacs for cider-jack-in? |
| 15:49 | justin_smith | mungojelly: I've done a lot of visual programming (mostly in puredata), and the biggest problem is that the number of relations between things that you can draw clearly is limited on a 2d surface, we can easily read text and infer a larger collection of relations with less ambiguity |
| 15:49 | justin_smith | augustl: sounds like you updated something in your cider ecosystem |
| 15:50 | augustl | I haven't touched it since I installed it but for some reason I have a -snapshot dependency |
| 15:50 | augustl | so perhaps it was updated automatically by leiningen |
| 15:50 | augustl | (in my ~/.lein/profiles.clj) |
| 15:50 | justin_smith | yup, snapshots are intended to update |
| 15:50 | justin_smith | but that's an elisp error |
| 15:51 | augustl | when I set this up a long time ago I had to use snapshots to make it work |
| 15:51 | augustl | doh, I did update all my packages in emacs too |
| 15:52 | justin_smith | augustl: in my experience when I update any packages that are in any way related to cider in emacs, I need to delete my elc files before things work again |
| 15:52 | mungojelly | justin_smith: one mistake i think all those systems make is they're ugly, or rather just boring looking. you're wiring up boxes, and they're all boxes. they need to be like candy cane striped and fluffy if they're this sort of thing, something that engages your visual perception of them. |
| 15:52 | justin_smith | augustl: emacs / cider should be smart enough to work this out itself, but somehow is not |
| 15:52 | noncom|2 | mungojelly: btw, maybe nightcode by zach oakes is getting close to what you're saying |
| 15:52 | mungojelly | even scratch is just about being cute and silly and yet the blocks are all pretty much the same except they're color coded. boooooooring. |
| 15:52 | augustl | justin_smith: will try that, tnx :) |
| 15:53 | mungojelly | noncom|2: i tried to run it and it didn't work. :( nightcode, nightrun or something, i tried the one that makes games. but when i clicked to show the code it just showed a greyness. :( |
| 15:54 | noncom|2 | hmmm.. should not be like that |
| 15:54 | mungojelly | i thought i'd see if i was doing anything obvious wrong and then write to the author |
| 15:55 | noncom|2 | what could possibly be done wrong with a program that should work out-of-the-box? |
| 15:56 | augustl | hmm, deleting the elpa folder solved the problem. I'm this close to throwing out emacs.. Why do I have to waste time with mundane bugs in software that's at least a few centuries old |
| 15:57 | kavkaz | augustl: Personally I don't really have any alternative to emacs + CIDEr |
| 15:58 | kavkaz | CIDER* |
| 15:58 | kavkaz | I was using vim with the lein repl in a tmux session, but it wasn't the same |
| 15:58 | augustl | yeah, I'm addicted to its paredit too |
| 15:58 | justin_smith | ~justin_misth |
| 15:58 | clojurebot | Gabh mo leithscéal? |
| 15:58 | justin_smith | ~justin_smith |
| 15:58 | clojurebot | justin_smith is sits on a throne of lies |
| 15:58 | justin_smith | ~justin_smith |
| 15:58 | clojurebot | justin_smith is sits on a throne of lies |
| 15:58 | justin_smith | ugh keeps getting the wrong factoid |
| 15:58 | kavkaz | of course there's the eclipse plugin counterclockwise, but It's really not the same, because I'm too hooked on the vim bindings |
| 15:59 | justin_smith | anyway, I gave up on cider, and now code by banging parens with rocks |
| 15:59 | justin_smith | kavkaz: cursive is probably the most extensive integration right now |
| 15:59 | kavkaz | justin_smith: you mean emacs version 1.0 |
| 15:59 | kavkaz | ? |
| 15:59 | justin_smith | kavkaz: I mean zero editor integration |
| 15:59 | kavkaz | they added pebbles and sticks in version 1.5 |
| 15:59 | justin_smith | heh |
| 16:00 | augustl | all editors having "added paredit" in a relatively late changelog lose a lot of trust from me :P |
| 16:01 | kavkaz | justin_smith: do you use cursive? |
| 16:01 | justin_smith | kavkaz: I use emacs with no repl integration |
| 16:01 | kavkaz | justin_smith: Ah i see |
| 16:01 | justin_smith | kavkaz: I edit the code in emacs, save it, then reload it in my repl terminal |
| 16:01 | kavkaz | justin_smith: That's what I used to do with vim in tmux |
| 16:01 | kavkaz | but i need those rainbow parentheses lol |
| 16:02 | mungojelly | what is cursive, how do you extend it |
| 16:02 | oddcully | ~cursive |
| 16:02 | clojurebot | Gabh mo leithscéal? |
| 16:02 | noncom|2 | its simply a clojure ide on top of jetbrains idea |
| 16:02 | mungojelly | i've gotten a vague impression that cursive is a cool thing so i have it on my list of things to try |
| 16:02 | augustl | kavkaz: I've found "highlight opposite parentheses" to be sufficient |
| 16:03 | noncom|2 | many ppl say cursive is cool! |
| 16:03 | noncom|2 | it is being actively developed |
| 16:03 | kavkaz | I'm gonna give it a shot with cursive, I have 240mb free space on my SSD lol |
| 16:03 | augustl | mungojelly: cursive is "oh god which editor do I hate the least whatever I'll throw money at the problem" |
| 16:04 | oddcully | i run vim-fireplace most of the time and check from time to time into cursive, what it complains about |
| 16:06 | kavkaz | Nah I'll stick with emacs |
| 16:08 | kavkaz | augustl: To me emacs just has been a better experience. But I understand the struggle of trying to get it to work the way you want it to |
| 16:09 | kavkaz | It's been said very well, vim is something that works right off the bat, emacs is something that you have to poke around with |
| 16:12 | augustl | emacs is my favorite so far as well |
| 16:18 | kavkaz | Honestly I think bbatsov's work on CIDER and Clojure mode makes emacs very sufficient for Clojure |
| 16:21 | kavkaz | Also all the other contributors for those projects, I know there's at least a couple here |
| 16:21 | kavkaz | and for other community projects as well |
| 16:23 | augustl | yeah that part is really nice, it's emacs itself I'm struggling with - it's so big! |
| 16:25 | Tagore | emacs can be kind of tricky- it kind of comes from a different time. |
| 16:27 | justin_smith | I don't know, I figured out emacs itself OK, but I'm too stupid to use cider properly |
| 16:27 | Tagore | It can also be very rewarding, especially if you want to do the kind of programming Slime and its alternatives allow. |
| 16:31 | Tagore | Hmm- well I just joined this channel, so I'm missing context. |
| 16:31 | Tagore | And I'm just starting to play with Cider- have used Slime a lot in the past though. |
| 16:32 | Tagore | What's up with Cider? |
| 16:32 | Tagore | And you? |
| 16:33 | kavkaz | Cider is honestly very minimal |
| 16:33 | justin_smith | Tagore: I used cider, it's features kind of worked, and every time any part of it was upgraded the whole thing would break |
| 16:33 | kavkaz | justin_smith: perhaps if you have an extensive emacs config as it is, many things will break |
| 16:33 | justin_smith | I got tired of fixing it all the time, and stopped using it. But clearly other people are productive with it. |
| 16:33 | kavkaz | when I started I only had evil mode on |
| 16:34 | justin_smith | kavkaz: being able to switch to evil mode was a bonus of leaving cider |
| 16:34 | kavkaz | augustl: check out braveclojure.com, he talks about emacs, I got a couple pointers from there |
| 16:34 | kavkaz | most of my proficiency with emacs comes from practice though... well, as with anything |
| 16:35 | kavkaz | justin_smith: Ah i see. I don't think evil mode broke too many bindings. Perhaps this is an earlier version of cider you're talking about? |
| 16:35 | kavkaz | Anyways I gotta go guys |
| 16:35 | augustl | I guess a core problem is my grumpyness.. I don't want to have to deal with weird errors after updating packages that are solved by basically a "clean' :) |
| 16:35 | justin_smith | kavkaz: versions 0.5 through 0.9, things broke all along the way |
| 16:35 | justin_smith | augustl: exactly |
| 16:36 | justin_smith | perhaps my fundamental problem was imagining a paradigm where packages could be updated |
| 16:38 | expez | Expecting software marked unstable to be stable isn't fair |
| 16:39 | expez | CIDER uses semver so you should expect some stuff to break until it reaches 1.0 |
| 16:39 | justin_smith | OK |
| 16:40 | justin_smith | expez: I guess I got used to clojure world, where I can use core.async 0.00001-ALPHA-asdlkfjasdklfj and then upgrade to 0.00002-ALPHA-joiasdf and things don't break |
| 16:40 | augustl | the problem seemed to be with emacs and how it compiles packages though |
| 16:40 | expez | Some people are even using the Melpa build while complaining about it being unstable. Melpa is like the development snapshot so unless you're willing to jump into the debugger every now and then you should definitely use melpa-stable |
| 16:41 | augustl | or I guess at least you could say emacs makes it possible for cider to update in a way that is broken unless you do a "clean" of already compiled elisp |
| 16:41 | justin_smith | expez: I wasn't using melpa, but you've concinced me to try cider if there's ever a 1.0 |
| 16:41 | expez | justin_smith: the package manager gets better in emacs 25, but now you often have to manually delete packages after upgrading because emacs kept some of the old stuff around :/ |
| 16:42 | justin_smith | expez: I guess cider was the only emacs thing I ever used that saw breaking abi changes, so it looked like a cider problem rather than an emacs one. But yeah, that sounds like a problem with emacs. |
| 16:44 | justin_smith | expez: also the nature of the projects I'm working on mean I expose some hairy edges UX wise. I have four clojure processes running at a time, juggling them is much easier when none of them are in my editor |
| 16:44 | expez | justin_smith: CIDER is 16k lines of Elisp now, and 4k lines of clojure. I doubt many other packages you use are of similar complexity. |
| 16:46 | justin_smith | yeah, that's very likely true |
| 16:46 | expez | justin_smith: you should check in every now and then to help find nasty edge cases :) |
| 16:46 | mungojelly | expez: huh that is big, what all does it do? |
| 16:46 | Tagore | Justin: do you have a way of interacting with a running program right now that works for you, or are you restarting it every time you change the code? |
| 16:46 | justin_smith | Tagore: I use (require my.ns :reload) |
| 16:46 | justin_smith | it's simple and it works |
| 16:47 | expez | mungojelly: check out the readme here https://github.com/clojure-emacs/cider for a list stuff |
| 16:47 | justin_smith | oops, (require 'my.ns :reload) of course |
| 16:49 | mungojelly | am i prematurely optimizing by thinking of having my tiles say what kind of tile they are and referring to one copy of how to draw them etc., will clojure make it ok if i just put the same thing over and over for the same tile. oh i guess it won't make it ok in serialized forms or whatever. so i should definitely just have the board be indirectly pointing to the tiles. |
| 16:50 | srbaker | heya folks. |
| 16:50 | srbaker | i'm using enlive-html to do some scraping for my first clojure project. |
| 16:50 | mungojelly | i'm just going to have them indexed by a vector of [x y] i guess, indexing by vectors is pretty, or should i name them x and y like {x: 0, y: 0} hm |
| 16:51 | srbaker | first q: what's the easiest way to print out the value of a function so i can see what it's giving me? i think it's a map, but i'm not sure |
| 16:51 | srbaker | i currently have just a println |
| 16:51 | Tagore | I haven't used that approach, so I have no idea what it's like to program using it. I have always found it very nicve to be able toi interact with a running Lisp image from my editor. |
| 16:52 | srbaker | http://pastebin.com/J9Q7bsyk that's what println gives me. but i'm having a hard time mapping over it |
| 16:52 | srbaker | i don'tknow why |
| 16:52 | clojurebot | Cool story bro. |
| 16:52 | justin_smith | srbaker: there's prn if you want the output to be less ambiguous, or you could print the type of the thing |
| 16:52 | srbaker | aha, prn is what i wanted for now. thanks |
| 16:53 | justin_smith | srbaker: here's my trick (-> d type) followed by (-> d count) (-> d first type) (-> d first keys) (-> d first :attrs)... |
| 16:53 | justin_smith | srbaker: this is very quick if you are using the arrow keys in the repl, you can find your data quickly |
| 16:53 | justin_smith | srbaker: also, it helps to put a pprint at the end sometimes to get multi line printout |
| 16:53 | srbaker | okay i've updated the paste: http://pastebin.com/Rqrgv8D1 |
| 16:53 | srbaker | what type is that? and where do i get a list of functions i can use with it? |
| 16:53 | srbaker | specifically, i want the string at the end. |
| 16:54 | justin_smith | it's a list which contains a number of things, including hash maps |
| 16:54 | justin_smith | srbaker: use the -> as I recommended above, you'll find a series of accessors that get the data you want |
| 16:55 | justin_smith | (where d is the var containing that whole big blob of data of course) |
| 16:56 | srbaker | i suppose i should probably set up emacs to be more helpful |
| 16:57 | justin_smith | srbaker: here's how to do it (I just used your paste as the starting data) you don't need emacs, this is just a regular repl https://www.refheap.com/109471 |
| 16:58 | srbaker | nice. tanks |
| 16:58 | srbaker | thanks |
| 16:58 | justin_smith | just fixed the formatting |
| 16:59 | srbaker | weird. so what's working in the repl is not working in my code |
| 16:59 | srbaker | (defn vf-days [] (html/select (vf) [:p.p1])) |
| 17:00 | srbaker | when i try to do first type on that, it complains that it can't convert it too ISeq |
| 17:00 | srbaker | when when i prn it, and paste it into (def d on the repl, no problem |
| 17:00 | justin_smith | srbaker: OK, what does your code say the type is? |
| 17:01 | srbaker | LazySeq |
| 17:01 | srbaker | er |
| 17:01 | justin_smith | then you should be able to get the first item of that |
| 17:01 | srbaker | whoops. missing parens |
| 17:01 | srbaker | hah |
| 17:02 | srbaker | i'm sure i'm not the first dude to run into that :P |
| 17:02 | justin_smith | the learning process never ends |
| 17:18 | srbaker | is there a has-key function? |
| 17:18 | justin_smith | srbaker: contains? |
| 17:18 | srbaker | i want to know if a map has a key :tag |
| 17:18 | justin_smith | ,(contains? {:tag "OK"} :tag) |
| 17:18 | clojurebot | true |
| 17:18 | srbaker | what's ,? |
| 17:19 | justin_smith | ,(contains? {:bag "OK"} :tag) |
| 17:19 | clojurebot | false |
| 17:19 | srbaker | ah, thanks |
| 17:19 | justin_smith | srbaker: it makes clojurebot evaluate things |
| 17:19 | srbaker | nice. |
| 17:20 | justin_smith | srbaker: also, in normal clojure code , is whitespace |
| 17:20 | _Bruno_ | hey guys, does anyone know why (into {} [[:a 1] [:b 2]]) => {:a 1, :b 2} while (into {} ['(:a 1) '(:b 2)]) => throws ClassCastException?? |
| 17:20 | justin_smith | ,,,,,(,,,,,+,,,,,,,,,,21,,,,,,,10,,,,,11,,,,),,,,,,,,,,,,, |
| 17:20 | clojurebot | 42 |
| 17:20 | justin_smith | _Bruno_: because lists cannot be coerced to map-entries, but vectors can |
| 17:21 | _Bruno_ | I came across this by trying to manipulating a sequence and turn it into a map, and I was curious to understand why the vector version works but it breaks with lists or sequences. |
| 17:21 | srbaker | (defn new-day [item] (if (contains? (item :content) :tag)) ... |
| 17:21 | srbaker | i'm getting "unable to resolve item in this context" which is confusing :( |
| 17:21 | justin_smith | srbaker: too many parens |
| 17:21 | justin_smith | for starters... |
| 17:22 | justin_smith | or wait... |
| 17:22 | justin_smith | srbaker: are you sure that's what you have? because that should not complain about item - I mean if item is not callable it would complain about that |
| 17:22 | justin_smith | (:content item) would be more canonical |
| 17:22 | _Bruno_ | justin_smith: is there any particular reason why would you not coerce a list into a map entry? |
| 17:23 | justin_smith | _Bruno_: I'm not totally certain of the reasoning, but I do know that clojure can use a vector as a map entry without creating a new data structure |
| 17:23 | justin_smith | or something like this... |
| 17:23 | justin_smith | but this can't be done with a list |
| 17:24 | _Bruno_ | I guess the protocol need to be extended to lists as well. |
| 17:25 | justin_smith | well, lists aren't associative |
| 17:25 | justin_smith | so I don't know if extending the protocol even makes sense in that case |
| 17:25 | _Bruno_ | MapEntry isn't either, it need just a tuple of two values |
| 17:26 | srbaker | it is complianing about item |
| 17:26 | justin_smith | _Bruno_: yes it is, all vectors are associative, and mapentry is a vector |
| 17:26 | justin_smith | ,(associative? []) |
| 17:26 | clojurebot | true |
| 17:27 | srbaker | it is definitely complaining about item :( |
| 17:28 | justin_smith | srbaker: can you use refheap.com to show us the whole function? |
| 17:28 | _Bruno_ | justin_smith: vectors are but here you are trying to bridge Java's MapEntry which only cares about a key and a value which in turn can be extracted from a list with `first` and `second` |
| 17:28 | justin_smith | _Bruno_: no, this is clojure's map entry, which is a two element vector |
| 17:28 | luma | clojure's mapentry is a vector |
| 17:29 | justin_smith | _Bruno_: this isn't about the java data structures in hash maps at all |
| 17:29 | _Bruno_ | justin_smith: it's java's one ClassCastException clojure.lang.Keyword cannot be cast to java.util.Map$Entry |
| 17:30 | justin_smith | ,(into {} ['(:a :b)]) |
| 17:30 | clojurebot | #error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :at [clojure.lang.ATransientMap conj "ATransientMap.java" 44]}]\n :trace\n [[clojure.lang.ATransientMap conj "ATransientMap.java" 44]\n [clojure.lang.ATransientMap conj "ATransientMap.java" 17]\n ... |
| 17:30 | justin_smith | oh, right, sorry |
| 17:30 | srbaker | hrm. not getting that error now. must've had some parens missing |
| 17:30 | justin_smith | anyway, the Map$Entry is a vector of two elements, regardless of provenance |
| 17:30 | srbaker | or too many at the bottom |
| 17:31 | _Bruno_ | justin_smith: thx, i'll dig in the source code |
| 17:31 | justin_smith | _Bruno_: it's very unlikely you'll convice the core clojure team to change conj such that it would convert lists to map entries |
| 17:32 | justin_smith | though I guess it could be done hypothetically as a local extension |
| 17:32 | luma | clojure map's cons tries three different things: it checks if the object is a java.util.Map$Entry, then checks if it's a clojure.lang.MapEntry, then treats it as a sequence of java.util.Map$Entry without checking |
| 17:32 | justin_smith | luma: oh! I feel much less stupid now, thanks |
| 17:32 | justin_smith | luma: and it's conj not cons, of course |
| 17:33 | luma | in the java source, it's cons (but in clojure, conj obviously) |
| 17:33 | luma | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java |
| 17:33 | justin_smith | oh, cool |
| 17:33 | srbaker | so the canonical form is (key map) for getting values from maps? |
| 17:34 | justin_smith | srbaker: if the map is not a literal but the key is, yes |
| 17:34 | srbaker | okay |
| 17:34 | justin_smith | srbaker: the idea being that you know what the key is because it's literal |
| 17:34 | justin_smith | whereas what happens if the map were a list instead? or nil? |
| 17:43 | luma | reading my comment again, the second check is actually for vector and not MapEntry |
| 17:43 | luma | so that's why vector works but a list doesn't |
| 17:45 | _Bruno_ | luma: looking at the code it looks like that lists or sequences are not accepted in order to be able to distinguish between the two following cases: (conj {} [:a 1] [:b 2]) and (conj {} {:a 1 :b 2}) |
| 17:45 | luma | sounds reasonable |
| 17:45 | _Bruno_ | the first one is a variadic parameter as seq of vectors |
| 17:45 | luma | since seqing a map results in a sequence of mapentries |
| 17:45 | _Bruno_ | the second one is a seq of map.entry |
| 17:46 | justin_smith | I keep forgetting that (conj {} {}) works |
| 17:52 | srbaker | is there a pretty print function that will make these maps a bit easier to read when i print them? |
| 17:52 | justin_smith | clojure.pprint/pprint |
| 17:52 | srbaker | tack |
| 17:52 | justin_smith | it's automatically imported into your starting ns as pprint if you use nrepl |
| 18:14 | srbaker | ,(seq? "") |
| 18:14 | clojurebot | false |
| 18:15 | justin_smith | ,(map seq? [nil [] {} ()]) |
| 18:15 | clojurebot | (false false false true) |
| 18:36 | srbaker | okay, this is a super weird error |
| 18:37 | srbaker | https://www.refheap.com/109472 |
| 18:37 | srbaker | i'm sure it's someting to do with my expectionat of how the if works |
| 18:37 | srbaker | in new-day |
| 18:37 | justin_smith | srbaker: line 10, (true) |
| 18:37 | justin_smith | ,(true) |
| 18:37 | clojurebot | #error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java"... |
| 18:37 | TEttinger | ,true |
| 18:37 | clojurebot | true |
| 18:37 | justin_smith | srbaker: parens in clojure are not for grouping |
| 18:38 | justin_smith | they are for calling things |
| 18:38 | srbaker | oh |
| 18:38 | srbaker | right, of course |
| 18:38 | srbaker | and that shouldbe false :P |
| 18:38 | srbaker | excellent. thanks |
| 18:39 | justin_smith | also, line 100 (= (:tag (first item))) will always return true |
| 18:39 | justin_smith | ,(= (:tag nil)) |
| 18:39 | clojurebot | true |
| 18:39 | justin_smith | err, I mean line 11 |
| 18:39 | srbaker | oh, right, i'm missing :strong |
| 18:41 | justin_smith | ,(map #(apply (first %) %&) (iterate #(conj % =) [= =])) |
| 18:41 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/=> |
| 18:42 | srbaker | i'm getting a lot furhter when i switched to test-driving this. |
| 18:42 | justin_smith | srbaker: yeah, that can help a lot when it comes to keeping your steps organized |
| 18:42 | justin_smith | (and ensuring you don't break something as you fix something else) |
| 18:42 | srbaker | especially since i've practised TDD pretty much without exception since about 2001 |
| 18:44 | justin_smith | ,(map #(apply (first %) (rest %)) (iterate #(conj % =) [= =])) |
| 18:44 | clojurebot | (true true true true true ...) |
| 18:44 | justin_smith | srbaker: that would help too! |
| 18:45 | justin_smith | srbaker: I'm a big fan of how you can make tests easy to implement in clojure by separating logic from side effects |
| 18:45 | justin_smith | well, I mean you can do that in other languages too, but clojure has some nice facilities for this sort of thing |
| 18:46 | amalloy | feature request: since (apply f x [y z]) is the same as (apply f [x y z]) already, (apply [f x y z]) should work too |
| 18:47 | giantwaffelcat | why do people think clojure is a lisp |
| 18:47 | dbasch | giantwaffelcat: because it plays one on the internet |
| 18:47 | amalloy | FR #2: replace all other characters in clojure source code with ( and ) |
| 18:47 | justin_smith | giantwaffelcat: because they disagree with you about the definition of the word lisp |
| 18:48 | giantwaffelcat | heh |
| 18:48 | giantwaffelcat | I'm just upset Clojure lacks cons |
| 18:48 | TEttinger | ,cons |
| 18:48 | clojurebot | #object[clojure.core$cons__4090 0x6db6d0a6 "clojure.core$cons__4090@6db6d0a6"] |
| 18:48 | justin_smith | ,(cons 'a nil) |
| 18:48 | clojurebot | (a) |
| 18:48 | giantwaffelcat | justin_smith: not proper cons |
| 18:48 | TEttinger | do you mean cons pairs? |
| 18:48 | giantwaffelcat | ,(cons 'a 'b) |
| 18:48 | clojurebot | #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Symbol"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.RT cons "RT.java" 655]\n [clojure.core$con... |
| 18:48 | giantwaffelcat | TEttinger: yes. |
| 18:49 | TEttinger | ,['a 'b] |
| 18:49 | clojurebot | [a b] |
| 18:49 | dbasch | giantwaffelcat: don’t focus on the cons, think of the pros |
| 18:49 | TEttinger | it is not that much different. |
| 18:49 | giantwaffelcat | also the fact nil isn't the (canon?) empty list is annoying |
| 18:49 | amalloy | anything you can do with improper lists you can do with real lists anyway |
| 18:49 | giantwaffelcat | dbasch: ...goddamnit |
| 18:50 | TEttinger | ,(seq (range 0)) |
| 18:50 | clojurebot | nil |
| 18:50 | TEttinger | ,(seq []) |
| 18:50 | clojurebot | nil |
| 18:51 | TEttinger | if empty list was equivalent to nil, would appending to it result in a list or a vector? |
| 18:51 | TEttinger | conj can produce either |
| 18:51 | srbaker | aw shit, partition-by won't do what i want anyhow :( |
| 18:51 | TEttinger | ,(conj nil 1) |
| 18:52 | clojurebot | (1) |
| 18:52 | TEttinger | appears to be a seq anyway |
| 18:52 | srbaker | i was hoping that given a list of 1, 2, 1, 2, 1, 2; i could partitionon (= 1 1) and get three lists. whoops! |
| 18:53 | TEttinger | ,(partition-by (partial not= 1) [1, 2, 1, 2, 1, 2]) |
| 18:53 | clojurebot | ((1) (2) (1) (2) (1) ...) |
| 18:53 | TEttinger | ,(partition-by (partial = 1) [1, 2, 1, 2, 1, 2]) |
| 18:53 | clojurebot | ((1) (2) (1) (2) (1) ...) |
| 18:53 | TEttinger | ah! |
| 18:53 | TEttinger | you may want group-by, not sure |
| 18:53 | srbaker | oh |
| 18:53 | justin_smith | TEttinger: group-by returns a hash-map |
| 18:53 | TEttinger | err, no... |
| 18:54 | TEttinger | yeah I realized it was wrong after I said it |
| 18:54 | TEttinger | still waking up |
| 18:54 | srbaker | i basically want to iterate the list, and start a new sub-list every time (new-day) is true |
| 18:54 | justin_smith | srbaker: sounds like a good time to use reduce |
| 18:55 | srbaker | yeah. |
| 18:56 | justin_smith | ,(apply conj (reduce (fn [[done curr] el] (if (even? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2]) |
| 18:56 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 18:56 | justin_smith | ,(apply conj (reduce (fn [[done curr] el] (if (even? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2])) |
| 18:56 | clojurebot | [[1] [2 1 1] [2 1 1 1] [2 1 1 1 1] [2]] |
| 18:56 | TEttinger | (inc justin_smith) |
| 18:56 | justin_smith | every instance of an even number starts a new vector |
| 18:56 | TEttinger | lazyboooooot! |
| 18:56 | justin_smith | KHAAAAAAAN |
| 18:57 | srbaker | ,(apply conj (reduce (fn [[done curr] el] (if (odd? el) [(conj |
| 18:57 | srbaker | done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 |
| 18:57 | srbaker | 1 2 1 1 1 1 2])) |
| 18:57 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 18:57 | srbaker | whoops |
| 18:57 | justin_smith | srbaker: yeah, one liners only with lazybot |
| 18:57 | srbaker | ,(apply conj (reduce (fn [[done curr] el] (if (even? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2])) |
| 18:57 | clojurebot | [[1] [2 1 1] [2 1 1 1] [2 1 1 1 1] [2]] |
| 18:57 | TEttinger | ,(apply conj (reduce (fn [[done curr] el] (if (odd? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2])) |
| 18:57 | clojurebot | [[] [1 2] [1] [1 2] [1] ...] |
| 18:57 | srbaker | i'm actually oversimplifying with 1 and 2 |
| 18:58 | justin_smith | srbaker: I assumed, but I also figure you can do the mutatis mutandis to make it work with your code |
| 18:58 | srbaker | it's literally: a list of lists. the list is either a 1 element string; or a list of things where the first element is a hash with :tag => :strong |
| 18:58 | srbaker | and it comes in, in order. |
| 18:58 | justin_smith | srbaker: do they always strictly alternate? |
| 18:58 | srbaker | i'm writing a bot to scrape and parse the lunch menus for the two restaurants near our office |
| 18:58 | srbaker | so we can ask a slack bot what's for lunch. |
| 18:59 | justin_smith | srbaker: admirable plan |
| 18:59 | srbaker | justin_smith: yes, they always alternate. but the list elements mightbe varied |
| 18:59 | srbaker | here's the menu: http://valfarden.nu/dagens-lunch/ |
| 18:59 | justin_smith | in that case you can ditch the reduce and use partition-all 2 |
| 18:59 | justin_smith | ,(partition-all 2 [:a :b :a :b :a :b :a :b]) |
| 18:59 | srbaker | nope. while there are two options per day this week |
| 18:59 | clojurebot | ((:a :b) (:a :b) (:a :b) (:a :b)) |
| 18:59 | srbaker | it's not always true |
| 19:00 | justin_smith | ahh, OK |
| 19:00 | srbaker | ii think reduce will do it |
| 19:00 | justin_smith | in that case a reduce to start new collections as you go should handle it then |
| 19:00 | justin_smith | yeah |
| 19:00 | srbaker | yep. it's a pattern i'm not familiar iwth, and it's 1am |
| 19:00 | srbaker | so i'm probably going to give up for the night shortly |
| 19:01 | srbaker | the solution is reduce, so i can start with that in the morning |
| 19:01 | srbaker | i know how i'd do this with #inject in ruby, which is just reduce. |
| 19:01 | justin_smith | srbaker: do note that this is using a non-obvious idiom of making a collection of collections as the accumulator, and conditionally emptying an in-progress collection into the master collection at each step |
| 19:02 | justin_smith | s/emptying/putting oops |
| 19:06 | justin_smith | I should totally write a splits function that does what people keep expecting split-with to do |
| 19:09 | amalloy | flatland.seq has partition-between |
| 19:09 | amalloy | er, flatland.useful.seq |
| 19:10 | _Bruno_ | justin_smith: what do you think split-with should do? |
| 19:12 | justin_smith | _Bruno_: I'm fine with what split-with does, but what people keep expecting it to do is slice a collection based on a predicate |
| 19:12 | justin_smith | so that each item that is truthy for that predicate becomes the start of the next subsequence |
| 19:12 | justin_smith | (which is also useful and I think deserves to be its own function) |
| 19:12 | _Bruno_ | justin_smith: isn't that partition-by ? |
| 19:13 | justin_smith | I think that's a special case of amalloy 's partition-between |
| 19:13 | justin_smith | _Bruno_: partition-by only splits once |
| 19:13 | justin_smith | oh wait, |
| 19:13 | justin_smith | you are right |
| 19:13 | amalloy | justin_smith: no, he's not |
| 19:13 | justin_smith | _Bruno_: it's almost partition by |
| 19:14 | _Bruno_ | the one which split only once is split-at |
| 19:14 | justin_smith | but still not quite - that one starts a new coll every time the f returns a different value |
| 19:14 | amalloy | your predicate thing is different from partition-by, but not because of number of splits |
| 19:14 | amalloy | right |
| 19:15 | justin_smith | what I am talking about is (splits #{:a} [:a :b :a :b :c :a :c]) => ((:a :b) (:a :b :c) (:a :c))) |
| 19:16 | amalloy | right. which is different fro partition-by |
| 19:16 | justin_smith | amalloy: yeah, and it can be done with partition-between just by testing the pred on the second item in the arg |
| 19:17 | _Bruno_ | justin_smith: could be called split-when |
| 19:17 | justin_smith | _Bruno_: that's a good name for it |
| 19:18 | amalloy | the split- family of functions each split once, and the partition family split N times. if you were going to define this function i wouldn't call it split-X |
| 19:18 | _Bruno_ | amalloy: partition-when then :-) |
| 19:20 | oddcully | partition-at |
| 19:22 | justin_smith | ,(defn partition-when ([p? [c & cs]] (partition-when p? cs [c])) ([p? [c & cs] acc] (cond (empty? cs) [acc] (p? c) (lazy-seq (cons acc (partition-when p? cs [c]))) :else (partition-when p? cs (conj acc c))))) |
| 19:22 | clojurebot | #'sandbox/partition-when |
| 19:22 | justin_smith | ,(partition-when #{1} [1 2 1 2 3 1 2 3 4 1 2 1]) |
| 19:22 | clojurebot | ([1 2] [1 2 3] [1 2 3 4] [1 2]) |
| 19:23 | justin_smith | oh it dropped the last part there... |
| 19:23 | oddcully | then do a partition-when-all |
| 19:24 | _Bruno_ | (defn partition-when [p c] (->> c (partition-by p) (partition-all 2) (map (partial apply concat)))) |
| 19:24 | justin_smith | ,(defn partition-when ([p? [c & cs]] (partition-when p? cs [c])) ([p? [c & cs :as coll] acc] (cond (empty? coll) [acc] (p? c) (lazy-seq (cons acc (partition-when p? cs [c]))) :else (partition-when p? cs (conj acc c))))) |
| 19:24 | clojurebot | #'sandbox/partition-when |
| 19:24 | justin_smith | oddcully: it was just a bug, I don't need the all version :P |
| 19:25 | justin_smith | ,(partition-when #{1} [1 2 1 2 3 1 2 3 4 1 2 1]) |
| 19:25 | clojurebot | ([1 2] [1 2 3] [1 2 3 4] [1 2] [1]) |
| 19:25 | justin_smith | _Bruno_: that's a nice way to do it too |
| 19:28 | noncom|2 | i am using the latest version of tower and timbre from ptaoussanis and tower cannot be required because it does not find "timbre/logp", how can this be? |
| 19:28 | noncom|2 | both are of the latest versions and from the same author |
| 19:28 | noncom|2 | did anybody encounter such an issue? |
| 19:30 | justin_smith | noncom|2: have you checked lein deps :tree ? that should show potential conflicts or misversionings |
| 19:31 | amalloy | justin_smith: the lazy-seq is in an odd place there. i think you want to either write (lazy-seq (cond ...)) or, better, (cons acc (lazy-seq ...)). and the last clause can/should use recur |
| 19:31 | justin_smith | ahh |
| 19:31 | justin_smith | good point, thanks |
| 19:31 | justin_smith | *points |
| 19:31 | noncom|2 | nope, did not check, will look at it now |
| 19:37 | noncom|2 | justin_smith: heh, it does not show anything, but manually i have found out that the latest version of tower uses timbre 3.3.1 while the latest version of timbre is 4.1.1 |
| 19:37 | noncom|2 | weird |
| 19:39 | noncom|2 | damn so i hate when projects do not compile of incompatible logging frameworks... |
| 19:39 | noncom|2 | had this happening in java many times |
| 19:39 | noncom|2 | thats why i really prefer println |
| 19:40 | justin_smith | noncom|2: I know, let's make a new logging framework api, that should fix this problem right? |
| 19:40 | noncom|2 | yeah! |
| 19:40 | noncom|2 | :D |
| 19:41 | emdashcomma | heh |
| 19:41 | crocket | What makes datomic attractive? |
| 19:41 | emdashcomma | strong, symmetrical features |
| 19:41 | crocket | Its EULA is unattractive, though. |
| 19:43 | oddcully | haha. and while you are at it also create a new linux distribution |
| 19:45 | noncom|2 | sure! we'll get it integrated right into the core! |
| 19:45 | oddcully | a linux distro specialized in java logging |
| 19:46 | noncom|2 | yeah! |
| 19:46 | noncom|2 | and it will be very flexible, so the user will have to like, manually compile like 1000+ other libs |
| 19:46 | emdashcomma | infinitely configurable |
| 19:46 | crocket | Fuck |
| 19:46 | emdashcomma | make sure it doesn't do anything useful out of the box |
| 19:46 | emdashcomma | better, have a team of consultants to offer |
| 19:47 | noncom|2 | yeah! and we'll provide a script that does half of the setup for ubuntu 10.04 coz we care |
| 19:47 | oddcully | export EDITOR=nano sorted! |
| 21:53 | elvis4526 | Is there a way to pass arguments to tests ? |
| 21:53 | elvis4526 | Let's say for example when you're inside a fixture |
| 21:53 | justin_smith | no, fixtures don't pass data to tests |
| 21:53 | justin_smith | though they can use binding of special vars |
| 21:54 | justin_smith | elvis4526: but remember that you can call test/is inside a normal function, and then call that function from multiple tests |
| 21:54 | justin_smith | (or multiple times in one test) |
| 21:54 | justin_smith | and then, you absolutely can pass in eg. different test data to the same harness |
| 21:55 | Trioxin | what do ppl use for clojure on windows? intellij? |
| 21:56 | Trioxin | cursive.. |
| 21:57 | cfleming | Trioxin: People use all sorts of things, but I try to make it easy with Cursive |
| 21:57 | cfleming | Installing lein can be tricky so I bundle it, and you can do all your leiny things from the IDE |
| 21:58 | cfleming | Which is useful for getting started - you'll want it working on the command line at some point though |
| 21:58 | elvis4526 | justin_smith: okay thanks. Special vars are the same thing as normal vars, right? |
| 21:58 | Trioxin | cursive seems to not be out yet |
| 21:58 | justin_smith | elvis4526: not quite |
| 21:58 | justin_smith | ,(def *foo* 1) ; elvis4526 note the warning |
| 21:58 | clojurebot | #error {\n :cause "denied"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojureb... |
| 21:58 | cfleming | Trioxin: It's not officially released but it works fine, it's as stable as anything else I think |
| 21:59 | justin_smith | elvis4526: anyway, in a real repl, if you try (def *foo* 1) it will warn you that the var is not declared dynamic, even though it has earmuffs |
| 22:00 | justin_smith | elvis4526: you make a special var with (def ^:dynamic *foo*) |
| 22:00 | elvis4526 | Ah, right. I just tried with a non-special vars in the fixture and its still working |
| 22:00 | justin_smith | oh, you can use def too |
| 22:01 | justin_smith | but with a dynamic var you can use (binding [*foo* ...] ...) to rebind |
| 22:02 | elvis4526 | the stackoverflow answer I read made it sound like the stars were just there to let know the programmer that the var was not dependant on lexical scope |
| 22:02 | justin_smith | the convention is that dynamic vars have ear-muffs |
| 22:03 | justin_smith | and yes, dynamic vars don't use lexical scope |
| 22:03 | elvis4526 | okay - and what's exactly the difference between let and binding ? |
| 22:04 | Trioxin | Cursive > La Clojure? |
| 22:04 | Trioxin | both are intellij plugins |
| 22:04 | elvis4526 | Trioxin: La Clojure is not maintained anymore AFAIk |
| 22:04 | Trioxin | kth |
| 22:04 | Trioxin | x |
| 22:04 | crocket | ℘ |
| 22:04 | justin_smith | elvis4526: let binds values to symbols that must be explicitly passed into a form to be used by that form |
| 22:04 | oddcully | i'd forget about ≠ cursive |
| 22:05 | oddcully | it's all old |
| 22:05 | justin_smith | elvis4526: binding changes the value of a dynamic var, and this has effect until another binding form is reached, or the scope of the binding call is escaped |
| 22:05 | justin_smith | and this does not rely on passing values in, it changes the execution environments view of some var |
| 22:06 | justin_smith | the reason we make dynamic vars look weird is because the scope and value rules for binding can lead to programs that are hard to reason about |
| 22:07 | justin_smith | (but calling def inside runtime forms instead is even worse, mind you) |
| 22:09 | elvis4526 | okay i get it - thanks |
| 22:09 | elvis4526 | i'm not sure where dynamic vars would be that useful though |
| 22:10 | justin_smith | for situations where you need to change some code's execution environment. It's very useful for the UI of emacs, so much so that the default is for variables to have dynamic binding. |
| 22:10 | amalloy | they're easier to misuse than use correctly |
| 22:10 | justin_smith | very true |
| 22:11 | amalloy | the compiler and other tooling like emacs make use of a fair number of dynamic vars, but most user programs won't |
| 22:11 | justin_smith | elvis4526: another example, *out* is a dynamic var, because a repl user should be able to change where a subprogram sends its output without adding an extra arg to every output function |
| 22:12 | elvis4526 | yeah it make sense - cool |
| 22:20 | Trioxin | so, I want to write my first clojure program (first lisp for that matter) and i have cursive and it's asking me what project type so I guess I should start with Java EE Application?? |
| 22:21 | justin_smith | Trioxin: there should be a "lein project" option, or something like that |
| 22:21 | Trioxin | i dont see that |
| 22:22 | amalloy | you don't want a java application or a java ee application |
| 22:22 | Trioxin | http://screencast.com/t/xMMZ4ZVwffW |
| 22:23 | oddcully | Trioxin: for reasons unknow, it shows java ee... do a `lein new lerl` and open that project |
| 22:23 | crocket | Stay away from java ee |
| 22:24 | crocket | java ee involves application servers which you don't want to deal with. |
| 22:24 | justin_smith | Trioxin: that was the UI for "additional libraries and frameworks" and you don't need any of them - just a basic leiningen project |
| 22:24 | Trioxin | leiningen isn't under the clojure tab |
| 22:24 | crocket | Embed jetty in your web application. Don't embed your web application in a java-ee application server. |
| 22:25 | justin_smith | Trioxin: there's an option on the left to use Leiningen as the build / dependency manager |
| 22:26 | oddcully | Trioxin: do the `lein new` dance and then open/import from idea |
| 22:26 | Trioxin | so don't use the clojure tab to use clojure.. ok |
| 22:26 | justin_smith | cfleming: I think your further assistence might be required here |
| 22:26 | justin_smith | oddcully: he doesn't know lein yet I don't think, he was trying to do this via cursive (which I guess should be easier on windows?) |
| 22:27 | oddcully | justin_smith: then he has to learn. idea is just a borken editor |
| 22:28 | Trioxin | i've used other versions of this but not for java, for html5, php, C, C++, D |
| 22:28 | Trioxin | i mean not for lisp |
| 22:30 | Trioxin | choosing clojure as my first lisp |
| 22:31 | oddcully | Trioxin: i hate to bust the bubble, but idea is not the ``be all end all'' ide; cursive might lack right now the means to generate a project out of thin air. it's the same for "advanced" gradle, ... |
| 22:32 | Trioxin | guess I'll just find a clojure tutorial first and then i'll know how to do it all right |
| 22:33 | Trioxin | else I'll never cause the singularity |
| 22:33 | Trioxin | loljk |
| 22:34 | Trioxin | or am i? |
| 22:34 | cfleming | Trioxin: La Clojure is now officially deprecated in favour of Cursive |
| 22:34 | oddcully | no you are |
| 22:34 | oddcully | all of them is depricated by not beeing useable |
| 22:35 | Trioxin | im not using la clojure |
| 22:35 | Trioxin | and i've done a lot of machine learning code |
| 22:35 | cfleming | Trioxin: In that screencast you sent, "Leiningen" appears on the left hand side as one of the project creation options. |
| 22:35 | Trioxin | yes |
| 22:36 | cfleming | That's the one you want |
| 22:36 | cfleming | That will allow you to create a new lein project |
| 22:36 | oddcully | cfleming: not for me it doesn't |
| 22:36 | oddcully | stuck at some java ee nonsense |
| 22:37 | cfleming | oddcully: What are you doing, exactly? File->New->Project..., select Leiningen from the left hand side list? |
| 22:37 | Trioxin | hold on updating my jdk first and then going back in there |
| 22:37 | Trioxin | cfleming, new project, then that yes |
| 22:38 | oddcully | meta-i -> ``Create New Project'' -> ``Leinigen'' |
| 22:38 | Trioxin | well, I was under "Clojure" |
| 22:38 | Trioxin | and I checked out the other as well not knowing what it was then looked it up and about to open it again |
| 22:39 | Trioxin | idea |
| 22:39 | cfleming | oddcully: What do you have meta-i bound to? |
| 22:39 | oddcully | cfleming: start intellij |
| 22:39 | cfleming | Ok |
| 22:39 | oddcully | cfleming: that little window, with the "pick your project" stuff |
| 22:40 | cfleming | oddcully: So you select "Leiningen", and the next step is Project SDK and Additional Libraries and Frameworks |
| 22:41 | Trioxin | oh he's doing the same thing I am |
| 22:41 | oddcully | cfleming: yes. it's project sdk (1.8 here) and then it provides only java ee BS |
| 22:41 | cfleming | Right. |
| 22:41 | oddcully | this is on linux, if you mind |
| 22:41 | Trioxin | same on windows |
| 22:41 | cfleming | Where are you seeing the Java EE stuff? |
| 22:41 | cfleming | Under "Additional Libraries and Frameworks"? |
| 22:41 | Trioxin | hold on ill screencast it again and try the leiningen |
| 22:42 | oddcully | cfleming: configure your idea to start up where the projects get picked |
| 22:42 | cfleming | oddcully: I don't understand what you mean |
| 22:42 | oddcully | iirc there is some switch that prevents loading the last project |
| 22:42 | cfleming | Oh, right |
| 22:42 | cfleming | Ok |
| 22:42 | cfleming | One sec |
| 22:43 | Trioxin | in my case there is no last project |
| 22:43 | oddcully | cfleming: isn't it way to early in the morning in jolly good england? |
| 22:43 | cfleming | Ok, let's go though this together |
| 22:43 | cfleming | oddcully: It would be, but I'm in jolly good New Zealand |
| 22:43 | Trioxin | ok lol |
| 22:44 | oddcully | in that case... i'm way to early in the morning... |
| 22:44 | oddcully | once you are at that |
| 22:44 | cfleming | Ok, so I'm on the "Welcome to IntelliJ" screen, previous project list on the left, IntelliJ logo on the right |
| 22:44 | oddcully | "idea startup screen thingy" |
| 22:44 | cfleming | Create New Project |
| 22:44 | oddcully | pick ``create new project'' |
| 22:44 | cfleming | Leiningen |
| 22:45 | cfleming | Choose your SDK |
| 22:45 | oddcully | for me there is regardless what i pick ``java ee'' |
| 22:45 | cfleming | oddcully: Can you send a screenshot of what you're seeing? |
| 22:45 | oddcully | e.g. if i pick gradle, there is gradle stuff... |
| 22:45 | oddcully | for leinigen there is only revolting java ee stuff |
| 22:46 | cfleming | oddcully: I need a screenshot to know what you're seeing |
| 22:46 | Trioxin | here's what he's doing |
| 22:46 | Trioxin | http://screencast.com/t/nEzBL05ONJ |
| 22:46 | cfleming | Trioxin: Thanks |
| 22:47 | Trioxin | ;) |
| 22:47 | cfleming | Ok, so that's all under additional libs and frameworks, you don't want any of that |
| 22:47 | cfleming | It's all unselected by default |
| 22:48 | oddcully | well without a flash player i can not confirm it... |
| 22:48 | cfleming | Just press next after doing the SDK |
| 22:48 | cfleming | You should see Project name: Project location: Template: Template options: |
| 22:49 | Trioxin | yes |
| 22:49 | cfleming | So if you just want a basic project, give it a name and location and press Finish |
| 22:49 | cfleming | If you want to use a lein template, enter its name and any args it needs |
| 22:51 | Trioxin | eh. i used an uppercase char |
| 22:51 | Trioxin | there's an iml file |
| 22:52 | cfleming | The iml file is the IntelliJ module file |
| 22:53 | cfleming | You don't care about that |
| 22:53 | cfleming | Your namespaces will be under the src and test directories |
| 22:53 | Trioxin | oh wait |
| 22:53 | Trioxin | i did it without the uppercase erorr. now much more files |
| 22:54 | Trioxin | a project.clj file |
| 22:54 | Trioxin | src |
| 22:54 | Trioxin | core.clj |
| 22:54 | justin_smith | oh, yeah, it probably would not like a capitalized name |
| 22:55 | Trioxin | oh I have a hello world app |
| 22:55 | oddcully | cfleming: i can confirm, that clicking ``next'' and ignoring the java ee ends up in a clojure prohect |
| 22:55 | Trioxin | and my own namespace |
| 22:55 | cfleming | Nice |
| 22:55 | oddcully | s/h/j/ |
| 22:55 | Trioxin | aaaaaand |
| 22:55 | Trioxin | some code I've never tried to understand sooo |
| 22:55 | Trioxin | lol |
| 22:56 | oddcully | from what is generated this looks like a `lein new xxx` |
| 22:56 | cfleming | Trioxin: Right click on the project.clj file in the root, and select Run REPL for <whatever> |
| 22:56 | cfleming | oddcully: That's exactly what it is |
| 22:57 | oddcully | shall i dare to use e.g. `figwheel` for the template? |
| 22:57 | cfleming | Fortune favours the brave |
| 22:57 | justin_smith | haha |
| 22:57 | Trioxin | the result of that didn't run my code |
| 22:57 | Trioxin | it ran some server |
| 22:57 | Trioxin | then gave me the clojure version |
| 22:57 | cfleming | Trioxin: And gave you a window on the right? |
| 22:58 | Trioxin | yeah |
| 22:58 | oddcully | works fine too... |
| 22:58 | cfleming | Trioxin: That's what you want. Now you're ready for a Clojure 101 tutorial. |
| 22:59 | Trioxin | oh but my binary or jar or whatever... something was just compiled right? |
| 22:59 | justin_smith | Trioxin: clojure has a repl |
| 22:59 | oddcully | cfleming: get lost of that java ee stuff... it's scary sh** |
| 22:59 | justin_smith | Trioxin: the repl compiles forms as you enter them |
| 23:00 | Trioxin | i was expecting hello world |
| 23:00 | justin_smith | Trioxin: the idea is that you can use the repl to interactively define things, and then use the things that work to build up your app |
| 23:00 | cfleming | oddcully: I can't do anything about that, if you never use J2EE just uninstall the J2EE plugins and you won't see that. |
| 23:00 | justin_smith | Trioxin: you can run your -main to get the hello world |
| 23:00 | oddcully | cfleming: and while you are here... can we assume, that "current-2 years" will be the target for cursive for idea? |
| 23:00 | justin_smith | Trioxin: but that's not what the repl does right away |
| 23:01 | cfleming | oddcully: Yeah, last two major versions. Currently I sort-of support 12.1 but that's going away soon. 13.1 support will go away when 15 becomes GA |
| 23:01 | Trioxin | i get what you're saying but how do I run the existing code? |
| 23:01 | justin_smith | Trioxin: what namespace is your repl in (you can tell from the prompt) |
| 23:01 | justin_smith | if it's in your core namespace, you can run (-main) |
| 23:01 | cfleming | justin_smith: Trioxin: actually in the title of the REPL tab |
| 23:01 | cfleming | In Cursive |
| 23:01 | justin_smith | cfleming: oh, OK :) |
| 23:01 | oddcully | cfleming: cool. i'd rather buy cursive than 15 |
| 23:02 | cfleming | Trioxin: click in your main editor window |
| 23:02 | cfleming | Trioxin: Then Tools->REPL->Load File in REPL |
| 23:02 | Trioxin | im in core. i just ran core and it exited with code 0 and showed that in bottom console |
| 23:02 | Trioxin | oh k |
| 23:03 | cfleming | That will load your code into the REPL |
| 23:03 | Trioxin | it's loaded |
| 23:03 | cfleming | Then Tools->REPL->Switch NS to current file |
| 23:03 | cfleming | You should see the REPL NS change to the NS of your file |
| 23:04 | Trioxin | yes |
| 23:04 | cfleming | blah.blah.core, probably |
| 23:04 | cfleming | Ok, now you have your code from your editor loaded, and your REPL is in the same NS. |
| 23:04 | cfleming | Go to the REPL editor at the bottom right, and type (my-function), or whatever your function is called - I don't recall what lein generates off the top of my head |
| 23:05 | Trioxin | foo |
| 23:05 | cfleming | Ok, (foo) then |
| 23:05 | Trioxin | i did but it didn't do anything |
| 23:05 | cfleming | Sorry guys, I have to go |
| 23:05 | Trioxin | i just typed it |
| 23:06 | Trioxin | it autocompleted |
| 23:06 | cfleming | Hit Cmd-Enter |
| 23:06 | cfleming | Or Ctrl-Enter if you're on Win/Linux |
| 23:07 | oddcully | (inc cfleming) |
| 23:07 | oddcully | lazy bumbot |
| 23:07 | cfleming | You should also be able to type (+ 1 2) and hit Cmd/Ctrl-Enter and see 3 come out. |
| 23:07 | cfleming | Aww man, my fake internet points!!! |
| 23:08 | ro50 | Hi everyone I'm a linux noob...when I tried to install leiningen the install 'worked' but I could only run lein in sudo mode |
| 23:08 | justin_smith | cfleming: I'll make sure you get them eventually |
| 23:08 | amalloy | ro50: you used apt-get? |
| 23:08 | justin_smith | ro50: it's better to just install lein to your ~/bin/ and not do a system wide install |
| 23:08 | ro50 | I tried from the web site, apt get doesnt have version 2.x |
| 23:08 | amalloy | well that's good |
| 23:08 | cfleming | Ok, I really do have to go. Trioxin: assuming you can execute things there, check out Aphyr's Clojure from the ground up, or Clojure for the Brave and True, and just ignore the bit where it tells you to install Emacs :) |
| 23:09 | justin_smith | ro50: that's the right way, lein manages it's own version better than linux would do it for you |
| 23:09 | Trioxin | k thanks |
| 23:09 | oddcully | apt-get lein? that would get you lein 0.01?! |
| 23:09 | ro50 | in ~/bin/ the ~ refers to the 'home ' folder? |
| 23:09 | justin_smith | ro50: right, and make sure that is on your path too of course |
| 23:09 | oddcully | ro50: yes, ~ is $HOME |
| 23:10 | justin_smith | the idea is to have it be executable, but belonging to your user only |
| 23:10 | ro50 | ok ~ is home of my normal account is / is root of the entire os right |
| 23:10 | justin_smith | ro50: right |
| 23:10 | ro50 | my home folder doesnt have a /bin so i make one |
| 23:10 | justin_smith | yup |
| 23:11 | justin_smith | ro50: many linux distros come with a shell set up to add ~/bin/ to your PATH at startup if it exists |
| 23:11 | justin_smith | but this is easy to fix if yours does not |
| 23:11 | justin_smith | s/startup/initial login/ |
| 23:12 | Trioxin | Hello World! |
| 23:13 | Trioxin | finally |
| 23:13 | ro50 | ok I installed it but it says lein is not currently installed |
| 23:13 | Trioxin | don't know why a hello world needs an argument but okay |
| 23:13 | ro50 | when I type lein in the terminal |
| 23:13 | Trioxin | oic it concatenated |
| 23:13 | Trioxin | sweeeeeeet |
| 23:14 | justin_smith | ro50: is your ~/bin in the $PATH variable in the shell? |
| 23:14 | ro50 | uh im not sure |
| 23:14 | oddcully | ro50: in a _new_ terminal try `which lein` |
| 23:14 | ro50 | nothing happens |
| 23:15 | ro50 | after typing $PATH I get: me@me ~ $ $PATH bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin: No such file or directory |
| 23:15 | justin_smith | also double check that ~/bin/lein is executable, and then check that ~/bin/ is on your path (you can use echo $PATH to do that) |
| 23:15 | justin_smith | ro50: oh, you can also get your PATH from an error message :) |
| 23:15 | justin_smith | so no, ~/bin/ is not on your path, and you need to add it |
| 23:15 | justin_smith | in your shell you can do PATH=$PATH:~/bin/ |
| 23:16 | justin_smith | to make this happen automatically it can be added to your shell init file, usually .bashrc or .login or .profile or something |
| 23:16 | justin_smith | (all will be hidden files in your home directory) |
| 23:18 | ro50 | oh there is already something in there for that |
| 23:18 | ro50 | i will try reset and see if it works |
| 23:18 | ro50 | brb |
| 23:19 | justin_smith | oh man he left before I could tell him about "bash -l" |
| 23:19 | oddcully | he'l be right back |
| 23:20 | justin_smith | oddcully: right, but he didn't need to reboot |
| 23:20 | justin_smith | or whatever he thought he had to do |
| 23:20 | oddcully | he is doing the ole windowsaroo: reboot to update the env |
| 23:20 | justin_smith | the ms-dance |
| 23:21 | Trioxin | so, I'm used to curly braces and this defn shows the closing ) on the same line as the last statement in it. Is it bad form to close the function on the next line? |
| 23:22 | justin_smith | Trioxin: yup |
| 23:22 | Trioxin | whyyyyyyyyyyyy |
| 23:22 | justin_smith | Trioxin: we have different standards around here |
| 23:22 | justin_smith | Trioxin: I like it because it means I don't get confused about which kind of code I'm reading |
| 23:23 | justin_smith | (if the braces are on their own lines, I'm reading an algol, if on the same line, I'm reading a lisp) |
| 23:23 | rem500 | hi got it working thanks everyone |
| 23:23 | justin_smith | rem500: cool, right as you left I was like "use bash -l instead of logging out or rebooting" but I was too late |
| 23:23 | justin_smith | lol |
| 23:24 | rem500 | has anyone else read the leiningen vs the ants story it's good |
| 23:24 | oddcully | rem500: kindled it |
| 23:24 | justin_smith | yup, that's where the name of our build tool comes from - ant is a popular build tool for java |
| 23:24 | oddcully | justin_smith: also salve |
| 23:25 | TEttinger | Trioxin: I totally used to feel that way. I quickly got accustomed to closing parens on the same line because it saves a lot of space |
| 23:25 | justin_smith | oddcully: salve? |
| 23:25 | oddcully | justin_smith: vim-salve |
| 23:25 | Trioxin | is "I don't do a whole lot." here a comment? http://hastebin.com/purosucode.lisp |
| 23:25 | TEttinger | docstring |
| 23:26 | justin_smith | Trioxin: it's considered the official documentation of that function |
| 23:26 | Trioxin | oooo |
| 23:26 | justin_smith | Trioxin: you can look up doc for functions using the doc function too |
| 23:26 | justin_smith | ,(doc +) |
| 23:26 | TEttinger | ,(defn foo "I don't do a whole lot." [x] (println x "Hello, World!")) |
| 23:26 | clojurebot | "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'" |
| 23:26 | TEttinger | ,(doc foo) |
| 23:26 | clojurebot | Excuse me? |
| 23:26 | clojurebot | #'sandbox/foo |
| 23:26 | Trioxin | well, I hope I like this enough to not want to go to CL |
| 23:26 | TEttinger | ,(doc foo) |
| 23:26 | clojurebot | "([x]); I don't do a whole lot." |
| 23:26 | TEttinger | there we go |
| 23:27 | justin_smith | Trioxin: cursive will use doc-strings for help popups iirc |
| 23:27 | rem500 | I tried to learn clojure a month or so ago but now im back even though I'm busy |
| 23:27 | TEttinger | Trioxin: it's definitely an active community here. not sure if the same can truly be said of CL, which has been a bit more subdued I would say |
| 23:28 | Trioxin | i really wanted to try lispworks but it was a billion dollars |
| 23:28 | TEttinger | you're more likely to find up-to-date libs in clojure than for CL, I would say. |
| 23:28 | rem500 | i never thought id see a lisp make a comeback |
| 23:28 | oddcully | Trioxin: better pay cfleming |
| 23:28 | Trioxin | i can use all that is java in clojure right? |
| 23:28 | TEttinger | yes |
| 23:29 | TEttinger | also, technically, all that is Scala or Groovy or any JVM language, though Java remains the easiest to call |
| 23:29 | justin_smith | clojure / java interop works very nicely going both directions |
| 23:29 | justin_smith | others might not be as easy (scala makes things harder then they should be to be sure) |
| 23:29 | Trioxin | interesting |
| 23:29 | TEttinger | Olajyd used the Scala Storm stuff from Clojure, that was... interesting |
| 23:30 | TEttinger | it worked though |
| 23:30 | Trioxin | what about mobile dev how is that coming? |
| 23:30 | Trioxin | i see lein-fruit and something for android |
| 23:31 | Trioxin | goby |
| 23:31 | justin_smith | yeah, there are projects, I've only done things with mobile via web-apps myself |
| 23:31 | TEttinger | I think, as for many many platforms, the best approach is "make a web app that the user can view on mobile and on desktop." and clojure has excellent support for that via clojurescript |
| 23:31 | Trioxin | clochure |
| 23:31 | justin_smith | TEttinger: exactly, that's what's worked for me |
| 23:31 | oddcully | i put some cljs stuff up for me mobile dudes. my last mobie projects made made me imagine killing people |
| 23:32 | TEttinger | there are also various things that let you convert a webpage to a web app. I believe Intel's XDK consumed Appcelerator Titanium |
| 23:32 | Trioxin | well I write all my mobile in HTML5 using cordova but I was thinking for heavy lifting... |
| 23:32 | TEttinger | yep, clojure works well on servers |
| 23:32 | Trioxin | or maybe better API access on the mobile platform |
| 23:32 | Trioxin | well, more not better |
| 23:33 | TEttinger | I've had clojure processes open for months without intervention. And, that was on a windows laptop with overheating issues |
| 23:35 | Trioxin | wonder how hard it would be to port my ANNs from c |
| 23:36 | TEttinger | I'd imagine a rewrite would be easier than a port, myself. probably a lot shorter |
| 23:36 | justin_smith | ANN ? |
| 23:37 | TEttinger | the approaches used in C programs and in Clojure programs are really not at all similar. |
| 23:37 | Trioxin | neural networks. been doing prediction code lately on a side project |
| 23:37 | TEttinger | have you looked at Torch at all? |
| 23:37 | Trioxin | no |
| 23:37 | TEttinger | Torch struck me as unusually high-level Lua meant for neural networks and other scientific code |
| 23:38 | TEttinger | also it has GPU acceleration for CUDA stuff |
| 23:38 | Trioxin | I started with matlab |
| 23:38 | Trioxin | torch seems cool |
| 23:41 | TEttinger | there's some stuff in that area for clojure but I haven't looked into it as much |
| 23:42 | oddcully | i'm parsing factorio files with instaparse... i hope there is some jlua... |
| 23:42 | TEttinger | I've found clojure is really really good for writing complex collection heavy code without making your brain explode |
| 23:42 | TEttinger | the immutable collections are a big contributor to brain stability |
| 23:43 | Trioxin | i see clojure has been used in robotics, that's good |
| 23:43 | justin_smith | can verify, I have an explosion-prone brain and clojure is very nice about not lighting the wick |
| 23:44 | justin_smith | or was that "can verify, am exploded brain" |
| 23:44 | Trioxin | well it doesn't look too touch. I'm sure if I can learn all these other languages I can get this |
| 23:45 | Trioxin | i'm just wanting it mostly for the paradigms |
| 23:45 | TEttinger | clojure's also hilariously good at code golf. some CL people described Clojure as a Lisp meant for writing one-liners :) |
| 23:45 | TEttinger | (part of the joke being that any lisp program can be rewritten as a one-liner) |
| 23:45 | TEttinger | (for very long lines) |
| 23:47 | Trioxin | after this I'll get into python and then my brain will be complete with programming. I've stuck with the same languages for too long and all these papers come out in PY and ppl talking about lisp paradigms. must not miss out |
| 23:51 | Trioxin | will it be difficult to understand CL knowing clojure? |
| 23:51 | Trioxin | wow you weren't overselling the java interop. that was ez |
| 23:52 | justin_smith | in my experience using clojure after common lisp and scheme, there was a break in period of being constantly annoyed about minor syntax differences, followed by everything being easy because the core building blocks were the same. |
| 23:53 | Trioxin | fair enough |
| 23:53 | justin_smith | though CL and even scheme use mutable data structures much more than we do in clojure, so they make a wider variety of programming styles possible that don't work as nicely in clojure |
| 23:54 | justin_smith | the tradeoff is that due to clojure being more constricted in style we get nice things like easy concurrency (due to eschewing the things that make concurrency really hard, like rampant mutation of data) |
| 23:54 | justin_smith | Trioxin: it is easy to code CL or scheme as if they are clojure, coding clojure like one of the others is a bit harder |
| 23:55 | justin_smith | (and probably not a good idea even when it isn't hard) |