2015-03-29
| 13:43 | danlentz | I'm self taught, so I'm quite aware of what a prick I can be as a teacher. |
| 13:46 | danlentz | Also as a student. Hmmm. |
| 13:46 | justin_smith | danlentz: realizing I can be a jerk has been a repeated theme as I grow older, it comes back in so many nuanced varieties. |
| 13:48 | gfredericks | it culminates at your death bed when you realized you never actually succeeded at not being a jerk at all ever not even once |
| 13:48 | justin_smith | haha |
| 13:48 | danlentz | In that final realization, you attain humanity |
| 13:49 | danlentz | Wait, wasn't that what happend to Spock? |
| 13:56 | joe124 | http://pastebin.com/dECUn04R why is this not tail position? |
| 13:57 | joe124 | brb |
| 13:57 | mavbozo | parens solve everything? |
| 13:57 | justin_smith | joe124: (( means you are calling something, then calling what it returns |
| 13:58 | joe124 | ok i removed extra parens around the if statement? |
| 13:58 | justin_smith | joe124: it's not tail position, because your code wants to call it |
| 13:58 | justin_smith | now you'll likely see an error with (result ...) because result is a collection |
| 13:59 | justin_smith | well, depending on the arg, I guess the arg could be a number, then you just get a nil... |
| 13:59 | joe124 | i have an out of bounds exception |
| 13:59 | justin_smith | what do you intend (result(last coll)) to do? |
| 14:00 | joe124 | i want to append the last element of coll to result |
| 14:00 | justin_smith | joe124: how would clojure know you wanted that, and not calling result as a function? |
| 14:00 | justin_smith | because that syntax means a function call, right? |
| 14:00 | joe124 | well earlier result was defined as [] |
| 14:00 | joe124 | and [] is a function |
| 14:01 | justin_smith | yes, but it doesn't do what you want |
| 14:01 | joe124 | should i use conj or something |
| 14:01 | justin_smith | ,([] 3 :out-of-bounds) |
| 14:01 | clojurebot | #error{:cause "Wrong number of args (2) passed to: PersistentVector", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: PersistentVector", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 36] [sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compi... |
| 14:01 | justin_smith | oops |
| 14:01 | danlentz | (foo ) invokes a function foo |
| 14:01 | justin_smith | ,([] 3) |
| 14:01 | clojurebot | #error{:cause nil, :via [{:type java.lang.IndexOutOfBoundsException, :message nil, :at [clojure.lang.PersistentVector arrayFor "PersistentVector.java" 152]}], :trace [[clojure.lang.PersistentVector arrayFor "PersistentVector.java" 152] [clojure.lang.PersistentVector nth "PersistentVector.java" 156] [clojure.lang.APersistentVector invoke "APersistentVector.java" 283] [sandbox$eval49 invoke "NO_SOUR... |
| 14:01 | justin_smith | so that's your error |
| 14:01 | joe124 | yes |
| 14:02 | justin_smith | joe124: so yeah, ##(conj [] 3) is likely what you want |
| 14:02 | lazybot | ⇒ [3] |
| 14:03 | danlentz | It would be funnier if somehow the Chinese could launch an attack on Gravatar and give us embarrassing icons |
| 14:03 | joe124 | ok cool it worked, but i had defined result as []. So why does it work when the input is a list? |
| 14:04 | justin_smith | joe124: can you rephrase that? |
| 14:04 | joe124 | https://www.4clojure.com/problem/23#prob-title |
| 14:04 | justin_smith | do you mean, how can it take things out of a list and put them in a vector? |
| 14:05 | joe124 | (= '(1 2 3) [1 2 3]) ? |
| 14:05 | justin_smith | ,(= '(1 2 3) [1 2 3]) |
| 14:05 | clojurebot | true |
| 14:05 | joe124 | ok well that solves that haha |
| 14:05 | gratimax | when checking for equality, you don't care about the type of the sequence |
| 14:05 | justin_smith | joe124: my favorite definition for reverse is (partial into ()) |
| 14:05 | justin_smith | joe124: but that is way over your head for now |
| 14:06 | joe124 | ok let me look up partial and into then maybe u explain it to me? |
| 14:06 | justin_smith | joe124: sure, feel free to ask any follow up you need |
| 14:08 | danlentz | ,((partial into ()) (range 8)) |
| 14:08 | clojurebot | (7 6 5 4 3 ...) |
| 14:08 | justin_smith | danlentz: of course as a literal you can just do ##(into () (range 10000)) |
| 14:08 | lazybot | ⇒ (9999 9998 9997 9996 9995 9994 9993 9992 9991 9990 9989 9988 9987 9986 9985 9984 9983 9982 9981 9980 9979 9978 9977 9976 9975 9974 9973 9972 9971 9970 9969 9968 9967 9966 9965 9964 9963 9962 9961 9960 9959 9958 9957 9956 9955 9954 9953 9952 9951 9950 9949 9948 9947 9... https://www.refheap.com/99036 |
| 14:09 | ggherdov | Hello. I googled "rest api clojure" and got to https://mmcgrana.github.io/2010/08/clojure-rest-api.html (the post is from 2010) |
| 14:09 | ggherdov | question: in the toy example the author wraps the data he's exposing over the API in an atom. |
| 14:09 | ggherdov | Is that because he wants to prevent concurrent http requests to have inconsistent views of the data? Is that what one would do in a "real world app" as well, where the data comes from a db? |
| 14:09 | tahmid | When’s a good time to learn macros ? |
| 14:10 | justin_smith | ggherdov: I think the atom is just for representing a state that PUT etc. can manipulate |
| 14:10 | swarthy | ggherdov: He likely did it because he wanted a mutable piece of data that he could add to by hitting the rest API. |
| 14:10 | danlentz | tahmid: we call that macroexpansion time |
| 14:10 | swarthy | ggherdov: in production you would just update/read from your DB |
| 14:10 | tahmid | LOL |
| 14:10 | ggherdov | justin_smith: swarthy: ah right |
| 14:11 | danlentz | You should be really comfortable using functions |
| 14:11 | justin_smith | ggherdov: but, bigger picture, in clojure we almost always put something that we expect to mutate in runtim inside an atom, or ref, or agent, because they have good behavior when interacting with updates from multiple threads |
| 14:11 | ggherdov | justin_smith: ok |
| 14:11 | tahmid | I am really comfortable using funcions |
| 14:11 | justin_smith | so in that sense you are right, we could have used a mutable java data structure or class instead, but it would not likely be as well behaved |
| 14:12 | justin_smith | tahmid: I'd use macros when you have the functionality dialed in, but usage is clumsy and could be fixed if you could modify syntax |
| 14:12 | tahmid | I mean when should one try to solve something with macro ? |
| 14:12 | danlentz | The best way to approach macros is to look at examples and build up practice examples |
| 14:12 | justin_smith | tahmid: for example not needing to quote an arg, or just specifying optional forms instead of functions to call as args |
| 14:12 | tahmid | justing_smith: Okay, got my ans |
| 14:12 | danlentz | When it cannot be done with a function |
| 14:13 | joe124 | ,((partial into ()) '(1 2 3)) |
| 14:13 | clojurebot | (3 2 1) |
| 14:13 | tahmid | Cool |
| 14:14 | mavbozo | ,into |
| 14:14 | clojurebot | #object[clojure.core$into "clojure.core$into@2f18c986"] |
| 14:14 | mavbozo | ,(doc into) |
| 14:14 | clojurebot | "([to from] [to xform from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined. A transducer may be supplied." |
| 14:14 | joe124 | ,((into ()) '(1 2 3)) |
| 14:14 | clojurebot | #error{:cause "Wrong number of args (1) passed to: core/into", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (1) passed to: core/into", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 32] [sandbox$eval93 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784... |
| 14:14 | danlentz | When you are in some way looking to change the normal syntax of clojure |
| 14:14 | joe124 | ,(into () '(1 2 3)) |
| 14:14 | clojurebot | (3 2 1) |
| 14:14 | joe124 | ,(into () [1 2 3]) |
| 14:14 | clojurebot | (3 2 1) |
| 14:14 | oddcully | ,(doc conj) ? |
| 14:14 | clojurebot | "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type." |
| 14:15 | justin_smith | ,(into '(1 2) 3) ; joe124 |
| 14:15 | clojurebot | #error{:cause "Don't know how to create ISeq from: java.lang.Long", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: java.lang.Long", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.core$seq__4079 invoke "core.clj" 135] [clojure.core.protocols$seq_reduce invoke ... |
| 14:15 | justin_smith | oops, I mean ##(into '(1 2) [3]) |
| 14:15 | lazybot | ⇒ (3 1 2) |
| 14:16 | joe124 | since lists and stuff are immutable does into do the exact same thing as reverse |
| 14:16 | mavbozo | ,((partial into []) '(1 2 3)) |
| 14:16 | clojurebot | [1 2 3] |
| 14:16 | danlentz | Macros (generally) operate programmatically on the source code of your program, rather than directly contributing to computing the result |
| 14:16 | tahmid | that’s why I am scared of macros |
| 14:16 | joe124 | if you write your macro wrong it will delete your program |
| 14:17 | justin_smith | joe124: the implementation is not exactly the same, but the behavior is |
| 14:17 | joe124 | and auto save over it |
| 14:17 | danlentz | Delete your program? |
| 14:17 | tahmid | I read in somewhere that I should always prioritize data over functions over macros |
| 14:18 | mavbozo | i am still scared of macros |
| 14:18 | justin_smith | joe124: do you know about clojure.repl/source ? if you look at the source of reverse, and the source of into, you should be able to see that (partial into ()) and reverse are very close to being identical when you go down a couple layers |
| 14:18 | justin_smith | tahmid: that is solid advice |
| 14:18 | justin_smith | mavbozo: that's healthy |
| 14:19 | tahmid | I understand the function part |
| 14:19 | tahmid | But how can data > function |
| 14:19 | danlentz | Macros are really nice in clojure |
| 14:19 | justin_smith | tahmid: there are a lot of things we can do with data, that we can't do to functions |
| 14:19 | tahmid | I mean datas are just data |
| 14:19 | tahmid | example pls |
| 14:19 | justin_smith | and similarly, there are a lot of things we can do with functions, that we can't do with macros |
| 14:22 | justin_smith | tahmid: ##(do (require 'clojure.walk 'clojure.string) (clojure.walk/postwalk (fn [x] (if (string? x) (clojure.string/reverse x) x)) {"hello" {:a "world"}}) |
| 14:22 | Jaood | tahmid: why do you mean by data? functions operate on data |
| 14:23 | justin_smith | tahmid: we can scramble, reorganize, store and retrieve, query from users, aggregate and analyze |
| 14:23 | justin_smith | tahmid: you don't have the same flexibility with functions |
| 14:23 | bbloom | when clojure ppl say "data" in this context they are referring to a particular style of data |
| 14:24 | justin_smith | we don't even have useful equality predicates for functions, other than object identity |
| 14:24 | tahmid | WoW never thought of that way before |
| 14:24 | bbloom | in particular, 1) immutable values with 2) structural equality and 3) printable/readable representations |
| 14:24 | justin_smith | (inc bbloom) |
| 14:24 | lazybot | ⇒ 51 |
| 14:24 | justin_smith | very important point, thanks |
| 14:24 | tahmid | Yes you are write I can store pass and scramble data |
| 14:24 | justin_smith | yup |
| 14:24 | mavbozo | (inc bbloom) |
| 14:24 | lazybot | ⇒ 52 |
| 14:24 | tahmid | lol what am I writing |
| 14:25 | justin_smith | then, functions we can compose, pass as first class values at runtime - these things don't work so nicely with macros |
| 14:26 | tahmid | guys why are you increasing people’s name ? |
| 14:26 | tahmid | oh I get it |
| 14:26 | justin_smith | tahmid: fake internet points |
| 14:26 | tahmid | (inc bbloom) |
| 14:26 | lazybot | ⇒ 53 |
| 14:26 | tahmid | (inc justin_smith) |
| 14:26 | lazybot | ⇒ 224 |
| 14:27 | danlentz | CL can pass macros as first class values |
| 14:27 | swarthy | there are some pretty cool white papers on something called Language Oriented Programming that I read recently. They have altered my views a bit such that now I ask, "Can I solve this problem with Clojure the language?" When the answer is no, I then create the missing piece of the language with a macro. The answer however is usually: yes I can do it in clojure. |
| 14:27 | danlentz | Well, there is macro-function |
| 14:28 | danlentz | swarthy: that's what I love about lisp |
| 14:28 | bbloom | danlentz: macro-function isn't exactly what ppl would consider first class macros |
| 14:28 | danlentz | Yes |
| 14:28 | danlentz | bbloom: I was sorry I made the point |
| 14:29 | bbloom | danlentz: we can do macro-function in clojure too |
| 14:29 | danlentz | First class macros are FEXPRS |
| 14:29 | bbloom | @(find-var `binding) |
| 14:29 | bbloom | danlentz: fexprs are a little different than first-class macros too |
| 14:30 | bbloom | ,@(find-var `binding) |
| 14:30 | clojurebot | #object[clojure.core$binding "clojure.core$binding@5996f646"] |
| 14:31 | bbloom | ,(@(find-var `binding) nil nil '[x 1 y 2] '(+ x y)) ; heh, don't try this (impl detail) at home |
| 14:31 | clojurebot | (clojure.core/let [] (clojure.core/push-thread-bindings (clojure.core/hash-map (var x) 1 (var y) 2)) (try (+ x y) (finally (clojure.core/pop-thread-bindings)))) |
| 14:33 | danlentz | Yes I see regarding FEXPRS |
| 14:34 | danlentz | Something I've clearly not gotten to use in real life |
| 14:35 | bbloom | i'm not sure anyone in the last few decades has really :-) |
| 14:35 | danlentz | Kernel |
| 14:35 | danlentz | I think it's called. |
| 14:36 | danlentz | http://web.cs.wpi.edu/~jshutt/kernel.html |
| 14:37 | bbloom | there's no "real life" implementation of it, for a value of "real life" that equals "actually useful" |
| 14:37 | bbloom | danlentz: i've built a handful of kernel-style interpreters ;-) |
| 14:42 | danlentz | There was an experimental build of SBCL a few years ago I think, but obviously it was just a curiosity |
| 14:46 | tahmid | is ed an editor for clojure ? |
| 14:46 | justin_smith | ed is a text editor, and I think it is mocked more often than used |
| 14:46 | justin_smith | it doesn't have any language specific features |
| 14:49 | justin_smith | if I had to use an editor from within my repl, I would probably pick ed |
| 14:50 | tahmid | I was reading clojure irc log and someone mentioned ed |
| 14:50 | bensu | Does anybody have experience with the timber logging library? |
| 14:50 | ticking_ | timbre? |
| 14:50 | justin_smith | tahmid: it was probably a joke |
| 14:50 | clojurebot | timbre is awesome if you are tired of java logging (c.f. java logging) |
| 14:50 | bensu | ticking: yeah! timbre |
| 14:51 | ticking_ | bensu: yeah it's nice |
| 14:53 | bensu | ticking_: I'm thinking of storing my logs in DynamoDB or S3. Do you think I'll can with timbre? |
| 14:54 | bensu | *I'll be able |
| 14:54 | justin_smith | bensu: yeah, that can be done, it's just a clojure-friendly config frontend for java logging |
| 14:54 | justin_smith | and java can log to just about anything |
| 14:55 | bensu | justin_smith: I thought it was *all* Clojure and that clojure.logging was the wrapper over java |
| 14:56 | ticking_ | bensu: yeah you can just write a custom appender |
| 14:56 | ticking_ | https://github.com/ptaoussanis/timbre/tree/master/src/taoensso/timbre/appenders |
| 14:56 | justin_smith | bensu: timbre uses jvm logging |
| 14:56 | ticking_ | a bunch of example appenders |
| 14:58 | bensu | justin_smit: I guess I misread the README. I'm not sure what "Small, uncomplicated all-Clojure library." means |
| 14:58 | bensu | justin_smith: I thought that meant it implemented it's own thing. |
| 15:00 | bensu | ticking_: thanks, I looked at those but I'm not yet familiar with the abstractions, so I don't really understand the code. |
| 15:00 | bensu | ticking_: I'll have to dive in and try until I get it. |
| 15:00 | bensu | ticking_ justin_smith: Thanks for your help! |
| 15:01 | ticking_ | justin_smith: I don't think so, timbre doesn't use java logging internally |
| 15:01 | ticking_ | bensu: you're right I think |
| 15:02 | ticking_ | bensu: tibre has this simple concept of appenders, which is just a function that will get called when a log occurs |
| 15:02 | ticking_ | you can do whatever you want in there |
| 15:02 | ticking_ | it's also doccumented in the timbre readme |
| 15:03 | justin_smith | ticking_: hmm, I was looking for the proof that it used java logging, but yeah, not finding it - I'll have to figure out how I got confused |
| 15:03 | justin_smith | ticking_: I wonder if this changed at some point? |
| 15:03 | ticking_ | would have to be a long time ago I guess |
| 15:03 | ticking_ | I fixed a big a 2 years ago or something like that, and it wasn't using logging back then I think |
| 15:04 | justin_smith | ticking_: in that case I was just wrong, thanks |
| 15:04 | danlentz | I recently had a pretty unpleasant experience with log4j/slf4j |
| 15:05 | justin_smith | I have a syslog appender in caribou.logger that I should totally adapt for timbre and submit there |
| 15:05 | ticking_ | justin_smith: There are mentions of tool.logging all thoughout the codes comments though :/ |
| 15:05 | justin_smith | ticking_: that could be it - via tools.logging it can end up using log4j ? |
| 15:05 | ticking_ | yeah I think so |
| 15:06 | danlentz | In general. Nothing specific, but some really sticky conflicts in transitive dependencies with Datomic |
| 15:06 | justin_smith | when was tools.logging made optional? that would make me feel less stupid if that was some time in the last year or so |
| 15:07 | justin_smith | anyway, syslog appending is handy, I should submit that to timbre |
| 15:07 | danlentz | justin_smith: you are caribou? |
| 15:07 | justin_smith | danlentz: not the founder, but one of the core devs |
| 15:07 | danlentz | Nice |
| 15:08 | justin_smith | danlentz: we lost our corporate funding, so it hasn't been as active in the last year or so |
| 15:09 | danlentz | If people ask why the project is not more active, just tell them it's because the code is already near perfect |
| 15:09 | justin_smith | oh man I would die of hypocrisy |
| 15:10 | danlentz | Ive seen great deal of evidence that hypocrisy is not fatal. |
| 15:11 | danlentz | I thought it had a nice "product launch" |
| 15:11 | danlentz | Very clean, well presented |
| 15:12 | tahmid | Me too |
| 15:12 | tahmid | I wanted to use caribou in prod |
| 15:13 | tahmid | But later used plain ring |
| 15:13 | danlentz | I think you guys go about this ass-backwards. I'm going to pick the animal first, then come up with some kind of software to write for it to represent |
| 15:14 | danlentz | (Going off to create http://github.com/danlentz/clj-naked-mole-rats) |
| 15:15 | tahmid | (page-not-found github is under ddos ) |
| 15:17 | danlentz | tahmid: sorry i was just joking about all of the animal-named projects |
| 15:18 | justin_smith | danlentz: tahmid: thanks, patchwork definitely put a lot of work into the docs and the frontend design |
| 15:18 | justin_smith | danlentz: no joke, this is really how caribou was named |
| 15:18 | justin_smith | there was a big taxidermied caribou head on the wall |
| 15:19 | justin_smith | so the lib got named after it |
| 15:19 | danlentz | Ha poor caribou |
| 15:19 | justin_smith | patchwork is a genius and or madman when it comes to naming things |
| 15:20 | justin_smith | there are certain strings that if you google them are only found in caribou source, and in irc logs asking what the hell the names in the caribou source mean |
| 15:20 | justin_smith | :) |
| 15:20 | danlentz | The small print: "Very few animals were beheaded during the implementation of this web framework" |
| 15:21 | justin_smith | $google jopotonio |
| 15:26 | bensu | justin_smith: I didn't know of caribou, it looks pretty cool |
| 15:27 | justin_smith | bensu: thanks, it's very opinionated, but as a bonus it gives you a GUI admin for your data (including modeling data in the gui, and defining routes and pages in the gui and defining where they get their data) right out of the box |
| 15:27 | bensu | dalentz: so log4j doesn't play well with Datomic |
| 15:27 | danlentz | log4j/slf4j is used internally by datomic |
| 15:27 | justin_smith | bensu: in fact, it might be worthwhile to just modularize that admin to be used as a CMS / RAD tool. |
| 15:28 | tahmid | danlentz: is there any uuid generator for cljs ? |
| 15:28 | bensu | dalentz: got it. explains the conflict. |
| 15:29 | danlentz | so if you have another dependency which requires a different version, you have to do a hairy :exclusions kind of thing |
| 15:29 | bensu | justin_smith: I'm definitely gonna checkout the src since the admin side of things is universal |
| 15:29 | tahmid | justin_smith: how to modularize that admin to be used as CMS / RAD tool ? |
| 15:30 | danlentz | tahmid: good question |
| 15:30 | justin_smith | bensu: well, specifically the way you can define pages / routes etc. in the admin requires some integration, at least with your routing layer |
| 15:30 | justin_smith | tahmid: it is alreayd a CMS / RAD tool, but it would need an adaptor layer to use it with your favorite routing lib, template lib, etc. since otherwise it can't help your with those things. |
| 15:31 | justin_smith | or you can just use caribou. and then use polaris, and antlers, and all these work together already and you have a framework. |
| 15:31 | justin_smith | of course |
| 15:31 | danlentz | hoo-hoo antlers |
| 15:32 | justin_smith | or use the CMS but not its page definition functionality |
| 15:32 | justin_smith | and just use it for data modeling / content entry |
| 15:32 | justin_smith | making it slightly less convenient |
| 15:33 | tahmid | This is the missing part of my clojure web-dev tools |
| 15:33 | tahmid | I find myself moving to django for the admin panel they provide |
| 15:33 | danlentz | in the java mentality if software is not constantly being patched and rewritten it must not be any good |
| 15:33 | tahmid | and then come back to clojur e |
| 15:33 | justin_smith | tahmid: well caribou is out there, and you can use it, and the docs are very good |
| 15:34 | justin_smith | tahmid: we took a lot of ideas from django actually |
| 15:34 | tahmid | What I don’t like about caribou is it’s very tightly coupled |
| 15:34 | justin_smith | we were working on that... |
| 15:34 | tahmid | i want to use aleph with compojure + caribou admin panel |
| 15:34 | danlentz | i think the idea that software may just work well and be stable does not usually occur |
| 15:34 | danneu | pgadmin is my admin panel |
| 15:34 | justin_smith | tahmid: like I said, you totally can just use the admin (plus the data modeling in core) and skip the rest |
| 15:35 | tahmid | I would definitely like to help with modularizing the admin panel |
| 15:35 | tahmid | Okay I am giving it a try now |
| 15:35 | tahmid | Thanks |
| 15:36 | justin_smith | tahmid: oh, that would definitely be welcome. I still am in #caribou last I checked, and will gladly answer any questions that will help get you up and running with that. |
| 15:42 | gfredericks | hello |
| 15:43 | justin_smith | fancy seeing you here |
| 15:44 | not-much-io | Does anyone know why clojure.org is so "bare bones"? I visited haskell.org and felt motivated to learn the language based on the cool homepage. It makes haskell look cool! Superficial reason I know. Still for new people it might be offputting to see this new language they are interested having such a boring homepage. People can be quite shallow like that sometimes. :) |
| 15:45 | bbloom | not-much-io: clojure.org is actually useful |
| 15:45 | bbloom | it's just for a different audience |
| 15:45 | Frozenlock | bbloom: it is? I always considered #clojure to be the official doc. |
| 15:46 | bbloom | Frozenlock: the documentation on clojure.org is excellent |
| 15:46 | justin_smith | not-much-io: I think it's a very different (and pragmatic) design approach. |
| 15:46 | bbloom | it's clear, succinct, and correct |
| 15:47 | justin_smith | not-much-io: I think haskell.org is optimized for your first visit, clojure.org is optimized by your 10th visit, and all following visits |
| 15:47 | justin_smith | Frozenlock: on that note, clojure.org does have a link to this irc on its front page |
| 15:48 | joe124 | ,(reverse (seq "abc")) |
| 15:48 | clojurebot | (\c \b \a) |
| 15:48 | not-much-io | bbloom: I have not really looked at haskell.org in any depth but it SEEMS to be quite "content rich", under the documentation tab and news tab :) |
| 15:48 | joe124 | (reverse "abc") |
| 15:48 | justin_smith | joe124: the seq call there is redundant |
| 15:48 | tahmid | clojure.org is simple made easy |
| 15:48 | joe124 | ,(reverse "abc") |
| 15:48 | clojurebot | (\c \b \a) |
| 15:48 | justin_smith | ,(apply str (reverse "abc")) |
| 15:48 | clojurebot | "cba" |
| 15:48 | Frozenlock | justin_smith: and the cheatsheet points to clojuredocs |
| 15:49 | bbloom | not-much-io: justin_smith is definitely right about visit # optimization. the haskell docs page has a big list of books, courses, tutorials, etc |
| 15:49 | joe124 | in 4clojure problem 27 #(= % (reverse %)) does not work while #(= (seq %) (reverse (seq %)) ) does work |
| 15:49 | not-much-io | justin_smith : Well would it become less pragmatic and useful with some added css? *honest question* |
| 15:49 | bbloom | the references are buried on that page & not really highlighted |
| 15:49 | bbloom | most haskellers know to use hoogle |
| 15:50 | bbloom | and hackage refs |
| 15:50 | justin_smith | not-much-io: it's a good question, it might be worth trying some variant designs and proper UX research to see what is most effective |
| 15:50 | bbloom | not-much-io: by adding visual design, you make information design more rigid |
| 15:51 | mavbozo | not-much-io: is clojure.com style much more preferable to you? |
| 15:51 | justin_smith | not-much-io: my impression is that it may not feel "impressive" but the things that catch my eye when I glance at the page are the useful things I would be looking for |
| 15:51 | bbloom | as it is, Alex Miller (among others) can make changes to clojure.org trivially w/o having to worry about messing up a beautiful page layout |
| 15:52 | justin_smith | bbl, lunch |
| 15:52 | bbloom | the more visual polish you put in to things, the harder they are to change, so you should delay doing it until you understand the information design |
| 15:52 | bbloom | and then you have to ask: what value do i get from spending the effort on visual design? |
| 15:52 | not-much-io | mavbozo : It's kind of what I was thinking. |
| 15:52 | mavbozo | not-much-io: haskell.org website is built from scratch, clojure.org is built from wikispaces |
| 15:52 | bbloom | a few more low quality community participants? *shrug* |
| 15:53 | mavbozo | i think there is a limitation in wikispaces though |
| 15:53 | bbloom | if you want high quality design, check out the cognitect pages |
| 15:53 | bbloom | http://cognitect.com/clojure |
| 15:53 | bbloom | the mission there is to sell you clojure and services |
| 15:53 | bbloom | optimized for first visit |
| 15:53 | joe124 | https://www.4clojure.com/problem/27 why doesn't it work with #(= % (reverse %)) |
| 15:53 | not-much-io | bblook: I have to say, you've made your point about trading information manipulation ability for eye candy |
| 15:53 | dnolen | not-much-io: people are aware of the issue, the lack of an attractive official ClojureScript website is also annoying. Hopefully will eventually get addressed. |
| 15:54 | dnolen | not-much-io: there's no real reason other than, it's a lot of work and hasn't been made a priority |
| 15:55 | Frozenlock | "a few more low quality community participants? *shrug*" o_O |
| 15:55 | bensu | Frozenlock: what do you mean? |
| 15:56 | justin_smith | joe124: (reverse "racecar") is not equal to "racecar" |
| 15:56 | not-much-io | Thanks for the info, I suppose it really is just a pragmatic decision as I suspected. And nice to keep cognitect.com/clojure in your backpocket for showing friends :) |
| 15:56 | Frozenlock | I'm surprised by this sentence. I find it harsh. |
| 15:56 | bbloom | Frozenlock: if a pretty picture is the difference between using clojure and not, then i'd rather not :-P |
| 15:57 | bbloom | i'm not discounting the value of visual design. i'm only making a statement about the value produced in this instance being low |
| 15:57 | mavbozo | ,(reverse "racecar") |
| 15:57 | clojurebot | (\r \a \c \e \c ...) |
| 15:58 | mavbozo | joe124 ^not working for string |
| 15:58 | joe124 | ok im getting it know |
| 15:58 | bensu | Frozenlock: I'm sorry, I missed the earlier comment (just found it) |
| 15:59 | bensu | bbloom: is "You work for me, Computer" your blog? |
| 15:59 | bbloom | bensu: yes |
| 16:00 | bensu | bbloom: first, kudos on the blog, it's been the end of long google journeys a couple of times :) |
| 16:00 | bbloom | bensu: heh, really? cool :-) |
| 16:00 | bbloom | thanks |
| 16:00 | not-much-io | Frozenlock: Didn't mean to spark any controversy. I was just thinking to myself that a "pretty page" for a language would help getting young college kids more attracted to clojure |
| 16:01 | not-much-io | Don't know if they count as "low quality community particiapnts" :) |
| 16:01 | Frozenlock | not-much-io: Sure. IMO the best intro page for clojure is probably http://www.tryclj.com/ (depending on your background) |
| 16:01 | bensu | bbloom: I'm surprised you find the value of visual design in this instance low, when your blog is quite good visually |
| 16:03 | bbloom | my blog and a programming language landing page are quite different |
| 16:03 | not-much-io | Frozenlock : tryclj.com is just what I went with when showing some friends. :) |
| 16:06 | mavbozo | not-much-io: clojuredocs.org is also cool |
| 16:06 | bensu | bbloom: I agree but it is still unexpected. In my experience people that produce a visually appealing blog tend to be strict about everything being visually appeling |
| 16:06 | bensu | *appealing |
| 16:07 | bbloom | bensu: and here in the clojure community, you find people who understand that the world is available in shades of gray ;-) |
| 16:07 | mavbozo | bensu: and use emacs |
| 16:08 | bensu | bloom: sure, I agree. Do you really use vim? |
| 16:09 | mavbozo | bloom: xmonad? |
| 16:09 | not-much-io | Frozenlock: IMHO people, even otherwise smart, pragmatic and productive people can be easily swayed by a cosmestic reason. Our visual sense is our strongest sense afterall :) But I suppose their numbers are debatable. :D |
| 16:09 | bbloom | bensu: yes |
| 16:09 | bbloom | mavbozo: no |
| 16:09 | mavbozo | bbloom: :) |
| 16:09 | not-much-io | mavbozo: clojuredocs is cool :P |
| 16:10 | joe124 | i think the clojure landing page should be as visually appealing as possible to attract newbies |
| 16:10 | Frozenlock | justin_smith: caribou looks very nice! Is it possible to have authentification in the API? Customer A login/password, customer B login/password... |
| 16:10 | mavbozo | not-much-io: as far as i know, clojure core actively encourages community contribution |
| 16:10 | bensu | bbloom: I was in vim myself until evil-mode :) |
| 16:10 | mavbozo | not-much-io: maybe you could build a clojure-for-college-kids website |
| 16:11 | mavbozo | not-much-io: clojuredocs.org is the result of community contribution |
| 16:11 | bbloom | joe124: i'd rather attract people who respect and nurture newbies. it's a slower growth strategy, but seems to produce good results :-) |
| 16:11 | not-much-io | mavbozo: Would if I could do it in a matter that would actually be visually as cool as clojure is conceptually :) |
| 16:12 | mavbozo | clojuredocs.org wasn't as beautiful as it is now |
| 16:13 | bensu | not-much-io: you would have to be very talented! :) |
| 16:13 | oddcully | yeah, the design of the home page is really what makes a programming language viable... |
| 16:14 | not-much-io | mavbozo: Understood, I was just thinking today that I should offer to fix some example snippets I've seen using strange s-syntax. (braces on new lines) Just to contribute something :) |
| 16:14 | adamhill | speaking of clojuredocs.org. Is search broken for everyone else? |
| 16:14 | adamhill | searched for 'http' got 0 hits |
| 16:15 | not-much-io | oddcully: Please don't misunderstand, that is not what I am saying. Just a bit more appealing to quite a few newbies perhaps. |
| 16:15 | mavbozo | adamhill: me too, search http also got 0 hits |
| 16:15 | not-much-io | bensu: Awfully talented! :) |
| 16:16 | andyf | adamhill: Safari doesn't work in my experience. Firefox is better there |
| 16:16 | adamhill | ok, other core things do return something, so just a gap in the knowledge base |
| 16:17 | andyf | ClojureDocs is not comprehensive on libraries |
| 16:17 | mavbozo | not-much-io: great! |
| 16:17 | oddcully | not-much-io: you mean: let's use bootstrap |
| 16:23 | not-much-io | oddcully: No, I am not saying to do anything, just asking about the reason. If it was just that noone got around to doing it I thought maybe I would lend a hand. (ever so slightly as my skill would allow it) But as was made clear, and I agree, that the versatility of the page's content would be limited by "styling". There are other more visually appealing sites for the "first look" effect :) |
| 16:24 | oddcully | not-much-io: i'm just pulling your leg |
| 16:25 | oddcully | it really p*sses me off, when usability get's sacrificed for "mobile first" or "da appeal". like e.g. with elasticsearch recently |
| 16:28 | not-much-io | mmm, dat css |
| 16:28 | not-much-io | jkjk |
| 16:29 | mavbozo | oddcully,: elastic.co ? |
| 16:30 | oddcully | yes. it seams they have paddeld back. you can search again without javascript |
| 16:30 | oddcully | in the recent days of the change you had to remove some full-site-overlay divs |
| 16:37 | justin_smith | Frozenlock: just got back, yes, you can have arbitrary role based auth, where you have multiple users and each have apropriate roles |
| 16:37 | justin_smith | Frozenlock: one of these days I may even plug it into friend |
| 16:38 | justin_smith | and thanks |
| 16:42 | danlentz | i for one would not complain if someone were to spend some time on the clojure site/documentation |
| 16:44 | danlentz | and generating clojuredoc style documentation really isn't as easy as "lein doc" with codox for example |
| 16:45 | Frozenlock | justin_smith: I'm trying it and loving every bit so far. |
| 16:45 | justin_smith | Frozenlock: awesome! |
| 16:45 | mavbozo | danlentz: most of active denizens here like justin_smith already wrote one such as this http://conj.io/store/v0/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/defmulti/ |
| 16:46 | andyf | Alex Miller has spent nontrivial hours on adding text to the docs on clojure.org over the past year or so. Not saying he is finished, and I don't know what future plans might be, but the content there has improved. |
| 16:47 | mavbozo | danlentz: and andyf too also actively wrote in clojuredocs.org |
| 16:47 | mavbozo | *writes* |
| 16:48 | andyf | There is a preference for concise docs on clojure.org and official doc strings that will likely never change. Other doc sites can be more verbose, like ClojureDocs.org, which is easy for anyone to edit in bits and pieces. |
| 16:49 | mavbozo | ,(doc future-cancel) |
| 16:49 | clojurebot | "([f]); Cancels the future, if possible." |
| 16:50 | hyPiRion | Oh no, time freezes yet again |
| 16:50 | danlentz | well, as a language it seems that (and Im just speculating) the lack of an explicit specification is at odds with the direction clojure has taken towards implementations across various platforms |
| 16:52 | andyf | Anyone that wants to can try writing a spec :). I would not expect clojure core team to want to spend time on such a project. |
| 16:52 | danlentz | no. i wouldn't want to be the guy to do it. Im just saying I think lets not undersell the value of _having_ such a thing if it were possible |
| 16:54 | arrdem | danlentz_: core will never write a spec I suspect. |
| 17:00 | gfredericks | that'd be an interesting thing to try to sell for bundling with clojure 2.0 |
| 17:00 | gfredericks | in particular taking the opportunity to break a few things in the name of a simpler spec |
| 17:00 | arrdem | I would agree. |
| 17:01 | Bronsa | i'd rather have a more open development process than a spec |
| 17:03 | bbloom | genuine question: why do you want a spec? |
| 17:04 | Bronsa | bbloom: have you ever used IPersistentMap in your code? |
| 17:05 | andyf | Guess: a more precise spec gives more guarantees on behavior than docs that leave much behavior unspecified. |
| 17:05 | bbloom | Bronsa: only after making a portability/compatibility risk tradeoff :-) |
| 17:05 | Bronsa | or any of the c.l interfaces that you kinda know you can use, but there's actually no *guarantee* of it |
| 17:06 | bbloom | Bronsa: well there is a guarantee of binary compat for public java code |
| 17:06 | bbloom | but it's a microsoft/sun style promise, rather than a source compatability promise |
| 17:06 | bbloom | which is a separate thing from portability between implementations |
| 17:07 | Bronsa | bbloom: afaik the only public java api is c.l.ifn and c.java.api.clojure |
| 17:08 | Bronsa | everything else is technically implementation details |
| 17:08 | bbloom | Bronsa: yes, but rich & alex have gone out of their way to preserve binary compat of the impl details |
| 17:10 | bbloom | https://groups.google.com/d/msg/clojure/BAlKtMB8pp8/F_4ru1ISf3sJ |
| 17:11 | bbloom | i also don't necessarily buy the argument that having a spec would improve the situtation |
| 17:11 | bbloom | the spec would simply neglect to mention implementation details that you'd then have to make the same cost/benefit risk tradeoff decision about |
| 17:11 | bbloom | w/o any material new info |
| 17:12 | danlentz | wow |
| 17:13 | bbloom | what's so wow? |
| 17:13 | danlentz | I think a spec would go a long way toward advancing clojure in a number of ways |
| 17:13 | bbloom | i'm not arguing against having a spec, i'm arguing that the spec would be useful for the IPersistentHashmap interface Bronsa mentioned |
| 17:13 | bbloom | happy to hear other arguments |
| 17:15 | danlentz | i mean, I'm not talking about creation of the CLJHS (or at least not in the image of CLHS) |
| 17:15 | Bronsa | bbloom: my only other argument is the usual "metadata is evaluated weirdly, also :tag" one :P |
| 17:15 | bbloom | Bronsa: lol, metadata :-P |
| 17:15 | danlentz | type hinting |
| 17:16 | hyPiRion | There are some funny edge cases lying around |
| 17:16 | hyPiRion | ,(#(`{~@% ~@%&} %) 1 2 3 4) |
| 17:16 | clojurebot | #error{:cause "Don't know how to create ISeq from: java.lang.Long", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: java.lang.Long", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.core$seq__4079 invoke "core.clj" 135] [clojure.core$concat$fn__4166 invoke "core... |
| 17:16 | danlentz | but at minimum we could specify what we intend to leave unspecified |
| 17:16 | hyPiRion | whoops |
| 17:17 | andyf | Has an attempt and later abandonment of a Ruby spec hurt Ruby adoption? |
| 17:17 | bbloom | andyf: no, but i don't know if adoption was the objective |
| 17:17 | Bronsa | ,(map meta ['^:foo [] '^:foo [1]]) |
| 17:17 | clojurebot | (nil {:foo true}) |
| 17:17 | danlentz | are we trying to be the most popular or the most useful/best? |
| 17:18 | danlentz | the spec encourages implementations |
| 17:18 | arrdem | porque no los dos? |
| 17:18 | danlentz | i mean, without a spec what are you even trying to implement |
| 17:19 | andyf | Clojure does not seem to be lacking in implementations. |
| 17:20 | danlentz | i think that their existence does not necessarily justify the conclusion that no specification is the most effective environment to nurture those implementations |
| 17:22 | bbloom | ,(defn print-spec [] (->> (ns-publics 'clojure.core) keys (map #(eval (list 'doc (symbol "clojure.core" (name %))))))) |
| 17:22 | clojurebot | #'sandbox/print-spec |
| 17:22 | bbloom | ,(print-spec) |
| 17:22 | clojurebot | ("; " "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Supports arbitrary precision. See also: +" "([n]); Returns true if n is a BigDecimal" "([a new-state & options]); When an agent is failed, changes the agent state to new-state and then un-fails the agent so that sends are allowed again. If a :clear-actions true option is given, any actions queued on the agent that were bei... |
| 17:22 | andyf | danlentz: Have you considered that specs can be a hindrance in some cases, too? They beget language lawyers :) |
| 17:22 | danlentz | yeah, language lawyering is painful |
| 17:23 | bbloom | danlentz: the lack of a spec also meant that clojurescript could find a happy tradeoff |
| 17:23 | bbloom | a clojure spec would have restricted clojure to provide features that may not have been possible on javascript runtimes |
| 17:23 | bbloom | or not possible with good perf |
| 17:23 | Bronsa | it also meant that I wanted to kill myself twice a day when making sure t.a could handle both clj and cljs :P |
| 17:23 | bbloom | by writing a spec, you constraint what gets to be called "clojure" |
| 17:24 | bbloom | Bronsa: would the existence of a spec have prevented that problem? |
| 17:24 | rhg135 | it also means you can write code that works identically on all platforms |
| 17:24 | danlentz | well, going forward can't we look ahead and anticipate what is going to be a reasonable set of abstractions to support? |
| 17:24 | bbloom | and if so, would the spec have had to existed before or after clojurescript was implemented? |
| 17:25 | bbloom | danlentz: we can only look backwards to see which reasonable set of abstractions have been supported successfully |
| 17:25 | rhg135 | how about a versioned spec? |
| 17:25 | rhg135 | say when clj only existed we had 1.0 then cljs came and it's 1.1 |
| 17:26 | bbloom | rhg135: but you're proposing a solution to a problem with a solution that hasn't been successfully motivated by a problem :-P |
| 17:26 | bbloom | i ask again: what benefit does a spec provide us? |
| 17:26 | andyf | Perhaps the spec could be versions with sha1 values? (ducks) |
| 17:27 | arrdem | (inc andyf) |
| 17:27 | lazybot | ⇒ 26 |
| 17:27 | danlentz | i mean, as a developer I would love to have definitive language to refer to in addition to the "few well chosen example" approach of the clojure doc |
| 17:27 | bbloom | danlentz: the doc strings in clojure.core are definitive |
| 17:27 | danlentz | do they tell me how to type hint? |
| 17:27 | rhg135 | i know that, andyf, that's just my view on a way a spec would be useful and maintainable |
| 17:27 | andyf | Albeit sometimes leaving details unspecified |
| 17:27 | bbloom | no, but type hints differ between clojure and clojurescript |
| 17:27 | Bronsa | bbloom: it would have probably made some of the problems I had to work around, somebody else's problems when implementing cljs |
| 17:28 | bbloom | so type hints wouldn't have been covered in this theoretical hint anyway |
| 17:28 | Bronsa | bbloom: type hints are dialect-specific things though |
| 17:28 | bbloom | Bronsa: as far as i'm concerned, your implementations are specs |
| 17:28 | danlentz | they should be documented as unspecified |
| 17:28 | rhg135 | type-hints are details anyway |
| 17:28 | rhg135 | mainly for performance |
| 17:29 | bbloom | danlentz: but how were we to know apriori the ways in which type hints would or wouldn't map to other platforms? |
| 17:29 | danlentz | well, details are not important in documenting a language |
| 17:29 | Bronsa | rhg135: it stops being details when you need that performance and they don't do what you'd expect them to do |
| 17:29 | danlentz | we could say where they belong |
| 17:29 | bbloom | the danger of writing a spec is that you screw up and now it's a spec |
| 17:29 | bbloom | the if you change it, ppl get pissed you broke it |
| 17:29 | danlentz | we could say what the syntax of defn should look like |
| 17:30 | bbloom | (doc defn) |
| 17:30 | clojurebot | "([name doc-string? attr-map? [params*] prepost-map? ...] [name doc-string? attr-map? ([params*] prepost-map? body) + ...]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata. prepost-map defines a map with optional keys :pre and :post that contain collections of pre or post conditions." |
| 17:30 | bbloom | the syntax is defined there |
| 17:30 | arrdem | bbloom: without the spec you have the same problem. Imagine the ire if defn got changed in 1.7. |
| 17:30 | bbloom | ,(-> #'defn meta :arglists) |
| 17:30 | clojurebot | ([name doc-string? attr-map? [params*] prepost-map? ...] [name doc-string? attr-map? ([params*] prepost-map? body) + ...]) |
| 17:30 | danlentz | so if i am returning a long where do i put the type hint? |
| 17:31 | bbloom | arrdem: sure, which brings me back to my question: what value does the spec provide us? |
| 17:31 | TEttinger | you can't return a long on JS because JS doesn't have longs |
| 17:31 | bbloom | the web is a place where we have 1) specs and 2) many implementations |
| 17:31 | rhg135 | js is a prime example of a spec |
| 17:31 | TEttinger | internet explorerjure! |
| 17:31 | bbloom | and i find the spec to be of significantly less value then mozilla's community maintained documentation, which records facts about implementations |
| 17:31 | danlentz | the type hint can go on the var or on the arg vector |
| 17:32 | danlentz | if on the var, it cannot be primitive |
| 17:32 | rhg135 | i'm not sure what the opposite would be |
| 17:32 | danlentz | if on the type vector, it must be fully qualified |
| 17:32 | danlentz | show me where it says that in the clojure documentation |
| 17:32 | TEttinger | danlentz: that's what's called a wart |
| 17:32 | bbloom | rhg135: js mainly benefits from being a spec b/c js code is trasmited as data to agents w/ unknown execution environments |
| 17:32 | rhg135 | most languages have varying degrees of specs: from ansi to 'what is a spec' |
| 17:32 | bbloom | clojure doesn't have that use case |
| 17:32 | jbizzle | hey |
| 17:32 | arrdem | bbloom: I would argue that we have an implicit spec in the form of the Clojure implementation which should be better rendered in the form of a clear document so that people like Bronsa and myself who are interested in making "near Clojure" langs have something more to work with and some idea of the extent to which we are breaking compat. |
| 17:33 | danlentz | so it should DEFINITELY be documented |
| 17:33 | TEttinger | and they've been meaning to change it, but it would break a lot of code |
| 17:33 | jbizzle | what us clojure |
| 17:33 | TEttinger | jbizzle: see topic |
| 17:33 | rhg135 | bbloom: that's the key. one language, lots of platforms |
| 17:33 | TEttinger | it's a programming language |
| 17:34 | bbloom | rhg135: the fundamental distinction is whether the code runs on a KNOWN platform/implementation, or an *unknown* one |
| 17:34 | bbloom | you'll notice that EDN has a spec |
| 17:34 | danlentz | things and intents are left unspoken |
| 17:34 | bbloom | that's b/c it's expected to be interpreted by unknown implementations |
| 17:34 | jbizzle | ok ok |
| 17:34 | danlentz | even if "everbody knows" how a particular implementation works |
| 17:34 | bbloom | writing specs is 1) time consuming 2) difficult and 3) not without risks |
| 17:34 | bbloom | so you need a strong motivation, like with JS or EDN |
| 17:34 | danlentz | looking at that in another context might not be so clear cut |
| 17:35 | danlentz | i think having things expressed explicitly facilitates the discussion that helps bridge those gaps |
| 17:35 | bbloom | arrdem: if you were trying to implement a scheme and the spec said "you must have tail calls" but your platform doesn't support them, well then, you're going to spend a whole hell of a lot of time trying to match the spec & dealing w/ ppl bitching you don't have tail calls |
| 17:35 | rhg135 | i think we should start on a spec once we hit 150 platforms |
| 17:36 | bbloom | arrdem: now granted, if you tried to run some scheme code on your no tail calls platform, it would fail... but what if tail calls were spec'd LATER and all the code out there didn't rely on them? |
| 17:36 | bbloom | arrdem: like is the case with javascript |
| 17:36 | danlentz | well lets not call the other languages "clojurexxxxx" then |
| 17:36 | bbloom | arrdem: if rich specs something, ppl like you will force yourself to adhere to the spec |
| 17:36 | danlentz | because clojure is defined by this one java implementation and that is what we should expect as clojure |
| 17:37 | bbloom | arrdem: and while admirable, that would be a detrimental effect to your experiments |
| 17:37 | arrdem | bbloom: agreed, one of the many reasons I've abandoned calling my experiments "clojure". |
| 17:37 | bbloom | look at pypy which runs some % of all python code, minus some c ffi stuff, and subject to dozens of caveats |
| 17:37 | rhg135 | a good test suite should work |
| 17:38 | bbloom | rhg135: yes, i'd much prefer a portable test suite than a spec |
| 17:38 | rhg135 | it'd be nice |
| 17:38 | rhg135 | if you pass the clj suite, you're good. if not, no |
| 17:38 | danlentz | i think there is a very close relationship between a formal portable test suite and a spec |
| 17:39 | arrdem | danlentz: loosely construed Curry/Howard, yes. |
| 17:39 | bbloom | danlentz: there's a critical difference in my mind, which is that a spec aims to be exhaustive, or at least is treated as such |
| 17:39 | bbloom | tests are expected to not necessarily be comprehensive |
| 17:40 | danlentz | but even with tests its important to understand test coverage |
| 17:40 | danlentz | e.g. what is currently remains untested |
| 17:40 | bbloom | anyway, my position is not that a spec is a bad idea |
| 17:40 | bbloom | only that it 1) is not without costs/risks and 2) would provide limited value for clojure |
| 17:41 | danlentz | just as with a spec you are free to say what you are specifying, what is implementation defined, and what is undefined |
| 17:41 | bbloom | i'll also add that, in my career, i've never once encountered a spec that was widely implemented correctly by multiple independent vendors |
| 17:41 | bbloom | and i've coded to a lot of specs... |
| 17:42 | danlentz | "we all suck, so why bother trying..." |
| 17:42 | bbloom | "this isn't working, let's double down" |
| 17:42 | danlentz | :) |
| 17:42 | mavbozo | guys, how many pages needed to write a clojure spec? I guess it won't be that many cause clojure is a lisp |
| 17:43 | bbloom | microsoft pushed the W3C to start publishing test suites, and surprise surprise, that seems to be working :-) |
| 17:43 | mavbozo | algol-60 spec is 34 pages |
| 17:43 | arrdem | mavbozo: this is left as an exercise for the reader |
| 17:46 | rhg135 | for the syntax? maybe a paragraph |
| 17:46 | rhg135 | aside from the edn spec of course |
| 17:46 | danlentz | there are actually other lisp specifications we can look at an learn from |
| 17:48 | danlentz | at minimum, do no worse |
| 17:54 | danlentz | the way w3c tests sparql and ttl and n3 is really quite good |
| 17:56 | danlentz | also the ansi-cl test suite demonstrates some very extensive and concerted effort to verifiably test an implementation and correlate the results with the standard |
| 18:13 | justin_smith | wow, this contributor agreement is weird (on google chrome, linux) http://i.imgur.com/YTTeTgn.png |
| 18:14 | bbloom | justin_smith: *sigh* adobe.... |
| 18:14 | justin_smith | inorite |
| 18:16 | justin_smith | I waited too long to sign this thing. |
| 18:19 | gfredericks | back in my day we could only sign contributor agreements with printers and pens and stamps and mailmen |
| 18:20 | gfredericks | but we were happier then, though we were poor |
| 18:20 | oddcully | weird and from adobe... that is odd |
| 18:28 | brehaut | gfredericks: and we waited bloody months for international postage |
| 18:29 | gfredericks | hell yes we did |
| 18:29 | gfredericks | then we had to email somebody at relevance to ask if they every got the letter |
| 18:30 | gfredericks | but did we complain? |
| 18:30 | gfredericks | yes. |
| 18:30 | gfredericks | pretty much nonstop. |
| 18:30 | brehaut | vocally, on the mailing lists |
| 18:30 | oddcully | haha |
| 18:31 | Bronsa | gfredericks: it's a thing of the past now, let's find something else to complain about ;) |
| 18:31 | bbloom | :-) |
| 18:31 | brehaut | theres always jira |
| 18:32 | gfredericks | yeah why the hell do these unchecked functions do so much checking |
| 18:33 | bbloom | gfredericks: numerics are hard :-( |
| 18:34 | gfredericks | numbers I will tell you what. |
| 18:39 | justin_smith | gfredericks: we should emulate the olive oil people and make extra-unchecked functions |
| 18:40 | Glenjamin | its mildly amusing that all computers can do is numbers |
| 18:40 | Glenjamin | and now we can't get them to do only that |
| 18:42 | gfredericks | justin_smith: I can go for that |
| 18:42 | gfredericks | ,(defn extra-unchecked-add [x y] (unchecked-add (long x) (long y))) |
| 18:42 | clojurebot | #'sandbox/extra-unchecked-add |
| 18:53 | brehaut | justin_smith: its like unchecked, but with a more pepper taste |
| 18:55 | danlentz | au-poive |
| 19:01 | danlentz | is there a particularly good resource to see a large number of examples of how to build various abstractions with the primitives of core.logic? |
| 19:03 | danlentz | i was really interested in screamer when working in common lisp but I had a look at the source code and porting it seems like a lost cause |
| 19:05 | danlentz | https://github.com/nikodemus/screamer |
| 19:06 | danlentz | first there is the issue of what seems to be a system of delimited continuations |
| 19:06 | justin_smith | danlentz: could that be modeled with trampoline? |
| 19:06 | danlentz | second there is the issue that this macro system needs to pretty much account for the entire language |
| 19:07 | danlentz | but if I could have a wish this would be it |
| 19:09 | danlentz | it is really an awesome tool |
| 19:10 | danlentz | also (blush) i ported Screamer+ and gathered some extensions and documentation |
| 19:10 | danlentz | https://github.com/danlentz/screamer-plus |
| 19:11 | danlentz | by "ported" i mean de-allegrized it |
| 19:14 | danlentz | well with atoms I would think |
| 19:17 | danlentz | IE, an unknown would be modeled as an atom with a watcher and when it became known, any logical implications of that would be reflected in an update to the other unknowns of the universe |
| 19:17 | danlentz | the trick is to make that calculation lazy |
| 19:27 | justin_smith | sounds like a delay, not an atom |
| 19:28 | justin_smith | unless it can become known more than once |
| 19:30 | danlentz | no, retraction is complicated |
| 19:31 | danlentz | https://github.com/danlentz/screamer-plus/raw/master/doc/screamer.pdf |
| 19:32 | danlentz | "Screaming Yellow Zonkers" |
| 19:32 | danlentz | so the basic idea is "nondeterministic lisp" |
| 19:36 | danlentz | this describes the screamer-plus extensions |
| 19:36 | danlentz | https://github.com/danlentz/screamer-plus/blob/master/doc/screamer-plus.pdf |
| 19:37 | danlentz | yes, delay |
| 19:44 | danlentz | i think there would have to be some adaptation of the concept to a model more conciliatory toward immutability, but I guess that has to be addressed with any layered extension to clojure for deductive logic |
| 19:46 | danlentz | built up as a macro on top of funcall-nondeterministic |
| 20:50 | Shayanjm | I have a big vector containing center points of circles that need to be plotted. I'm running through them with map and plotting them with Incanter. |
| 20:50 | Shayanjm | If I try running the same exact vector with pmap, though, it returns a wildly different result |
| 20:51 | Shayanjm | it's almost as if pmap doesn't actually run through the entire vector |
| 20:51 | Shayanjm | any reasoning re: why/how to rectify? I'd like to parallelize this if possible because there could be a non-trivial amount of plotting necessary in the future |
| 20:52 | justin_smith | Shayanjm: I don't think pmap will help much because your GUI still only has one event loop to register all these shapes to display |
| 20:52 | justin_smith | unless calculating the actual display data is a CPU bottleneck |
| 20:52 | justin_smith | which I doubt |
| 20:52 | justin_smith | ~pmap |
| 20:52 | clojurebot | pmap is not what you want |
| 20:52 | Shayanjm | justin_smith: nah, no CPU bottleneck - though in the (near) future i'll be needing to make tons of API requests using these points |
| 20:53 | Shayanjm | so parallelizing that if possible would be very helpful |
| 20:54 | justin_smith | yeah parallelizing that would be good, but pmap has a hard baked strategy that assumes the task is CPU bound, not network bound |
| 20:54 | Shayanjm | Gotcha. is there a well-adopted norm for parallelizing network stuff? |
| 20:54 | Shayanjm | or is it basically bake your own solution? |
| 20:54 | justin_smith | you can use an async network client and feed the result into your GUI updating function |
| 20:54 | Shayanjm | That works |
| 20:55 | justin_smith | also the async network client will do fancy shit like keeping the http connection open for multiple requests |
| 20:55 | justin_smith | which is a big plus if you keep hitting the same host |
| 20:55 | Shayanjm | nice |
| 20:55 | Shayanjm | Yeah definitely |
| 20:55 | Shayanjm | I'm psyched that my general solution packing function works as expected |
| 20:56 | Shayanjm | so any additional leg work on top to get it wired up is no problem |
| 20:56 | justin_smith | yeah, that's always cool |
| 20:56 | justin_smith | you have the correct version, so now you can work on turning it into the fast version |
| 20:56 | Shayanjm | yup definitely |
| 21:14 | prt44 | I've got a map keyed by a java.util.Date {d v d2 v2}, I'd like to convert to the map be keyed by year i.e. 2015, then the value is a nested map keyed by month with it's value the original value. Note the day is not really significant because it's always the last day of the month. |
| 21:19 | andyf | prt44: Check out group-by. You could start by making a function that extracts the year from a java.util.Date and using that in the call to group-by. |
| 21:19 | andyf | Then iterate on each value of the map created to do something similar with the month. |
| 21:21 | andyf | Hmmm, not exactly what you asked for, but not too far from it. |
| 21:21 | prt44 | andyf: thanks, I had been using reduce and update-in, but I'll experiment with group-by |
| 21:26 | amalloy | group-by is probably going to be more work than reduce/update-in |
| 21:27 | amalloy | (reduce (fn [m date] (assoc-in m [(.year date) (.month date)] date)) {} dates) |
| 21:27 | amalloy | or however you get data out of Date objects |
| 21:32 | justin_smith | and change that assoc-in to an update-in / conj date if you would care about multiple pieces of data with the same month (which it sounds like you may not) |
| 21:37 | justin_smith | ,(reduce (fn [acc date] (update-in acc [(.getYear date) (.getMonth date)] conj date)) {} (repeatedly 8 #(java.util.Date. (long (rand-int 1000000000))))) |
| 21:37 | clojurebot | {70 {0 (#inst "1970-01-01T19:42:43.552-00:00" #inst "1970-01-06T07:52:39.424-00:00" #inst "1970-01-07T06:32:57.051-00:00" #inst "1970-01-05T18:26:28.078-00:00" #inst "1970-01-06T01:30:58.082-00:00" ...)}} |
| 21:38 | justin_smith | ,(reduce (fn [acc date] (update-in acc [(.getYear date) (.getMonth date)] conj date)) {} (repeatedly 5 #(java.util.Date. (* 10000 (rand-int 1000000000))))) |
| 21:38 | clojurebot | {196 {2 (#inst "2096-03-06T03:51:50.000-00:00")}, 280 {2 (#inst "2180-03-11T19:01:10.000-00:00")}, 369 {7 (#inst "2269-08-05T03:25:20.000-00:00")}, 359 {2 (#inst "2259-03-31T01:35:40.000-00:00")}, 171 {10 (#inst "2071-11-27T19:31:10.000-00:00")}} |
| 22:16 | elvis4526 | Hi! Is it possible to use a regexp when matching a path with compojure ? |
| 22:16 | arrdem | elvis4526: yep! |
| 22:16 | arrdem | elvis4526: the context macro allows you to gard path elements with a regexp. |
| 22:16 | arrdem | elvis4526: you may be able to do the same with other routing terms, I can't say I'm sure. |
| 22:17 | Lewix | hello folks |
| 22:17 | catern | is there a "Java for Clojure programmers" tutorial yet? |
| 22:17 | catern | please someone write it soon |
| 22:18 | arrdem | elvis4526: (context ["/:a", :a #"fo+"] [a] ...) should work for instance. |
| 22:19 | elvis4526 | I'm not sure I understand why I would be using context |
| 22:19 | elvis4526 | What I meant is: |
| 22:19 | elvis4526 | I want a route like that (GET "^\w*$" [] foo) |
| 22:20 | elvis4526 | I don't want to prefix all my routes with something necesseraly |
| 22:20 | raspasov | catern: https://www.youtube.com/watch?v=P76Vbsk_3J0 Clojure for Java Programmers video |
| 22:20 | catern | raspasov: wrong way around |
| 22:20 | catern | friend |
| 22:20 | arrdem | elvis4526: https://github.com/weavejester/compojure/wiki/Routes-In-Detail#matching-the-uri |
| 22:21 | raspasov | catern: oops :) |
| 22:21 | elvis4526 | alright cool |
| 22:21 | catern | I think this is kind of what i'm looking for http://www.braveclojure.com/java/#3_3__Importing |
| 22:21 | elvis4526 | and are the rules defined after this rule of mine |
| 22:21 | elvis4526 | will override it ? |
| 22:21 | catern | er |
| 22:21 | catern | http://www.braveclojure.com/java/ |
| 22:21 | arrdem | elvis4526: no compojure works on a "first match" basis. |
| 22:22 | elvis4526 | oh okay |
| 22:22 | elvis4526 | so basically i just put it at the end |
| 22:22 | raspasov | catern: yea I learned most of this stuff with the help of IntelliJ and Cursive, and auto-filling of imports is badass |
| 22:22 | elvis4526 | thanks |
| 22:22 | arrdem | elvis4526: sure, but there is a built in for the route which matches anything. |
| 22:22 | elvis4526 | are you speaking about ANY ? |
| 22:22 | elvis4526 | I thought it matches every type of requerst |
| 22:22 | arrdem | elvis4526: https://github.com/weavejester/compojure/blob/master/src/compojure/route.clj#L40 |
| 22:31 | gfredericks | 4L96dmaMgJ |
| 22:33 | TEttinger | hahaha |
| 22:33 | TEttinger | $google 4L96dmaMgJ |
| 22:33 | brehaut | gfredericks: your pass is ********** ? |
| 22:33 | gfredericks | maybe a security breach email would be more appropriate |
| 22:33 | brehaut | that doesnt sound very secure |
| 22:33 | TEttinger | also, no symbols? for shame |
| 22:34 | TEttinger | you're in #clojure and you don't use symbols whenever possible??? |
| 22:34 | lazybot | TEttinger: How could that be wrong? |
| 22:34 | brehaut | TEttinger: i prefer keywords in my passphrases |
| 22:35 | TEttinger | I like BOMs |
| 22:35 | TEttinger | just in general |
| 22:36 | TEttinger | password: \0\0\0password\0\0\n\r\n\0 |
| 22:36 | TEttinger | I wonder how many places would even be able to take that |
| 22:52 | justin_smith | TEttinger: more as a paste - that way it won't get in the way of widget / tty key bindings |
| 22:52 | justin_smith | but with a password like that, you wouldn't be typing it all in by hand anyway I don't think |
| 22:53 | justin_smith | catern: that's a really shallow intro to interop, the docs on clojure.org are better |
| 22:54 | justin_smith | catern: http://clojure.org/java_interop |
| 22:54 | catern | justin_smith: I don't need docs on interop |
| 22:55 | catern | justin_smith: I need an explanation of WTF all this Java crap is |
| 22:55 | justin_smith | catern: and the extra thing neither resource mentions, is that java is documented by a highly standardized format called javadoc, and there are tools like javadoc-search-pane for modern browsers that make finding things really easy |
| 22:55 | justin_smith | catern: this java crap is 100% interop |
| 22:55 | justin_smith | that's the way you access it |
| 22:55 | catern | well |
| 22:55 | catern | let me assure you |
| 22:56 | catern | that the brave clojure one is much better for me personally as someone unfamiliar with Java |
| 22:56 | TEttinger | catern, are you writing java coming from a clojure bg? |
| 22:56 | justin_smith | catern: the problem to me is that the entire chapter there covers like what you could get from half a paragraph on the clojure.org page |
| 22:56 | TEttinger | java is, thankfully, not that hard of a language compared to many others out there |
| 22:57 | catern | justin_smith: and I need that |
| 22:57 | TEttinger | catern, if you have any specific questions we can try to answer some |
| 22:57 | catern | well |
| 22:57 | catern | I haven't actually read the brave clojure or the clojure.org pages yet |
| 22:57 | catern | I have other things I have to get done |
| 22:57 | catern | BUT LATER I WILL |
| 22:58 | TEttinger | (I'm guessing the package/namespace stuff is a big headache for anyone coming from java or clojure and trying to learn the other) |
| 23:03 | justin_smith | TEttinger: no matter what, they are two parallel and weirdly incompatible systems - I came in knowing neither java or clojure and it was confusing |
| 23:03 | TEttinger | wow |
| 23:17 | devll | How long have you been using Clojure ? justin_smith |
| 23:17 | justin_smith | about 3 years |
| 23:18 | devll | Yeah. Big relief, I have 2 years to catch up. |
| 23:18 | devll | lol |
| 23:19 | devll | do you have blog on Clojure? |
| 23:20 | justin_smith | devll: funny, I was thinking about that earlier, some ideas for one... |
| 23:22 | tolstoy | Hard to think of what to write about with Clojure that hasn't already been done and available via Planet Clojure. |
| 23:22 | tolstoy | Maybe an un-clojure Blog? |
| 23:22 | tolstoy | Show how you can translate a few lines of Clojure into 100 lines of Java or whatever? |
| 23:23 | tolstoy | Blog: Leiningen Considered Harmful -- 1st paragrah: Let us open to chapter 59 of the Gradle documentation site.... |
| 23:23 | justin_smith | I think I might have a kind of unique intro-to-programming via clojure perspective, different from the other stuff I've seen |
| 23:23 | tolstoy | Eh. Barrels. Fish. |
| 23:24 | devll | justin_smith: that will be awesome. |
| 23:24 | tolstoy | Ah, yeah. Nice. |
| 23:25 | justin_smith | my general idea is: first the abstraction, then the various ways you will see it leak, and the signs that particular abstraction is leaking |
| 23:26 | justin_smith | eg. "cannot find ... _init.class" usually means you asked for a namespace but clojure failed to load the file for it |
| 23:27 | tolstoy | Back in 2008ish, I _always_ got caught with the error for not using a vector for parameters. |
| 23:27 | justin_smith | the stuff that held me back for so long, and then I came to IRC and people could tell me instantly what was wrong, when I first started |
| 23:27 | justin_smith | tolstoy: yeah, that's another good one |
| 23:27 | justin_smith | maybe "the clojure error dictionary" |
| 23:27 | tolstoy | It's better now. At least they mention "parameter". ;) |
| 23:27 | justin_smith | haha |
| 23:29 | tolstoy | I wonder if there's a "how to read clojure" opportunity out there? |
| 23:29 | tolstoy | Maybe, "How to read Clojure source for the not particularly detail oriented." |
| 23:29 | TEttinger | heh |
| 23:29 | justin_smith | tolstoy: that would be another good thing to cover |
| 23:30 | justin_smith | "clojure speed reading" |
| 23:30 | TEttinger | the lazy guide to lazyseqs |
| 23:30 | justin_smith | haha |
| 23:30 | justin_smith | oh, here's another idea: stack trace flash cards |
| 23:30 | TEttinger | yes! |
| 23:30 | tolstoy | Whenever you see "reduce", you know someone's taking a bunch of values and crunching 'em down to a few. So just glance right over that without getting lost in the actual anonymous function. |
| 23:30 | tolstoy | That kind of thing. ;) |
| 23:30 | TEttinger | I like it |
| 23:30 | justin_smith | on one side it has a real stack trace, on the other side, the kind of mistake that makes that stack trace, lol |
| 23:31 | TEttinger | OutOfMemoryError |
| 23:31 | justin_smith | TEttinger: that would be the name for the clojure flavor of the game memory |
| 23:31 | TEttinger | heh |
| 23:31 | amalloy | TEttinger: fat-themed yo mama joke |
| 23:31 | TEttinger | or dumb-themed, amalloy! |
| 23:31 | tolstoy | "For a stack trace, read the first line. That's all you need unless it's a NullPointerException. Then get a cup of coffee." |
| 23:32 | TEttinger | "yo mama's so dumb she gets an OutOfMemoryException when she tries to turn on her TV" |
| 23:34 | devll | It will be nice if we could stack those to one github repo. |
| 23:34 | TEttinger | "yo mama's so dumb she gets an NullPointerException when she tries to figure out if Darnell is really the baby's father on Jerry Springer" |
| 23:34 | TEttinger | I'm typoing all over here |
| 23:35 | justin_smith | TEttinger: "yo mama got an NPE when she tried to dereference her BabyDaddy field" |
| 23:35 | TEttinger | haha |
| 23:35 | TEttinger | UnknownInheritanceException |
| 23:35 | justin_smith | LOL |
| 23:44 | justin_smith | so set!, with-redefs, binding and alter-var-root walk into a var... |
| 23:50 | morganthomas | hi all! i have a situation which i don't understand. i have couple instructions which produce different results when run in a "do" block and when run separately on the repl. |
| 23:51 | morganthomas | if i write into the repl: |
| 23:51 | morganthomas | > (foo bar) |
| 23:51 | morganthomas | > (baz abc) |
| 23:51 | morganthomas | that produces a different result than doing |
| 23:51 | morganthomas | > (do (foo bar) (baz abc)) |
| 23:51 | justin_smith | morganthomas: if foo is lazy, then printing in the repl will force it to be eager |
| 23:51 | justin_smith | but inside do, it won't do anything at all |
| 23:52 | justin_smith | the moral of this story is that laziness and side effects are star-crossed features, doomed to a complicated and bug-ridden romance |
| 23:52 | morganthomas | ah, thank you! |
| 23:52 | justin_smith | morganthomas: options include dorun (if you never use the result) and doall (if you use it) |
| 23:52 | morganthomas | so foo uses a for loop to do a series of actions on a java object. i am assuming the action of "for" is lazy? |
| 23:53 | justin_smith | morganthomas: yes, for is lazy, and unlike every other language out there, clojure's for is not a loop |
| 23:53 | justin_smith | morganthomas: it's easy to test this in general actually |
| 23:53 | justin_smith | ,(type (for [a (range)] a)) |
| 23:53 | clojurebot | clojure.lang.LazySeq |
| 23:53 | justin_smith | if type gives that answer, the function is lazy |
| 23:54 | morganthomas | justin_smith: ah, thank you so much. so what would be the idiomatic way to perform a series of actions, one for each element in a sequence? |
| 23:54 | justin_smith | morganthomas: doseq is identical to for, except it returns nil |
| 23:54 | justin_smith | and is not eager |
| 23:55 | justin_smith | and accepts N forms in its body |
| 23:55 | morganthomas | justin_smith: brilliant, thank you! now i can fix my code. :-) |
| 23:55 | justin_smith | but it has the same binding syntax and features as for, so you can just s/for/doseq |
| 23:55 | justin_smith | morganthomas: np |
| 23:56 | justin_smith | that would be one of the chapters in my tutorial |
| 23:56 | justin_smith | when your thing suddenly does nothing, it's usually because it's lazy and you aren't using its result |
| 23:57 | morganthomas | i'll go take a look at that. |
| 23:57 | justin_smith | morganthomas: my hypothetical not yet existing tutorial, something we were discussing earlier |
| 23:58 | morganthomas | ah, i see. yes, it did not come up on google. :-) |
| 23:58 | justin_smith | morganthomas: this too I can attribute to laziness |
| 23:58 | justin_smith | so if I just edit my inner for and make it a doseq... |
| 23:58 | morganthomas | :-p |