2014-08-21
| 00:00 | justin_smith | though you can use prefixes in require, that's kind of unpopular (make grep for ns usage break) |
| 00:00 | joshuafcole | for my pacman demo it doesn't matter much (probably < 5 renderers) but for a bigger game it seems unwieldy and tightly coupled |
| 00:00 | joshuafcole | hmmm |
| 00:00 | joshuafcole | I guess the other approach might be an "index" file of sorts for all renderers |
| 00:00 | joshuafcole | that exposes all the renderers as a member of itself |
| 00:01 | joshuafcole | that way requires are all still static |
| 00:01 | puredanger | munderwo: there can be some weirdness with which classloader calls loadLibrary - you may want to ensure that the loadLibrary call happens in the base loader, not clojure's loader. If you're only doing clojure, you might want to wrap -main with a custom Java shim that loads the library. I ran into this once. |
| 00:01 | joshuafcole | but they're organized instead of splatted throughout the places that define entities |
| 00:01 | joshuafcole | I'll give that a go, thanks |
| 00:01 | justin_smith | joshuafcole: the problem with trickery like that is it messes with static analysis tools, and with programmgers that expect to be able to grep for a full ns to find where it is required |
| 00:02 | joshuafcole | Well, I *think* that won't cause problems |
| 00:02 | joshuafcole | since the partial ns resolves to a file that then immediately points to the real ns |
| 00:02 | joshuafcole | so even though it'd be two hops of goto source, it'll still point their with static code |
| 00:02 | munderwo | puredanger: ahh… I understand what you just said is important… but I have no idea how to go about doing it :) |
| 00:02 | joshuafcole | rather than something generated e.g. w/ macros or prefixes. Or am I missing something? |
| 00:03 | joshuafcole | (If there's a serious code smell here I want to avoid it, just want to make sure we're on the same page) |
| 00:03 | justin_smith | joshuafcole: so how would the index file work? |
| 00:03 | joshuafcole | let me throw together a pastebin of my idea |
| 00:03 | puredanger | munderwo: you just need a Java class with a static public void main(String[] args) that 1) calls loadLibrary, 2) invokes clojure.main/main with args. |
| 00:04 | munderwo | ahh ok.. I think I get what you mean. is it because when I import the java library later on it messes up something? |
| 00:07 | munderwo | puredanger: did you get something along the lines of "Check failed: new_bundle. Failed to load the bundle at Contents/Frameworks/blah blah blah"? |
| 00:07 | puredanger | munderwo: don't remember |
| 00:07 | munderwo | ok thanks! |
| 00:09 | joshuafcole | justin_smith: thrown together *in* pastebin, so please forgive any simple mistakes http://pastebin.com/96nNdJKc |
| 00:10 | joshuafcole | The primary goal is, if there are 20 renderers and 30 components and 15 systems, all with identital interfaces to others of their type, not to have to require them all separately everywhere they might be used |
| 00:10 | justin_smith | ahh, using def to expose something from the other ns |
| 00:10 | justin_smith | that can be annoying in a big codebase, but yeah, not as bad as what I was thinking |
| 00:10 | joshuafcole | this way everythins is still static, so the code flow is preserved |
| 00:11 | joshuafcole | do you have any better suggestions to meet that goal? |
| 00:11 | justin_smith | another thing to consider is that the point of multimethods and protocols is that the caller not need to care about the subtype of the thing, it can just invoke render on it and trust it does the right thing |
| 00:12 | joshuafcole | Well 1. I'm not yet familiar w/ multimethods, I'll need to investigate those, but 2. I don't actually care about subtype, I'm relying purely on duck typing in the engine |
| 00:12 | justin_smith | so then you can make a list of things to render, some being pacman, some being ghost, whatever, each knowing what to do if you ask it to render |
| 00:12 | joshuafcole | I just need some way to get at the defined components / defined systems in order to wire them together |
| 00:13 | joshuafcole | so in a sense I do have an implicit protocol going (if you want to be rendered, you need to have the renderable component with a render callback stored in it that I can pass the texture to, etc.) |
| 00:13 | justin_smith | I think that packman and block should be defining render, and requiring the renderer to make that definition, then core should create a block and a pacman, and pass those to the consumer, that will call render on each |
| 00:13 | joshuafcole | though codifying it explicitly sounds like an excellent idea |
| 00:14 | justin_smith | it seems odd that both render and core would need to know about blocks and pacmans |
| 00:14 | joshuafcole | well, this is in the context of a component entity system, and pacman is actualyl a very contrived example |
| 00:14 | joshuafcole | actually* |
| 00:14 | justin_smith | OK |
| 00:14 | joshuafcole | in reality, there'd be a folder of entities with the pacman folder pulling in the appropriate components |
| 00:14 | joshuafcole | (player-controlled, renderable, etc.) |
| 00:15 | justin_smith | with component-entity, the pacman namespace doesn't need to know about the render that goes with pacman |
| 00:15 | joshuafcole | and rather than a pacman example I'm testing the water with, the eventual goal is to build a game which uses only procedurally generated content |
| 00:15 | justin_smith | my goal would be to minimize the design dependencies - have simple and clear paths for which parts are expected to know details of what |
| 00:15 | joshuafcole | for all of it's assets |
| 00:15 | joshuafcole | much of which I hope will be interchangable |
| 00:16 | joshuafcole | so there isn't likely to be a pacman entity and pacman renderer, but rather a sword, scimitar, katana, and knife that all use the blade renderer |
| 00:16 | justin_smith | OK |
| 00:45 | ben_vulpes | i'm using a lot of time dates in an application that i'm hacking on, and i've sort of settled on the philosophy of throwing around joda datetimes and coercing them to java instants at the very last moment, in the binding declaration for my datomic queries. how would you go about addressing this design challenge? |
| 00:46 | ben_vulpes | i'm at the point where just doing it consistently is important and giving me big wins in terms of reducing cognitive overhead, but i'd be interested to hear how anyone else would go about this |
| 00:48 | ben_vulpes | i've also considered doing the coercion in let bindings, but not all of my queries have let bindings |
| 00:48 | ben_vulpes | *shrug* |
| 01:04 | posed2death | ... |
| 01:05 | posed2death | does anyone here talk ? |
| 01:05 | ben_vulpes | not late at night. |
| 01:05 | posed2death | huh |
| 01:05 | ben_vulpes | rather busy during us work hours though. |
| 01:05 | posed2death | oh I see |
| 01:06 | posed2death | it's been over ten years since ive used this program |
| 01:09 | ben_vulpes | irc? |
| 01:09 | clojurebot | irc is only for opionfests |
| 01:09 | ben_vulpes | irc |
| 01:09 | ben_vulpes | irc? |
| 01:09 | clojurebot | irc is only for opionfests |
| 01:09 | ben_vulpes | opionfests, eh? clever bot... |
| 01:11 | posed2death | yes |
| 01:12 | posed2death | Far too long |
| 01:12 | posed2death | looks have not changed much |
| 01:12 | ben_vulpes | if it ain't broke |
| 01:12 | posed2death | hah |
| 01:13 | ben_vulpes | much like gpg |
| 01:14 | posed2death | ah |
| 01:16 | posed2death | well... guess I better wait till morning |
| 01:16 | posed2death | hah |
| 01:42 | wei | I’m dealing with a 3rd-party service that takes JSON to set attributes. partial updates are supported, e.g. an object with {a: 1} can be updated to {a: 1, b: 2} by supplying {b: 2}. I’d like to keep structures as Clojurey as possible (using keywords, etc). Would transit be an appropriate solution? |
| 01:44 | wei | My initial test seems to say no, since transit serializes Clojure maps into JSON arrays instead of objects: {:hello 1} => ["^ ","~:hello",1] |
| 01:50 | ben_vulpes | transit? |
| 01:50 | ben_vulpes | if it's json, why not try the core json facilities? |
| 01:50 | danielcompton | ben_vulpes: https://github.com/cognitect/transit-format |
| 01:50 | ben_vulpes | ayeah, found it danielcompton. |
| 01:51 | ben_vulpes | ,(clojure.data.json/write-str {:a 2 :b 4}) |
| 01:51 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.data.json> |
| 01:52 | ben_vulpes | wei; |
| 01:52 | ben_vulpes | from my repl |
| 01:52 | ben_vulpes | (clojure.data.json/write-str {:a 4 :b 2}) |
| 01:52 | ben_vulpes | "{\"b\":2,\"a\":4}" |
| 01:52 | ben_vulpes | that said i've no clue what you're doing. using transit implies some sort of wire protocol, so ymmv. |
| 01:54 | wei | ben_vulpes: two considerations, one major and one minor. the major issue is that I use both numbers (ids, etc) and keywords as keys to my maps, and json serialization would clobber that distinction. the minor issue is that transit is supposed to be much faster than EDN on deserialization |
| 01:56 | wei | dnolen makes the case for transit here: http://swannodette.github.io/2014/07/26/transit--clojurescript. |
| 01:56 | ben_vulpes | i am blessed in that nothing i do is performance sensitive |
| 01:57 | ben_vulpes | or rather, that my dev hours are so much pricier than my compute cycles ;) |
| 01:57 | ben_vulpes | this is guaranteed to kick my ass sometime this or next year, i suspect. |
| 01:59 | wei | ben_vulpes: lol. since the data is stored as JSON (on a 3rd party service that I don’t control), how would you recommend dealing with non-json values like keywords? or should I just design my schema to only use json-supported values |
| 02:35 | wei | eureka! the solution to my above problem was transit’s json-verbose mode |
| 03:20 | mskoud | Hi |
| 03:39 | sveri | Hi, Is anyone else here experiencing problems when developing with http-kit? Whenever I encounter an uncaught exception during development I cannot restart my system, cause http-kit will throw this error then: BindException Address already in use: bind sun.nio.ch.Net.bind0 (Net.java:-2) |
| 03:39 | wei | this article says keywords must be strings when using transit, but i seem to be able to round-trip with keywords intact http://swannodette.github.io/2014/07/26/transit--clojurescript. was there an update? |
| 03:40 | wei | sveri: you sure there’s not another version of your app running? |
| 03:40 | sveri | wei: yea, I am sure, if I exit the repl and restart it, it's working |
| 03:48 | wei | sveri: not sure what else then, sorry. perhaps you could file an issue |
| 03:58 | sveri | wei: Thank you anyway :-) |
| 04:03 | mskoud | Is there any larger Ring/Compojure open source projects out there, that might serve as example? |
| 04:09 | mskoud | Well not necessary Ring/Compojure but at least Clojure? I find lots of examples, but would like to see the structure and errorhandler in a real project. |
| 04:49 | lvh | What's the gold standard tool for prose docs in Clojure? |
| 04:49 | lvh | Sphinx seems like the best general tool, but does not appear to have any specific clojure support. |
| 04:49 | lvh | Which is unfortunate, because it means it can't e.g. display function signatures. |
| 04:50 | mskoud | lvh: maybe http://fogus.github.io/marginalia/ |
| 04:52 | lvh | mskoud: hm, I guess I could try some literate programming, but not quite what I had in mind, no :) |
| 05:12 | borkdude | In liberator, if I have a post resource, where/how do I return a response? |
| 05:14 | srenatus | hm. just when I learnt about (def ^:dynamic *foo* []), I end up seeing (def ^{:dynamic true} *bar* []) everywhere. what is it? just a more obvious, explicit variant? |
| 05:17 | hyPiRion | srenatus: ^:dynamic is equivalent to ^{:dynamic true}. It's just a shorthand form |
| 05:17 | hyPiRion | so yes |
| 05:17 | srenatus | hyPiRion: ok thanks |
| 05:17 | mpenet | the ^{} form is the whole metadata map |
| 05:17 | mpenet | http://clojure.org/metadata |
| 05:17 | srenatus | mpenet: thanks, just what I wanted to ask next |
| 05:21 | mpenet | well technically, not the whole, but it allows you to set multiples values in 1 go |
| 05:22 | mpenet | ,(meta (var ^{:foo :1 :bar 2} x)) |
| 05:22 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: x in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:23 | mpenet | ,(let [^{:foo :bar} x 1] (meta (var x))) |
| 05:23 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: x in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:23 | mpenet | :/ |
| 05:24 | srenatus | clicked the window for focus, ended up in channel #<CompilerException. (It's empty.) |
| 05:25 | clgv | mpenet: use `def` clojorebot got very permissive lately ;) |
| 05:25 | clgv | *clojurebot |
| 05:25 | clgv | mpenet: a local binding is not a var anyway.. ;) |
| 05:26 | clgv | ,(def ^{:foo :bar} x 1) |
| 05:26 | clojurebot | #'sandbox/x |
| 05:26 | clgv | ,(meta #'x) |
| 05:26 | clojurebot | {:ns #<Namespace sandbox>, :name x, :file "NO_SOURCE_PATH", :column 0, :line 0, ...} |
| 05:26 | clgv | ,(select-keys (meta #'x) [:foo]) |
| 05:26 | clojurebot | {:foo :bar} |
| 05:50 | virmundi | Hello. I'm trying to figure out if a lazy-seq is a good idea for wrapper around a Web API. The web api returns JSON records. They get batched returned with a cursor attribute for future retrieval. |
| 05:51 | virmundi | In order to efficiently work with the API source, the cursor needs to be deleted when the query is complete. |
| 05:52 | virmundi | I think I can see how to use a protocol to extend closable with another function like execute to call the service. |
| 06:20 | taharqa | Hi there ! clojure noob here ! |
| 06:21 | taharqa | I know emacs lisp I do a lot of java and I want code a lib in clojure that can be reused in java and jvm world. |
| 06:22 | taharqa | To do so I want to know the way in clojure to "implements" an already existing java Interface ? |
| 06:22 | taharqa | Someone can tell me how to to do this ? |
| 06:24 | rweir | http://clojure.org/java_interop |
| 06:24 | rweir | people may or may not be willing to load clojure into their java app to run your code though |
| 06:26 | taharqa | rweir: I already have a look on your link and it is not clear to me the right method to do it |
| 06:27 | noncom | anyone using CCW here? is there a way to know project name in the REPL ? |
| 06:27 | noncom | or maybe it is common for Leiningen and CCW ... ? |
| 06:27 | rweir | taharqa, ok |
| 06:32 | taharqa | rweir: I see this which can be interesting "You can also generate statically-named classes and .class files with gen-class" |
| 06:32 | rweir | do consider the above though |
| 06:34 | clgv | ~ask |
| 06:34 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 06:34 | clgv | noncom: ^^ |
| 06:35 | clgv | ah there it was |
| 06:35 | noncom | clgv: reading now.. |
| 06:35 | taharqa | rweir: the clojure jar file is not that big |
| 06:35 | clgv | noncom: in repl you can probably use leiningen's library to find and read the project map |
| 06:36 | noncom | clgv: aha, so i have to link the leiningen dep ? |
| 06:36 | clgv | noncom: in a jar it is easier since the project.clj is included at the toplevel |
| 06:37 | noncom | but whats up with a repl. .. ? |
| 06:37 | clgv | noncom: yeah that should work. but I dont know if the effort of finding the project.clj is worth the trouble |
| 06:37 | clgv | noncom: what is your use case? |
| 06:38 | noncom | my case is that i want to make some project-management from repl |
| 06:39 | noncom | for example, i want to auto-write some namespaces.. |
| 06:39 | noncom | from templates |
| 06:39 | clgv | hm ok. |
| 06:39 | noncom | i guess i have to know the name of the top package then so it is automatically put there.. and that name is == project name.. |
| 06:39 | noncom | (in my cases) |
| 06:39 | clgv | yeah maybe you want to pull in deps from the repl as well, then you are already setup with the leiningen lib |
| 06:40 | noncom | what is the best way to pull deps from the repl ? |
| 06:40 | clgv | you can not assume that the namespace you are in belongs to the project? |
| 06:40 | clgv | noncom: humm pomegranate works most of the time but there seem to be edge cases according to its readme |
| 06:41 | clgv | noncom: during the last weeks there was an announcement for a lib on the ML as well. but I forgot its name |
| 06:41 | noncom | well maybe i can assume the belonging of the ns... but then i have to deal with its relative location.. and project name would give me the "root directory access" to the project.. |
| 06:42 | noncom | i know, that all sounds not too definite.. still a ground for explore to me also |
| 06:43 | noncom | a new realtime dep mngmnt lib ? |
| 06:43 | clgv | adding deps from repl, yes |
| 06:44 | noncom | i have to look at the ML too then |
| 06:44 | noncom | don't like it much though, much of a chaos there |
| 06:44 | noncom | things get lost and go down to the bottom.. the paging is terrible.. just google groups, yeah... |
| 06:44 | clgv | noncom: do you plan to use a leiningen template? maybe you could pass the project name through configuration to the running repl |
| 06:45 | clgv | noncom: I only read it in my mail client ;) |
| 06:45 | noncom | no, not a leiningen template. in my programming practice, i have to create similar namespaces for different projects .. |
| 06:45 | noncom | for example, the "repl" namespace itself |
| 06:46 | noncom | i got used to it have some instrumentation.. also, all my projects depend on a lib that i have created and i put all the required funcs in there |
| 06:47 | noncom | so i want to easily write namespaces from templates, configured by a list of params |
| 06:47 | noncom | something like that... |
| 06:52 | clgv | noncom: souds pretty much like a leiningen template |
| 06:52 | clgv | *sounds |
| 06:52 | laurio | how can i find a previous key in a sorted map in case there is no exact match? |
| 06:53 | noncom | clgv: yeah, but i do not want to restrict myself to the project creation phase. i may require to create multiple new namespaces during project lifetime. also, using a templating engine with it (like stencil) allows for high customization |
| 06:53 | noncom | laurio: previous to what ? |
| 06:55 | clgv | laurio: no the implementation class does not support that afaik |
| 06:56 | clgv | laurio: you can only get the keys and do a binary search on those |
| 06:56 | laurio | clgv, so that ((into (sorted-map) [[1 1] [3 3]]) 2) would return 1 |
| 06:56 | clgv | laurio: or use a different data structure |
| 06:57 | clgv | laurio: maybe that one works for you? https://github.com/clojure/data.avl |
| 06:58 | laurio | thank you, clgv, i'll take a look |
| 07:05 | Xionbox | Hello. I am new to CLJS and trying to iterate over all items of a content map ( `[:children [{:identification "010100", :name "Pure Mathematics"} ... `). I tried the following syntax with no luck: `doseq [{:keys [identification name] :as children} children]`. How is one supposed to use doseq with a content map's items? Thanks! |
| 07:05 | clojurebot | Ik begrijp |
| 07:06 | clgv | Xionbox: ##(doseq [[k v] {:a 1 :b 2}] (print k "->" v ", ")) |
| 07:07 | clgv | ,(doseq [[k v] {:a 1 :b 2}] (print k "->" v ", ")) |
| 07:07 | clojurebot | :b -> 2 , :a -> 1 , |
| 07:07 | Xionbox | Okay, thanks clgv, I'll give it a shot. |
| 07:08 | clgv | Xionbox: you seem to have some kind of nested map structure, though |
| 07:10 | Xionbox | clgv, yes that's correct. I am already able to extract the children information using `{:keys [children] :as cls}` in the parameters of the function. |
| 07:10 | clgv | ,(doseq [[k1 v1] {:a {:b 2, :c 3} :d {:e 4}}, [k2 v2] v1] (print k1 "->" k2 "->" v2 ", ")) |
| 07:10 | clojurebot | :d -> :e -> 4 , :a -> :c -> 3 , :a -> :b -> 2 , |
| 07:11 | clgv | Xionbox: the above pattern is usefull if you now in advance the constant number of levels you need to access |
| 07:12 | Xionbox | Nice, nice! Is there a cljs cheat sheet somewhere? I'm getting into cljs because we're moving all the company's front end code to it (two devs are very pro clojure) but I can't seem to find thorough documentation. |
| 07:15 | oliy | hi, is anyone from metosin around? |
| 07:18 | clgv | Xionbox: you can use the clojure cheat sheet for basic stuff, but be aware that there might be differences |
| 07:18 | clgv | Xionbox: http://clojure.org/cheatsheet |
| 08:18 | taharqa | Xionbox: You can also have a look at http://hyperpolyglot.org/lisp |
| 08:19 | taharqa | there is a column clojure and it helps me a lot |
| 08:20 | justin_smith | someone should update that |
| 08:22 | taharqa | Yeah it is clojure 1.2 , I was thinking syntax is quite similar |
| 08:22 | justin_smith | it is |
| 08:22 | justin_smith | the changes are actually pretty small, but it would still be nice if it was up to date |
| 08:22 | taharqa | justin_smith: I agree |
| 08:23 | taharqa | the thing that helps me is that it compares syntax between different lisps, and I know emacs lisp more |
| 08:23 | justin_smith | I used to refer to that frequently, in my first two weeks of using clojure. It's been years since I looked at it :) |
| 08:24 | taharqa | great ^^ you are a veteran then ! |
| 08:24 | justin_smith | it was a weird situtation, I got hired to do clojure, but didn't really know it yet, they just trusted I would pick it up based on my emacs lisp, scheme, cl experience |
| 08:25 | justin_smith | definite learning from immersion situation |
| 08:26 | Bronsa | there are some clojure examples that are definitely out of dat |
| 08:26 | Bronsa | date |
| 08:26 | justin_smith | yeah |
| 08:26 | Bronsa | some use unnecessary java interop |
| 08:27 | Bronsa | oh well. |
| 08:27 | justin_smith | well, it does say it is for clojure 1.2 |
| 08:27 | Bronsa | justin_smith: clojure 1.2 already had rand and str |
| 08:27 | justin_smith | I wonder if they take pull requests |
| 08:28 | justin_smith | also the file-handles section is weirdly empty |
| 08:30 | blunte | Does anyone here have experience with clj-time? I'm trying to convert a string of format YYYYMMdd "20140630" to a sql date, but I can't make enough sense of the docs to understand how to do that. I imagine it's a simple thing to do. |
| 08:37 | justin_smith | I wonder if 1.2 really used , for unquote, or if the first macro example is just wrong |
| 08:40 | Bronsa | justin_smith: clojure never used , for unquote |
| 08:40 | justin_smith | that's what I had guessed |
| 08:41 | clgv | Bronsa: `rand` is clearly no case where you can avoid java interop |
| 08:41 | Bronsa | clgv: maybe in real life, but for that example (rand 100) would have been just fine |
| 08:42 | clgv | Bronsa: ok, but then the example is not worth much ;) |
| 08:42 | clgv | Bronsa: though in comparison to the others it works^^ |
| 08:43 | Bronsa | clgv: yeah, that's what I'm arguing |
| 08:43 | clgv | Bronsa: just caught up ^^ |
| 08:44 | Bronsa | that string constructor example is pretty ridiculous too |
| 08:50 | clgv | Bronsa: indeed, MUHAHAHAHA! |
| 08:52 | clgv | "show version" -> "displayed by repl on startup" :P |
| 09:48 | irctc | I would like to split a string with that has question mark, whats the way to escape a '?' in # pattern |
| 09:48 | irctc | I am trying. |
| 09:49 | irctc | (clojure.string/split "abcd ? bcda" #"\\?") |
| 09:49 | Duke- | #"\?" |
| 09:49 | ohpauleez | yeah, just one slash |
| 09:49 | mgaare | \? |
| 09:49 | clgv | ,(require '[clojure.string :as str]) |
| 09:49 | clojurebot | nil |
| 09:49 | irctc | ok, so the problem could be emacs cider-repl |
| 09:49 | clgv | ,(str/split "abcd ? bcda" #"\?") |
| 09:49 | clojurebot | ["abcd " " bcda"] |
| 09:50 | mgaare | oh, sorry lag |
| 09:50 | irctc | emacs cider-repl seems to add "^M" after I type "\" |
| 09:53 | irctc | that got solved, it couldn't be sillier... so I put question mark and then tried to put a \ in-front of it. that caused he problem |
| 09:54 | irctc | emacs expected me to put the character next that I was trying to escape by typing in '?' |
| 09:54 | irctc | thanks all |
| 09:58 | Xionbox | I just found this cheatsheet which makes the correspondance between JS and CLJS: http://kanaka.github.io/clojurescript/web/synonym.html . |
| 10:00 | lvh | Is there a cleaner way to write (condp #(%1 %2) thing map? expr1 vector? expr2 set? expr3) ? |
| 10:01 | jlongster | hey guys, I'm compiling some CLJS code and can't seem to use `enable-console-print!`. I get "Cannot read property 'call' of undefined" with `cljs.core.enable_console_print_BANG_.call(null);` |
| 10:01 | jlongster | dnolen_: ^ my project.clj https://github.com/jlongster/tmp-cljs/blob/master/project.clj |
| 10:03 | martinklepsch | jlongster: target nodejs doesn't seem right? |
| 10:03 | jlongster | martinklepsch: should be https://github.com/emezeske/lein-cljsbuild/blob/1.0.3/sample.project.clj#L112 |
| 10:04 | jlongster | it just adds a call to the entry point defined with *main-cli-fn* |
| 10:05 | martinklepsch | what do you expect enable-console-print! to do when run in node? |
| 10:06 | jlongster | the same thing? just define console.log as *print-fn* |
| 10:06 | jlongster | I'll try it in the browser I guess |
| 10:06 | jlongster | only reason using node is to get a quick cljs eval environment |
| 10:06 | clgv | Xionbox: but that might mislead you because 'var foo = "bar";' and '(def foo "bar")' are far from being the equivalent usage pattern for "variables" (= local bindings) in functions |
| 10:07 | clgv | Xionbox: oh ok there is a local binding example as well ;) but be warned anyway ;) |
| 10:07 | Xionbox | Thanks! |
| 10:08 | clgv | Xionbox: well post an example datastructure, e.g. on refheap.com, and an output example and link it here, there might be help ;) |
| 10:08 | jlongster | martinklepsch: if I compile it for the browser, same thing. searching through all the js, it doesn't exit. |
| 10:08 | jlongster | *exist |
| 10:09 | martinklepsch | jlongster: sorry, I thought console.log would be a browser specific thing, no node experience :) |
| 10:09 | justin_smith | irctc: yeah, I find that mode for character escaping really annoying |
| 10:09 | jlongster | martinklepsch: yeah, it's standard JS |
| 10:09 | dnolen_ | jlongster: you're dependencies are way out of date. Clojure 1.6.0 and ClojureScript 0.0-2311 lein-cljsbuild 1.0.4-SNAPSHOT |
| 10:09 | martinklepsch | jlongster: are you correctly loading all the files in output-dir? |
| 10:09 | dnolen_ | s/you're/your |
| 10:09 | dnolen_ | fix that first |
| 10:10 | jlongster | dnolen_: oh. I did a `lein search` and thought I picked the latest versions. not sure how you all do the equivalent to `npm install cljs --save` in Clojure? |
| 10:11 | Xionbox | clgv, thanks! Here's the function and example output. https://www.refheap.com/89336 I'm getting close to something working, but help is always appreciated. |
| 10:11 | dnolen_ | jlongster: also don't bother with :simple w/ node.js it's slow - https://github.com/clojure/clojurescript/wiki/Quick-Start#notes-on-optimization-settings |
| 10:11 | irctc | justin_smith: yeah its annoying when I didn't know about it. Now that I know it, I'll know soon if I like it or not. Getting used to emacs was also annoying for me, I am appreciating it now though. |
| 10:11 | dnolen_ | jlongster: you just need to supply a script that runs those requires for you |
| 10:12 | jlongster | dnolen_: ah sweet, thanks. saw a bug about having to use that under node |
| 10:12 | justin_smith | irctc: long term emacs lover here, and I can't stand that hand-holding string-escape thing |
| 10:13 | jlongster | I think I need to update clojure, when I try to use 1.6 I get a UnsupportedClassVersionError |
| 10:13 | jlongster | I installed all of this with lein, btw |
| 10:13 | jlongster | I think it automatically chose 1.5.1 |
| 10:13 | dnolen_ | jlongster: what java version are you running |
| 10:14 | clgv | Xionbox: the output example is listed in the second line. where is the input? |
| 10:14 | jlongster | dnolen_: 1.6.0_65; I never saw lein pull down the new verson of deps though, so something seems weird |
| 10:14 | Xionbox | Ha! I got it to work! W00t! |
| 10:14 | jlongster | dnolen_: btw, I also tried your mies template with lein but got the UnsupportedClassVersionError too |
| 10:14 | jlongster | so something's wrong with my machine |
| 10:15 | justin_smith | jlongster: you may need a newer jvm |
| 10:15 | oliy | lvh: why not just use cond? |
| 10:16 | justin_smith | jlongster: afaik UnsupportedClassVersionError means you are trying to use java code that is too new for your jvm (and 1.6 is pretty old) |
| 10:16 | Xionbox | clgv, I get the input via ajax: https://www.refheap.com/89336 (I updated the paste, so F5 should suffice). |
| 10:16 | irctc | justin_smith: right, no swich there? I find paredit-mode painful sometimes, but its more of a help, than a problem. |
| 10:16 | jlongster | justin_smith: gotcha, thanks. there is an update (strangely, the console says I have Java 7; I got the version from `java -version`) |
| 10:16 | dnolen_ | jlongster: think you need JDK 1.7 for Clojure 1.6 |
| 10:17 | jlongster | ok |
| 10:17 | clgv | Xionbox: usually you can try stuff like that in a plain clojure repl if you have input examples |
| 10:18 | clgv | dnolen_: no, Clojure 1.6 minimum dep is Java 1.6 |
| 10:19 | clgv | https://github.com/clojure/clojure/blob/master/changes.md#11-jdk-version-update |
| 10:19 | dnolen_ | clgv: ah k |
| 10:19 | justin_smith | irctc: sadly, paredit seems to have no configuration options |
| 10:19 | dnolen_ | jlongster: w/o more info can't say anything about mies issue - never encountered that myself nor heard about it before |
| 10:20 | jlongster | dnolen_: I think my java is old and that's why things are breaking |
| 10:39 | noncom | whats the best way to insert an element into a middle of [] |
| 10:39 | noncom | ? |
| 10:45 | dnolen_ | noncom: there is no best way with plain vectors, you're only options is concat + pour into a new vector. Or you could use the rrb-tree contrib https://github.com/clojure/core.rrb-vector |
| 10:48 | noncom | dnolen_: cool, thanks! |
| 10:49 | puredanger | you could also get portions with subvec and combine. not sure how that would perform |
| 10:58 | pandeiro | should it be possible to share redis-backed ring sessions between different ring-based services? (so that eg i can have just one authentication service and all my others simply assume a session is present or not) |
| 11:03 | justin_smith | pandeiro: if your apps are using the same redis backend, and the same credentials and config, it should just work I think |
| 11:03 | dnolen_ | jlongster: I fixed your tmp-cljs project, I will say it's not obvious what to do w/o knowing Google Closure conventions |
| 11:03 | pandeiro | justin_smith: that's what i thought, too |
| 11:04 | pandeiro | justin_smith: being new to carmine though i haven't even determined if my auth service is actually hitting redis, as i don't see any keys being generated |
| 11:04 | dnolen_ | jlongster: once you get your JDK sorted out, you can run `lein cljsbuild auto`, then to run your code `node load.js`, and you get incremental compile times |
| 11:05 | jlongster | dnolen_: oh, sweet! thanks! yeah, only using node for quick evals. I installed JDK7 and was able to use your mies template, but I'll try node again with that |
| 11:06 | justin_smith | pandeiro: are you seeing some problem, or just checking in before trying it? |
| 11:06 | pandeiro | justin_smith: yeah so in a dummy test i'm not getting sessions carrying over |
| 11:06 | pandeiro | but like i said, i'm also not seeing any sessions appearing in redis-cli |
| 11:07 | pandeiro | my handler looks something like this: |
| 11:07 | pandeiro | (-> app (compojure.handler/site {:store (carmine-store redis-conn {:prefix-key my-key})})) |
| 11:07 | justin_s` | one sec, connection issues |
| 11:07 | pandeiro | ah maybe i need to nest that in a :session key |
| 11:09 | justin_smith | yeah, I think so - I forget how compojure.handler/site works, but in general you want any session stuff to be injected into the :session key in the request map |
| 11:12 | pandeiro | justin_smith: yeah the session manipulation part i remember, it's the setup/teardown i think i am screwing up |
| 11:13 | justin_smith | I'd say just get a redis session on one server working first - then accessing it from multiple servers should be straightforward |
| 11:13 | pandeiro | justin_smith: that was it, i had the compojure.handler/site invoc wrong |
| 11:13 | justin_smith | cool! |
| 11:13 | pandeiro | and yes, the session is accessible to other services |
| 11:13 | pandeiro | justin_smith: thanks |
| 11:15 | justin_smith | np |
| 11:25 | Xionbox | How do I have an if-clause with two or more instructions? Do I have to define a new function? |
| 11:25 | Bronsa | tbaldridge: did you get a chance to look at the core.async patch I sent in JIRA? |
| 11:25 | justin_smith | ,(if true (do (print "like ") (print "this"))) |
| 11:25 | clojurebot | like this |
| 11:26 | justin_smith | Xionbox: contrived example of course, but I hope it's clear |
| 11:26 | puredanger | Xionbox: wrap in a (do … ) |
| 11:26 | Xionbox | Thanks guys! |
| 11:30 | razum2um | HI guys, I've got an existing clj project and I'd like to dig in it. recently i found an awesome dbg macros http://www.learningclojure.com/2010/03/conditioning-repl.html which prints the form and it's result, can I get it for the whole program execution? If someone used Ruby i'd like to have set_trace_func |
| 11:31 | pandeiro | razum2um: maybe checkout clojure.tools.trace |
| 11:33 | Jaood | TIL about http://foil.sourceforge.net/ |
| 11:35 | justin_smith | razum2um: check out tools.trace |
| 11:36 | justin_smith | you can use trace-ns to trace everything in an ns, or trace-vars to trace specific vars |
| 11:36 | justin_smith | (those vars probably being defn created functions, of course) |
| 11:36 | lvh | ISTR that go blcoks are smart enough to rewrite loops; are they smart enough to rewrite recurses? |
| 11:38 | clgv | lvh something like that https://github.com/cjfrisz/clojure-tco ? |
| 11:39 | lvh | clgv: er? I'm not sure; that doesn't appear to know about core.async at all |
| 11:39 | lvh | clgv: Did you read "do block"? |
| 11:39 | lvh | this may actually be interesting for a different question I have :) |
| 11:39 | lvh | lemme see if this code works in the repl and I'll show you :) |
| 11:40 | clgv | lvh: I thought you want to rewrite recursive calls ... |
| 11:41 | lvh | clgv: Argh! I meant *reduces* |
| 11:41 | lvh | although incidentally I want to rewrite recursive calls too :) |
| 11:42 | lvh | clgv: https://github.com/lvh/icecap/blob/master/src/icecap/execute.clj#L56 |
| 11:42 | lvh | (and the same problem at L59) |
| 11:42 | lvh | Do I rewrite those with loop/recur? |
| 11:45 | clgv | lvh: honestly, I have no idea what you are doing there ;) |
| 11:45 | lvh | clgv: I have a data structure, describing a plan for a bunch of requests (as in HTTP(S) requests) to be executed |
| 11:46 | lvh | clgv: a plan consists of a single request, or an ordered bunch of plans, or an unordered bunch of plans |
| 11:46 | lvh | (so the schema for the data structure is recursive) |
| 11:46 | justin_smith | lvh: there is no direct way to turn a mapped self-call into a tail recursion |
| 11:46 | razum2um | pandeiro: justin_smith: ok, it works, but it's very unreadable. the first thing - no console highlighting (clojure repl misses it, just try pry in ruby) and secondly it doesn't (pp) trace results |
| 11:47 | justin_smith | lvh: I think the general idea is you need to add an extra argument representing further execution on this "level" of recursion (to replace the map) |
| 11:48 | justin_smith | razum2um: we generally don't do output highlighting (and I am glad about that, because of how often my output is going to an emacs buffer, or a log file, or some other place where ansi colors make no sense) |
| 11:49 | ToxicFrog | justin_smith: isatty() |
| 11:49 | razum2um | justin_smith: but i see no way to save trace results and pipe it to (pp) & highlight |
| 11:49 | justin_smith | ToxicFrog: sure, but when I have been forced to use ruby tools, they seem not to use that - I get garbage in my logs |
| 11:49 | razum2um | justin_smith: moreover there is a way to distinguish bewteen tty or not |
| 11:50 | ToxicFrog | justin_smith: oh, ick. |
| 11:50 | ToxicFrog | I'm used to grep and git, which properly output colour to ttys and plain text to everything else. |
| 11:50 | razum2um | ToxicFrog: i think it's not ok |
| 11:50 | ToxicFrog | (in --colour=auto mode) |
| 11:51 | dnolen_ | jlongster: BOOM, https://github.com/swannodette/mies-node-template |
| 11:51 | razum2um | it's not about just convinience - it's about developer friendly |
| 11:51 | dnolen_ | jlongster: no one should have to figure this stuff out just to try it :) |
| 11:51 | justin_smith | razum2um: you are welcome to make a version of tools.trace that adds colors. the functionality simply isn't common in clojure tooling |
| 11:51 | jlongster | dnolen_: awwww yea! |
| 11:52 | dnolen_ | includes Node.js source map support |
| 11:52 | razum2um | justin_smith: yep, I know, but I think it's not a just one library problem |
| 11:53 | justin_smith | it is a "problem" with all clojure libraries, because we don't prefer to colorize |
| 11:53 | jlongster | dnolen_: great idea. it's very useful just to run stuff quickly, even if you'd normally just use Clojure server-side |
| 11:53 | jlongster | thanks! |
| 11:53 | dnolen_ | jlongster: no problem |
| 11:53 | ToxicFrog | justin_smith: I note that Timbre colourizes stack traces by default and the result is hugely more readable than default clojure stacks. |
| 11:54 | jlongster | dnolen_: at some point I'm going to push to integrate sourcemaps into Firefox's line numbers everywhere, but need to learn a bunch before I do that |
| 11:55 | razum2um | justin_smith: I cannot imagine to starve at screen on a very deep nested map, it's encountered as thing to get used to? |
| 11:56 | justin_smith | razum2um: instead of printing it, bind it to some value, then inspect it interactively in a repl. or you can pprint to get nice indentation. Or add colors, but to me that seems the least useful option of the three. |
| 11:57 | justin_smith | but if you want colors for convenience, go for it, as long as I'm not forced to use them that's fine with me |
| 11:58 | razum2um | justin_smith: ok, thanks, but really it seems strange, that you don't feel inconvenience |
| 11:58 | justin_smith | none whatsoever |
| 12:03 | noncom | what is the best library for working with NIO buffers in clojure ? |
| 12:03 | noncom | the byte buffers i mean.. |
| 12:03 | justin_smith | noncom: ToBeReplaced and I have been working on a wrapper for java.nio |
| 12:03 | justin_smith | https://github.com/ToBeReplaced/nio.file |
| 12:04 | justin_smith | I don't think it covers byte-buffers though |
| 12:04 | justin_smith | yeah, sorry for the noise, no bytebuffer |
| 12:04 | noncom | yeah, just looked at it before posting here, there is no byte-buffer support... |
| 12:04 | noncom | well np but hey is there anything for buffers ? |
| 12:05 | noncom | google shows up some options, but whats the best one.. maybe someone can advice ? |
| 12:05 | justin_smith | frankly I would just use interop |
| 12:05 | justin_smith | it's not a complex api |
| 12:06 | irctc | ,'(is (= var1 (get-val var2)) |
| 12:06 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 12:06 | irctc | '(is (= var1 (get-val var2)) |
| 12:10 | razum2um | justin_smith: btw, I saw projects like gorilla-repl and i think that must fight this readability problems, and indeed it does, but doesn't try colorizing on printed statements from (pp) and dosn't indent return values (but in browser i think it must do this way). do you think gorilla gets used more if gets this features? |
| 12:10 | irctc | I am using defmacro and generating a test function something like this. what's the correct way to achieve it? |
| 12:10 | irctc | https://www.refheap.com/89340 |
| 12:12 | justin_smith | razum2um: I am probably the wrong person to ask actually, it's not a feature I would actually enjoy (though I am sure many would find it helpful) |
| 12:12 | irctc | trying to generate test clauses from a given text file of questions and answers |
| 12:12 | xulfer | Would a seesaw related question be offtopic here? Just wondering. |
| 12:13 | razum2um | guys, how many of you tried or use at least once gorilla-repl? |
| 12:13 | justin_smith | irctc: you don't need a macro for that - you can call testing / is inside a function, and they work |
| 12:14 | justin_smith | just call the function calling testing/is from within your deftest form |
| 12:15 | irctc | justin_smith: so you mean we don't exactly need separate defmacros to achieve that? I can simply add that logic to deftest function? I'll try it |
| 12:16 | justin_smith | you can do something like (defn verify-foo [arg] (testing "foo status" (is (foo arg)))) (deftest bar-test (verify-foo bar) ...) |
| 12:20 | irctc | justin_smith: great, that works, thanks |
| 12:20 | justin_smith | np |
| 12:26 | razum2um | btw, just saw a comment https://github.com/clojure/tools.trace/pull/4#issuecomment-23447333 about contributing, why so?! it's probably ok for the language, but I think it prevents tools from being improved. there must be specs and automated test on travis, then github's pr's are coolest things to collaborate, don't you think so? |
| 12:27 | xulfer | You think? After seeing how bitbucket manages those I've kind of soured on githubs setup. :/ |
| 12:27 | ToxicFrog | razum2um: yeah, there's actually some improvements I want to make to clojure, and then I look at the procedure for contributing patches and I just go, holy shit, I do not have time for this |
| 12:30 | xulfer | It seems like a pretty logical to me for a project of this nature. Not as intensive as some large open source projects. |
| 12:30 | technomancy | razum2um: it's super annoying |
| 12:31 | razum2um | technomancy: what? |
| 12:31 | technomancy | razum2um: the policy, I mean |
| 12:32 | xulfer | It's similar to Linux, *BSD, and OpenSolaris afaict |
| 12:35 | razum2um | xulfer: this oses may bee too critical, hard to test automatically and have dedicated person for every subsystem, but the team DON'T HAVE to be big in contrast to tools and libs development |
| 12:35 | razum2um | and I said, probably for the core it's acceptable |
| 12:37 | razum2um | ruby core-team used to communicate in redmine in japanise sometimes :) |
| 12:37 | xulfer | I don't know enough about the scope of contrib and what not to comment on that bit really. I see your point, but I also don't think they're being all together unreasonable. |
| 12:37 | stompyj | Has anyone here used sente? https://github.com/ptaoussanis/sente |
| 12:38 | xulfer | Also I haven't read through everything in the CA so there's that. |
| 12:38 | xulfer | I don't know why a CA is necessary to submit patch suggestions on JIRA. That's kind of silly if that's how it is. |
| 12:39 | Bronsa | xulfer: now that the CA is eletronic, it's not a such big deal IMHO |
| 12:40 | xulfer | Bronsa, Yeah to me either. I referenced OpenSolaris (even though it's defunct) specifically because I had to sign a bunch of sun agreements to contribute to them. |
| 12:40 | Bronsa | xulfer: also you don't need a CA to open tickets in JIRA, just to get a patch merged |
| 12:40 | xulfer | Bronsa, but can I say submit a patch in my ticket, and if a committer likes it he just uses it? I assume so. |
| 12:41 | xulfer | Which seems like a good path to take if you don't have time to go through the CA> |
| 12:41 | Bronsa | I don't think so honestly |
| 12:41 | xulfer | Ah okay. Sorry I'm not even close to a contributer so I don't know the process. |
| 12:41 | hiredman | rich has previous said he prefers people to ask on the ml about things before opening an issue |
| 12:42 | hiredman | (not that people really do that) |
| 12:43 | xulfer | He's right to suggest that though. |
| 12:43 | xulfer | The issue could be solved in a patch you missed. A maintainer could be working on it. Any number of situations where you would SAVE time by hitting the ML. |
| 12:43 | Bronsa | hiredman: I guess that's a valid suggestion only for feature requests |
| 12:44 | hiredman | sure, but the distinction between feature requests and "bugs" can get pretty subjective |
| 12:50 | technomancy | the mailing list that you can't even ask for permission to join until your CA has been received and registered? |
| 12:52 | xulfer | It's on usenet |
| 12:52 | xulfer | aka google groups. which is usenet |
| 12:53 | xulfer | Unless they changed it. Then i'll feel silly. |
| 12:53 | technomancy | xulfer: the main clojure one might be mirrored. I doubt the clojure-dev one is. |
| 12:55 | Glenjamin | mirrored which way? i'm pretty sure i've read clojure-dev via google groups |
| 12:55 | xulfer | I can check later. But I was under the impression all google groups were based in usenet. Maybe that was misguided. |
| 12:55 | clojurebot | Excuse me? |
| 12:55 | xulfer | Perhaps google groups merely mirror usenet. |
| 12:55 | xulfer | but for a while you could even post to usenet via google groups |
| 12:56 | technomancy | you definitely can't do that with clojure-dev |
| 12:56 | technomancy | err--you definitely can't go the other direction |
| 13:23 | xeqi | someone could always fork it and make lava |
| 13:25 | hiredman | lava is so hot right now |
| 13:26 | scgilardi | krakatoa to the east |
| 13:42 | SegFaultAX | hiredman: I invented the piano-key necktie. |
| 13:44 | TEttinger | SegFaultAX, I can't turn left |
| 13:48 | SegFaultAX | TEttinger: I'm not an ambiturner, either! |
| 13:49 | SegFaultAX | There are literally dozens of us! |
| 13:49 | SegFaultAX | (See what I did there?) |
| 13:49 | TEttinger | I feel like I should get the reference |
| 13:49 | technomancy | ,(meta ^:hey 'x) |
| 13:49 | clojurebot | nil |
| 13:50 | technomancy | is it just me, or is that a bit weird? |
| 13:50 | technomancy | is that a quirk of the compiler or what |
| 13:51 | stuartsierra | I think because it's (meta ^:hey (quote x)) |
| 13:51 | technomancy | aha; of course |
| 13:51 | technomancy | ,(meta (quote ^:hey x)) |
| 13:51 | clojurebot | {:hey true} |
| 13:51 | technomancy | there we go |
| 13:51 | technomancy | tricksy! |
| 13:51 | stuartsierra | or $(meta (with-meta 'x {:hey true})) |
| 13:52 | technomancy | sure |
| 13:52 | technomancy | just threw me because it works fine in defproject |
| 13:52 | mikerod | technomancy: ,'^:hey a |
| 13:52 | mikerod | ,'^:hey a |
| 13:52 | clojurebot | a |
| 13:52 | mikerod | (meta ,'^:hey a) |
| 13:52 | stuartsierra | oh wow |
| 13:53 | mikerod | ugh |
| 13:53 | mikerod | ,(meta '^:hey a) |
| 13:53 | clojurebot | {:hey true} |
| 13:53 | mikerod | very pretty |
| 13:53 | technomancy | hehe |
| 13:53 | technomancy | one side-effect of using metadata for profile merge directives is that there are some places where I have to accept either a symbol or a keyword in order to allow metadata to be attached. |
| 13:55 | gfredericks | what would be the perf implications of having a separate class for keywords with metadata? There'd be checks in the .equals methods of both classes; but classical Keyword would still use identity after the instance check |
| 13:55 | stuartsierra | ,'^:*@#'* |
| 13:55 | clojurebot | (clojure.core/deref (var *)) |
| 13:56 | technomancy | gfredericks: it's not clear what that would buy you over symbols? |
| 13:56 | SegFaultAX | gfredericks: keywords are a subclass of symbol, and symbol support metadata, no? |
| 13:56 | technomancy | other than interchangeability I guess |
| 13:57 | SegFaultAX | So wouldn't you have to break that hierarchy? |
| 13:57 | amalloy | SegFaultAX: keywords aren't a subclass of symbol, in this universe anyway |
| 13:57 | SegFaultAX | Are they not? |
| 13:57 | SegFaultAX | I must be misremembering then. |
| 13:57 | amalloy | ,(instance? clojure.lang.Symbol :x) |
| 13:57 | clojurebot | false |
| 13:58 | technomancy | they have a lot in common though |
| 13:58 | amalloy | it wouldn't really work for either to be a subclass of the other: they want to be final classes, so that your code that accepts Symbol objects can't be passed a sneaky MaliciousSymbol that mutates itself or whatever |
| 13:58 | SegFaultAX | Oh it's a has-a relationship. Not an is-a. |
| 13:58 | amalloy | they could both share an abstract superclass like an Identifier, if we wanted |
| 13:59 | stuartsierra | Keywords are sort of interned symbols. |
| 13:59 | gfredericks | technomancy: yeah I'm not sure :/ |
| 13:59 | stuartsierra | Both keywords and symbols are clojure.lang.Named. |
| 13:59 | SegFaultAX | stuartsierra: Yea, that's where I was misremembering. |
| 13:59 | TimMc | mikerod: Nice. |
| 13:59 | mikerod | stuartsierra++ to that example |
| 13:59 | SegFaultAX | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java#L32 |
| 13:59 | gfredericks | I guess the question is 1) if perf didn't matter, would we still have keywords distinct from symbols? 2) if we did, would we want them to have metadata? |
| 14:00 | amalloy | gfredericks: i think the only other thing keywords vs symbols buys you is they don't get namespace-qualified by syntax-quote |
| 14:00 | technomancy | gfredericks: conceptually the self-evaluating aspect could be decoupled from the interned aspect, sure |
| 14:01 | bbloom_ | gfredericks: consider this: if lists and vectors had the same in memory representation, would it still be useful to distinguish them for the sake of their evaluation behavior? |
| 14:01 | bbloom_ | i think the answer is clearly yes |
| 14:02 | gfredericks | bbloom_: yeah good point |
| 14:02 | gfredericks | also technomancy's point, it was good when he said it too |
| 14:02 | gfredericks | you guys both say good words into your keyboards |
| 14:03 | bbloom_ | adding on to amalloy's comment about namespace qualification: symbols refer to "something else" and keywords refer to "themselves" ... with the caveat about double colon keywords |
| 14:03 | bbloom_ | so it makes sense that symbols don't get namespace qualified by syntax-quote |
| 14:03 | bbloom_ | since then they would refer to "something else" |
| 14:04 | amalloy | bbloom_: s/symbols/keywords |
| 14:04 | bbloom_ | amalloy: yeah, that's what i meant. you know tha ti know what i'm talking about but can't spell/type/etc |
| 14:04 | bbloom_ | also, this is common in some envs: |
| 14:04 | bbloom_ | ,(def foo 'foo) |
| 14:04 | bbloom_ | ,foo |
| 14:04 | clojurebot | #'sandbox/foo |
| 14:04 | clojurebot | foo |
| 14:04 | bbloom_ | CL, factor, etc |
| 14:04 | amalloy | obviously. and yet it's still useful to correct you, in case someone else gets confused |
| 14:04 | bbloom_ | amalloy: thanks |
| 14:06 | gfredericks | hmm |
| 14:07 | gfredericks | the (def foo 'foo) approach is interesting in that it effectively creates a whitelist of keywords |
| 14:07 | gfredericks | which alleviates the keyword-typo problem |
| 14:08 | technomancy | I wonder about an eastwood rule that warned for a keyword that only exists in one place in the whole codebase |
| 14:08 | bbloom_ | technomancy: that's a good idea! |
| 14:09 | bbloom_ | gfredericks: the problem with the whitelisted keywords approach is it creates an import burden |
| 14:09 | gfredericks | technomancy: yeah I've thought of that too |
| 14:09 | bbloom_ | gfredericks: one nice thing about keywords is that you can use them in a mutually recursive fashion w/o forward declarations |
| 14:10 | gfredericks | bbloom_: recursive keywords? |
| 14:10 | bbloom_ | gfredericks: no, recursive code which creates/consumes keywords |
| 14:10 | justin_smith | like {:foo :bar :bar :foo} ? |
| 14:10 | TimMc | technomancy: I don't think that would be useful. If your app makes an HTTP call in just one place, you'll have warnings about :socket-timeout-ms, etc. |
| 14:10 | technomancy | TimMc: it might help if it scanned your deps too |
| 14:10 | TimMc | hmm |
| 14:10 | technomancy | TimMc: but it would suck if you send a message to a system on the other side of an API |
| 14:11 | amalloy | technomancy: it could scan all existnig clojure projects |
| 14:11 | amalloy | if you're the only one in the universe to use keyword X, you get a warning |
| 14:11 | TimMc | It also wouldn't help with :keys destructuring. |
| 14:11 | technomancy | amalloy: taking "whole-program analysis" to a new level |
| 14:11 | gfredericks | ,(->> (str (rand-int 10000000)) keyword) |
| 14:11 | clojurebot | :2339340 |
| 14:11 | amalloy | bbloom_: i'm not convinced you could fit such a directory |
| 14:11 | gfredericks | ,(->> (str "bbloom-" (rand-int 10000000)) keyword) |
| 14:11 | clojurebot | :bbloom-8120204 |
| 14:12 | amalloy | it's like (2^16)^20, right? |
| 14:12 | bbloom_ | amalloy: fine. /usr/share/dict |
| 14:12 | Bronsa | technomancy: there's already a :keyword-typos linter btw |
| 14:12 | technomancy | Bronsa: oh cool; how's that work?= |
| 14:12 | bbloom_ | amalloy: plus edit distance two |
| 14:12 | amalloy | &(apply *' (repeat 20 (apply *' (repeat 16 2)))) |
| 14:12 | TimMc | There are also data-driven keywords e.g. from JSON and databases (which I hapen to think are a bad idea anyway) |
| 14:12 | amalloy | ,(apply *' (repeat 20 (apply *' (repeat 16 2)))) |
| 14:12 | clojurebot | 2135987035920910082395021706169552114602704522356652769947041607822219725780640550022962086936576N |
| 14:12 | bbloom_ | TimMc: a very bad idea |
| 14:12 | bbloom_ | :strs destructuring to the rescue |
| 14:12 | TimMc | srsly |
| 14:12 | bbloom_ | and (callable "maps") |
| 14:12 | Bronsa | technomancy: it uses levenshtein distance on all the keywords to find similar keywords that might be typos |
| 14:13 | technomancy | Bronsa: cool |
| 14:13 | gfredericks | bbloom_: what's the bad part of the idea? |
| 14:13 | TimMc | bbloom_: I hate it when I can't print a data structure and then paste it back into the REPL. |
| 14:13 | bbloom_ | gfredericks: keywordizing data is my pet peeve of the week |
| 14:13 | bbloom_ | it sucks |
| 14:13 | Bronsa | technomancy: if there are 2 :foo and 1 :foz, it will warn about :foz being a typo |
| 14:13 | technomancy | nice |
| 14:13 | gfredericks | bbloom_: because of interning perf things, or semantic issues? |
| 14:14 | bbloom_ | gfredericks: i can't think of any meaningful benefit to doing it, and keywords are a *subset* of arbitrary strings |
| 14:14 | bbloom_ | so surely you're going to run in to a case with a slash or a space in a key |
| 14:14 | bbloom_ | and i have |
| 14:14 | bbloom_ | repeatedly on clojure projects |
| 14:14 | gfredericks | I don't think I like the maps-as-functions alternative though |
| 14:14 | bbloom_ | gfredericks: give me one good reason |
| 14:15 | TimMc | Empty maps can be nil. |
| 14:15 | bbloom_ | "not as pretty" as (:keyword asfunctions) doesn't count |
| 14:15 | TimMc | becuse nil means all things to all functions |
| 14:15 | gfredericks | bbloom_: I think there's two distinct kinds of maps -- heterogeneous/records, and homogeneous; I like keywords-as-functions for the former and maps-as-functions for the latter |
| 14:15 | bbloom_ | TimMc: oh noez, add a get, problem solved |
| 14:15 | TimMc | (:foo some-map) is not the same as (some-map :foo) |
| 14:15 | TimMc | bbloom_: Right, which is not callable maps. |
| 14:15 | gfredericks | bbloom_: I don't think get for string keys is terrible though |
| 14:15 | technomancy | bbloom_: this is how maps work everywhere else in clojure |
| 14:15 | TimMc | And I do use get in those situations. |
| 14:16 | technomancy | adding a distinction just for databases just makes things complicated for no reason, assuming you control the DB schema |
| 14:17 | bbloom_ | gfredericks: my complaint is with automatic conversion absent explicit knowledge about the structure of the incoming data. so being able to distinguish record-like maps from homogenous data addresses the problem |
| 14:17 | technomancy | if you control the DB schema and you create a column with a space then you should consider alternate career choices. |
| 14:17 | bbloom_ | technomancy: sure, but then consider recursive keywordization of json, which is typical of clojure projects |
| 14:17 | TimMc | technomancy: Sometimes it is not your database. |
| 14:18 | gfredericks | bbloom_: if it were combined with a schema validation, that'd be good too? |
| 14:18 | TimMc | technomancy: Sometimes the keys are things like "count(*)" or whatever |
| 14:18 | bbloom_ | gfredericks: it would be acceptable to me :-P |
| 14:18 | technomancy | bbloom_: given that json typically has no schema, that one is less clear-cut to me |
| 14:18 | TimMc | which makes for a really lovely keyword |
| 14:19 | technomancy | TimMc: even if you don't control the DB you should still control the query |
| 14:19 | imanc | what's the fav ide/editor for clojure? |
| 14:19 | justin_smith | emacs usage outnumbers all the rest combined |
| 14:19 | amalloy | justin_smith: does it? i might believe it's only a plurality, not a majority |
| 14:20 | justin_smith | amalloy: it was just under 50% using cider/nrepl - if you add in the inferior-lisp and swank users, it's over 50% total on the last survey |
| 14:20 | TimMc | technomancy: This is like saying "why would you ever call this fn with 0 args?" |
| 14:21 | TimMc | Corner cases *suck*. |
| 14:22 | technomancy | I've written like five SQL queries from clojure total, so maybe I don't know what I'm talking about |
| 14:22 | imanc | justin_smith: Nice, an excuse to venture out of my vim-cave. |
| 14:22 | justin_smith | amalloy: http://cemerick.com/2013/11/18/results-of-the-2013-state-of-clojure-clojurescript-survey/ I think these are the most recent results |
| 14:22 | justin_smith | imanc: I hear the vim tooling is good actually |
| 14:22 | amalloy | justin_smith: well there's some selection bias there: it's a majority of "clojure users who like to fill out surveys" |
| 14:23 | imanc | OK, worth checking out first |
| 14:23 | amalloy | i bet that correlates positively with emacs usage, emacs being a religion that encourages proselytizing |
| 14:23 | technomancy | amalloy: only once someone implements an org-mode interface for gdocs surveys |
| 14:23 | bwreilly | I think if OSX didn't come with postgres or python I'd be 400 hours younger |
| 14:24 | justin_smith | amalloy: not something I'm in to, if that matters. If he asked me "what editor should I use" I would not have jumped to emacs. |
| 14:24 | technomancy | undoubtedly someone has a half-finished implementation somewhere |
| 14:24 | bwreilly | whoops, wrong window |
| 14:24 | joshuafcole | amalloy: Have you tried out our lord, Emacs Slime? |
| 14:24 | amalloy | bwreilly: informative nonetheless |
| 14:24 | amalloy | joshuafcole: emacs rex |
| 14:24 | imanc | I gave LightTable a look in but didn't like |
| 14:25 | imanc | albeit a brief look in |
| 14:25 | joshuafcole | (I've actually switched to LT, but it's been painful) |
| 14:25 | amalloy | imanc: no, stick with vim, or emacs if you're feeling adventurous. that would be my advice, anyway, if you asked for advice instead of for the results of the popularity contest |
| 14:25 | amalloy | i use emacs and it's great, but like justin_smith i hear the vim tooling is good also |
| 14:26 | imanc | amolloy: cool - seeing what vim has to offer. |
| 14:26 | borkdude | I'm reading rich's post on transducers. What's the difference between (sequence xform data) and (iteration xform data)? |
| 14:26 | justin_smith | vim fireplace is great, or so I hear |
| 14:26 | amalloy | imanc: also, your irc client will tab-complete usernames for you, so you never have to misspell one again |
| 14:28 | borkdude | maybe you guys have some more blogposts on transducers I can read? |
| 14:28 | imanc | amalloy: good point. Cheers. =) |
| 14:29 | SegFaultAX | We use HipChat for inter-office communication. We have someone who goes by their initials, @am, and someone who goes by their last name, @ma. It's random chance which one it will complete for you. |
| 14:29 | TimMc | HipChat is the worst. |
| 14:30 | TimMc | I have like 6 major usability bugs logged against it with support. |
| 14:30 | SegFaultAX | I don't know if I'd say it's the worst, but it's pretty bad. |
| 14:30 | mdeboard | yeah we use hipchat as well |
| 14:30 | mdeboard | agreed SegFaultAX |
| 14:30 | TimMc | Such as "randomly skips history" or "crashes when I switch monitors", |
| 14:30 | SegFaultAX | TimMc: And for the longest time, it had no search in the desktop client. |
| 14:30 | TimMc | or my favorite "just kind of removes some parts of URLs" |
| 14:31 | SegFaultAX | Searching would take you to a browser session. |
| 14:32 | justin_smith | wow - so I go to look up what it is, does anything from atlassian not suck? |
| 14:32 | bwreilly | justin_smith: sourcetree is pretty okay |
| 14:33 | TEttinger | yeah, agreed bwreilly |
| 14:33 | TEttinger | I still prefer github for windows as a GUI client |
| 14:33 | mdeboard | bitbucket |
| 14:33 | mdeboard | jira |
| 14:34 | TEttinger | mdeboard, are these reasons to dislike Atlassian? |
| 14:34 | justin_smith | I had bad experiences with jira, but maybe it was just a badly installed / badly used setup |
| 14:34 | TEttinger | I always hear JIRA in a negative context |
| 14:34 | TimMc | justin_smith: Atlassian only very recently bought HipChat, which had a long history of suck already. |
| 14:34 | justin_smith | OK |
| 14:34 | SegFaultAX | I think that's mostly a side-effect of JIRA being the wordpress of project management software |
| 14:35 | SegFaultAX | You can do literally anything with it, so people do literally everything with it. |
| 14:35 | bwreilly | I've yet to have a good experience with jira. We've since moved on to Trello and github issues and it's been a vast improvement. |
| 14:35 | sveri1 | TEttinger we are using JIRA and and Confluence at Software AG and I can only find a few things lacking, so for my side it is pretty ok |
| 14:36 | TEttinger | all this java enterprise software makes me think of https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition/tree/master/src/main/java/com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/impl |
| 14:37 | SegFaultAX | TEttinger: The one true fizzbuzz impl. |
| 14:38 | TEttinger | I'm also a fan of the completely incomprehensible livescript version of fizzbuzzbazz |
| 14:38 | bwreilly | SegFaultAX: There are some strong contenders out there. http://ideone.com/r3VOfZ and http://pastebin.com/6ZfanN2q spring to mind |
| 14:38 | TEttinger | [++x>?[k+\zz for k,v of{Fi:3,Bu:5,Ba:7}|x%v<1]*'' for x to 99] |
| 14:40 | TEttinger | oh no, what??? that random seed one is epic |
| 14:41 | bbloom_ | ,(let [^byte x 5] (.put (java.nio.ByteBuffer/allocate 100) x)) |
| 14:41 | clojurebot | #<CompilerException java.lang.UnsupportedOperationException: Can't type hint a local with a primitive initializer, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:41 | bbloom_ | what can i do about that? |
| 14:41 | bbloom_ | particularly b/c there are various other 1-arity put methods on ByteBuffers |
| 14:42 | amalloy | bbloom_: (let [x (byte 5)] ...) |
| 14:42 | bbloom_ | amalloy: anyway to avoid that call? this is in a tight inner loop (eg handling bytes) |
| 14:43 | amalloy | (let [x (byte 5)] (loop ...)) |
| 14:43 | bbloom_ | lol, not quite gonna solve my problem |
| 14:43 | bbloom_ | but thanks, that'll do for now... i guess |
| 14:44 | xulfer | Anyone have any suggestions on what to use for a gui application in clojure? I've been looking for a pure clojure solution and haven't much yet. |
| 14:44 | SegFaultAX | bbloom_: Were you hoping to avoid boxed bytes? |
| 14:44 | bbloom_ | SegFaultAX: yes |
| 14:44 | amalloy | my suggestion should avoid boxed bytes |
| 14:44 | SegFaultAX | ,(type (byte 5)) |
| 14:44 | clojurebot | java.lang.Byte |
| 14:44 | bbloom_ | SegFaultAX: that doesn't tell you if the byte or type fn causes the boxing |
| 14:44 | amalloy | SegFaultAX: ummmm...type always prints a boxed type |
| 14:45 | SegFaultAX | I see. |
| 14:45 | amalloy | because it's a function, and you can only call it with an object |
| 14:45 | xulfer | Seesaw looked really good, but it seems like there's a lot that you still have to roll yourself. Which kind of makes everything seem kind of hackish. |
| 14:47 | bridgethillyer | imanc: my advice is to use the editor you’re comfortable with |
| 14:48 | SegFaultAX | I've never spent much time looking at clojure.lang.RT/*Cast. Neat |
| 14:48 | bridgethillyer | I use vim and am very happy with vim-fireplace |
| 14:48 | bridgethillyer | And then eventually move to emacs :) |
| 14:48 | amalloy | bbloom_, SegFaultAX: for your amusement, i wrote https://www.refheap.com/03fe1a97b114f4f8cd89223d7, a function using my suggested approach and its disassembly, to verify that it indeed never uses a BYte |
| 14:49 | bbloom_ | amalloy: that's good news, but it still emits the RT.byteCast static call |
| 14:49 | SegFaultAX | bbloom_: How much do static calls cost? |
| 14:50 | bbloom_ | SegFaultAX: very little, but again: tight inner loop |
| 14:50 | amalloy | well, yes. it kinda has to, because clojure doesn't have byte literals |
| 14:50 | SegFaultAX | bbloom_: If it's that tight, why not just write it in Java? |
| 14:51 | amalloy | bbloom_: either the byte you want to write is a constant (in which case, yuo can let it once and reuse it, so there's no "loop"), or it's a non-constant primitive byte (in which case, just use it), or it's a non-constant non-byte (in which case, you have no choice but to emit multiple casts) |
| 14:52 | bbloom_ | amalloy: fair enough |
| 14:52 | amalloy | i'm a little surprised that (unchecked-byte 5) still emits a static call, actually; i would have expected that to use some intrinsic |
| 14:52 | bbloom_ | SegFaultAX: i already have some bits in java where perf really matters |
| 14:52 | amalloy | l2b or something |
| 14:52 | bbloom_ | amalloy: clojure's compiler has virtually zero intrinsics |
| 14:52 | amalloy | bbloom_: it has a couple dozen |
| 14:52 | SegFaultAX | amalloy: What did you use to decompile that? |
| 14:53 | amalloy | SegFaultAX: (println (no.disassemble/disassemble-str (fn ...))) |
| 14:53 | SegFaultAX | Oh I forgot about no.disassemble. |
| 14:53 | SegFaultAX | Thanks |
| 14:53 | amalloy | SegFaultAX: i have it in my ~/.lein/profiles for :swank, so that it's loaded whenever i'm playing around but not included in my uberjars |
| 14:54 | bbloom_ | amalloy: huh, you're right. i forgot about the Intrinsics class |
| 14:54 | amalloy | super convenient. same for criterium |
| 14:54 | bbloom_ | amalloy: i kinda wish i could add some easily :-P |
| 14:54 | bbloom_ | amalloy: yeah looks like only int, longs, and doubles are in intrinsics |
| 14:54 | bbloom_ | amalloy: would be nice to have all jvm primitives, heh |
| 14:55 | SegFaultAX | I've tried 3 or 4 times using evil, and it's great for core emacs. But very few plugins I've seen have much if any support for it. |
| 14:55 | SegFaultAX | I wonder if I should just break my vim muscle memory forever and switch to emacs once and for all. |
| 14:55 | postpunkjustin | SegFaultAX: It took me forever to get evil to the point where it could realistically replace vim for me. |
| 14:56 | postpunkjustin | But once I did, it was glorious. |
| 14:56 | SegFaultAX | postpunkjustin: Are your dotfiles online? I'd love to take a look. |
| 14:56 | Bronsa | you can always (def ^:const FIVE (byte 5)) |
| 14:56 | justin_smith | Bronsa: I am picturing an entire namespace of that, and it is glorious and horrific |
| 14:57 | postpunkjustin | SegFaultAX: Not at the moment, but I'm planning on it. I'd like to go through and properly refactor/document the settings so that it'll be more useful to people. |
| 14:57 | SegFaultAX | postpunkjustin: I'd be happy to look at it even uncommented. Any chance you'd be willing to tar it up and email it to me? :D |
| 14:58 | postpunkjustin | I guess there's no reason not to just put it up on GH now... |
| 14:58 | SegFaultAX | I'll trade you: https://github.com/SegFaultAX/vim-dotfiles :) |
| 14:59 | amalloy | bbloom_: clojure.lang.Intrinsics/ops isn't final. you'd have to do a little reflection, but you could add a new one probably |
| 15:00 | bbloom_ | amalloy: heh, ok, but maybe i'll just write 10 lines of java instead, to go with my other 15 lines of java so i could extend a concrete class :-) |
| 15:01 | amalloy | interesting. there's actually not a bytecode primitive for l2b that i can see |
| 15:01 | amalloy | you may have to go l2i, and then i2b? |
| 15:01 | mdeboard | l2b? |
| 15:01 | Bronsa | long to byte |
| 15:01 | amalloy | long to byte |
| 15:01 | mdeboard | ah |
| 15:02 | postpunkjustin | SegFaultAX: Cool, I'm throwing together a README right now just so people won't be totally lost. |
| 15:03 | Bronsa | amalloy: yeah, looks like that's how javac compiles byte foo(long x) { return (byte) x; } |
| 15:03 | amalloy | lame |
| 15:06 | celwell | Hi, I'm trying to cycle a list of maps, but I'm getting weird results. I'm using (take 10 (cycle ({:test "1" :blah "a"}{:test "2" :blah "b"}{:test "3" :blah "c"}))) |
| 15:07 | amalloy | celwell: that's not a list of maps |
| 15:07 | hiredman | celwell: list literals are function calls unless quoted |
| 15:07 | celwell | I'd like it to instead cycle through the list with each map as a unit. |
| 15:07 | celwell | bah, tahnks |
| 15:07 | celwell | yeah I always make this mistake... |
| 15:08 | nkoza | celwell: use more vectors :) |
| 15:08 | celwell | ha, ok. thanks |
| 15:10 | postpunkjustin | SegFaultAX: https://github.com/holguinj/evil-clojure-emacs |
| 15:12 | moro | Does anyone know of a tutorial that deals with accumulators and core.async? I want to create a chan that listens to another chan, accumulates the entries and then flattens them once a certain threshold is reached, ie. for batch processing |
| 15:12 | SegFaultAX | postpunkjustin: Thanks! |
| 15:13 | moro | so chan1 produces individual entries, chan2 accumulates them and sends them in batches, chan3 writes the info to the db |
| 15:13 | postpunkjustin | You're welcome |
| 15:17 | stuartsierra | moro: Sounds like a job for transducers :) |
| 15:20 | bridgethillyer | postpunkjustin: Thanks +1. That might just be the inspiration I need to finally start switching over to emacs |
| 15:27 | moro | stuartsierra thanks, do you know which core.async version introduced them? I have an external dependency that relies on an older version of core.async |
| 15:28 | stuartsierra | moro: don't know |
| 15:28 | stuartsierra | you could also do it with a standalone go/loop |
| 15:32 | moro | thanks! |
| 15:39 | mikerod | is there a good place to find the #clojure irc logs? |
| 15:39 | mikerod | I was struggling to find logs that covered today out there |
| 15:40 | ArseneRei | mikerod: http://logs.lazybot.org/irc.freenode.net/#clojure/today.txt |
| 15:40 | mikerod | ArseneRei: this tells me "These are not the logs you're looking for." |
| 15:40 | mikerod | hmm :P |
| 15:40 | justin_smith | http://logs.lazybot.org/ |
| 15:40 | mikerod | oh |
| 15:40 | mikerod | it worked |
| 15:40 | ArseneRei | mikerod: Weird, it works for me. |
| 15:41 | mikerod | after I went back a few |
| 15:41 | mikerod | ok, so are these up-to-date? |
| 15:41 | mikerod | it finishes at "22:22:03" |
| 15:41 | mikerod | with people saying good night |
| 15:41 | borkdude | I'm trying out a transducer in clojure 1.7. Shouldn't the order of comp work the same as in normal function comp? https://gist.github.com/borkdude/e5f77b9b80a523d62d55 |
| 15:42 | mikerod | Maybe the lazybot logs are lazy? |
| 15:42 | mikerod | :P |
| 15:42 | ArseneRei | mikerod: Haha, maybe. |
| 15:42 | mikerod | borkdude: one thing is that normal `comp` will create a lot of intermediate seqs |
| 15:42 | mikerod | Beyond that I'm not sure |
| 15:43 | Bronsa | borkdude: no, transducers compose in the opposite order |
| 15:43 | mikerod | With transducers you are really building up a transformed fn that does not "thread" the a single fn results from one to the next. |
| 15:44 | mikerod | Note: this is what I believe it to be doing at this point - I can't say I'm actually correct. :P |
| 15:44 | shriphani | Hi, I have a question about reflection - I want to generate a class at runtime (with a user-specified function). This class is going to be consumed by another java app (which is going to pick this up via reflection). Can anyone recommend the right way to do this ? Thanks. |
| 15:45 | justin_smith | shriphani: does this class need to be an implementation of a specific interface, or subclass of a given class? |
| 15:45 | mikerod | "lazily transform the data (one lazy sequence, not three as with composed sequence functions)" - http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming |
| 15:47 | borkdude | Bronsa I see, there must be a good reason for this, right? |
| 15:48 | mikerod | I'm surprised they'd compose in a different order |
| 15:48 | mikerod | defying math like that |
| 15:48 | mikerod | notation* |
| 15:48 | Bronsa | borkdude: I'm pretty sure it's an artifact of their implementation rather than a design choice |
| 15:49 | Bronsa | borkdude: but I didn't design/implement them so don't take my word for it :0 |
| 15:49 | Bronsa | :)* |
| 15:49 | shriphani | justin_smith, subclass |
| 15:50 | shriphani | justin_smith, does that make life harder ? |
| 15:50 | puredanger | mikerod: it is necessary that transducers compose as they do |
| 15:52 | puredanger | calling a transducer function returns a function that takes the next function in the transducer chain to call, which is an important part of how they work to avoid creating intermediate collections |
| 15:52 | mikerod | puredanger: I'm not really against the ordering, I just think it is interesting and I wonder what the motivations were that caused it |
| 15:52 | mikerod | that sounds like a pretty good explanation to me. thanks! |
| 15:53 | puredanger | so you can think of calling the "map" transducer function as saying "map a pred *before* you do the next step" |
| 15:54 | mikerod | interestign |
| 15:54 | mikerod | is one of the primary advantages of transducers to cut out the intermediary collections? |
| 15:54 | moro | my brain my brain, I probably can just use a reduce inside a go-loop for that, stuartsierra |
| 15:54 | puredanger | mikerod: that is one of the beneficial consequences |
| 15:55 | puredanger | I would say the primary advantage is that it separates the transformation algorithm from the collection/iteration mechanism |
| 15:56 | mikerod | puredanger: I think I have a bit of a grasp of the benefits in those terms. For example right now clj has, map & mapv |
| 15:56 | mikerod | because we want an "eager" map that returns a vector |
| 15:56 | mikerod | and we don't want to right (vec (map <blah> <blah>)) |
| 15:56 | borkdude | hmm https://gist.github.com/borkdude/33d79402e689460e62d6 |
| 15:56 | mikerod | to write** |
| 15:57 | justin_smith | shriphani: for a sublclass, the easiest thing is probably proxy - reify is easier, but only does interfaces |
| 15:57 | shriphani | justin_smith, and how do I dump it to a .class file ? |
| 15:57 | mikerod | But with transducers, you can define mapping abstractly as a transformation fn and stick it between a source and a target wherever you want. |
| 15:57 | mikerod | So if I want `map-set` |
| 15:57 | puredanger | yes |
| 15:57 | mikerod | (set (map <blah> <blah>)) |
| 15:57 | mikerod | booo |
| 15:57 | puredanger | mikerod: the map transducer does almost nothing other than apply pred to 1 element - https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2571 (and call the next transducer) |
| 15:57 | mikerod | (into #{} maptransfomration <source>) |
| 15:58 | shriphani | justin_smith, I can see a gen-class form but I am not sure how to mix the two (I have used proxy before so that part is ok). |
| 15:58 | justin_smith | shriphani: I don't know the easiest way to make a .class file at runtime, someone else may be able to weigh in |
| 15:58 | justin_smith | shriphani: gen-class isn't really doable as an arbitrary runtime thing is it? |
| 15:59 | shriphani | justin_smith, doesn't look like it. |
| 15:59 | stuartsierra | shriphani: I'm not sure it's possible to do what you want to do. `gen-class` only applies when AOT-compiling. |
| 15:59 | puredanger | mikerod: as opposed to the lazy seq map (https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2572-L2582) which knows how to turn something into a sequence, break into first/rest, do output construction (all with chunking complexity too) |
| 15:59 | technomancy | justin_smith: technically of course you can do it |
| 15:59 | stuartsierra | Clojure isn't really designed to generate arbitrary Java classes at runtime. |
| 15:59 | technomancy | there's no such thing as not-runtime in clojure |
| 15:59 | shriphani | stuartsierra, so I can't generate a .class file at all ? |
| 15:59 | technomancy | whether it's a good idea is another question |
| 16:00 | justin_smith | technomancy: OK - but how would I create a .class file with gen-class in response to a client request? I don't think there is a straightforward way to do that. |
| 16:00 | shriphani | technomancy, the situation here is that I want to be able to use clojure code in an existing spring project. |
| 16:00 | stuartsierra | shriphani: There's always a way, as technomancy says, but it's not really something Clojure is designed to do. |
| 16:01 | shriphani | stuartsierra, what is the way ? |
| 16:01 | Bronsa | puredanger: would it be out of the question to make comp reverse the fn orders when composing transducers? I'm kinda guessing the answer will be yes |
| 16:01 | puredanger | yes :) |
| 16:01 | stuartsierra | shriphani: Often its easier to write a stub class in Java which calls the Clojure function. |
| 16:01 | Bronsa | heh, I tried |
| 16:01 | technomancy | justin_smith: you could write to a directory on the classpath and call clojure.core/compile |
| 16:01 | shriphani | stuartsierra, that is totally acceptable to me. |
| 16:01 | shriphani | but I prefer to avoid recompiling my java code |
| 16:02 | llasram | You can always `eval` calls to gen-class |
| 16:02 | stuartsierra | shriphani: For example, https://github.com/pedestal/pedestal/blob/68b72a310e1cc5d32951ce0489a0ec7feaf9e726/service/java/io/pedestal/servlet/ClojureVarServlet.java |
| 16:02 | technomancy | llasram: as long as you bind *compile-files* |
| 16:02 | borkdude | when will using transducers without lazy intermediate collections yield better performance than "normal"? in my example it seems it's slower due to maybe overhead. |
| 16:02 | mikerod | puredanger: nice, I think I'm seeing what you are saying in terms of the 2 map varieties. this is certainly interesting. I think transducers look promising. |
| 16:02 | Bronsa | I'm sure I'll get used to the reverse order, but for now each time I've played with transducers, no matter how much I remind myself of the reversed comp order, I keep messing it up |
| 16:03 | llasram | technomancy, shriphani: Or reach slightly into the implementation https://github.com/llasram/shady/blob/master/src/shady/gen_class.clj |
| 16:03 | puredanger | mikerod: the consequences of clearly separating these things are 1) you can define a "suspended algorithm" once and apply it in many ways (that's really a decoupling kind of benefit and will take time to really permeate the Clojure ecosystem I think and 2) because the algorithm is separated |
| 16:04 | puredanger | you can avoid all sorts of intermediate cruft that was bound up in the old combined definition |
| 16:04 | borkdude | puredanger how easy is it to debug a huge composed transducer? |
| 16:05 | llasram | shriphani: Oh, earlier you said you needed for the Java consumer to access the generated class via reflection. If you can just pass instances in, then stuartsierra's suggestion is 100% the way to go |
| 16:05 | puredanger | transducer stacks with more than one transformation will generally be faster now and we have a bunch of additional changes coming for even more benefits |
| 16:05 | puredanger | borkdude: I haven't really done that yet but conceptually, it might be easier because you have removed laziness |
| 16:05 | puredanger | you still have a call stack with all of the transducer functions on the stack |
| 16:06 | puredanger | core.async debugging will still be hard :) |
| 16:06 | borkdude | puredanger why is the example on line 11 slower than on line 5 and 8? |
| 16:06 | borkdude | puredanger https://gist.github.com/borkdude/33d79402e689460e62d6 |
| 16:07 | puredanger | borkdude: without knowing your jvm settings, I don't believe any of those numbers |
| 16:07 | shriphani | llasram, the java consumer here is expected to be running and adds a new job via a spring config file. Unless the jar it is running off knows about my clojure code, it can't use my class |
| 16:07 | puredanger | borkdude: which is not to say that they're wrong, just that there are unknown variables to resolve first :) |
| 16:07 | borkdude | puredanger eh, here is the screenshot from my screen. I didn't fake it :) https://www.dropbox.com/s/8or9ga9ta36a88h/Screenshot%202014-08-21%2022.07.24.png |
| 16:08 | BobSchack | borkdude: I'd guess because you have to go through a lazy sequence for #11 |
| 16:08 | puredanger | I know you didn't fake it, it's just that things like lein and cider confound good perf numbers |
| 16:08 | borkdude | puredanger ok, I'll try it in a vanilla lein repl |
| 16:09 | justin_smith | borkdude: while you are at it, use criterium instead of dotimes |
| 16:09 | shriphani | llasram, can I use shady's generate-class to create my .class file ? |
| 16:09 | mikerod | +1 criterium |
| 16:09 | puredanger | borkdude: you should really set your :jvm-opts ^:replace ["-server" "-Xmx512m"] in project.clj and yes, use something like criterium. I'm sorry that's all annoying but it matters. |
| 16:09 | Bronsa | http://sprunge.us/cPVT here's my results |
| 16:10 | Bronsa | not through lein |
| 16:10 | borkdude | Bronsa same thing |
| 16:11 | llasram | shriphani: Let me read some backlog, or if you have a link to documentation describing what you're trying to wire up? |
| 16:11 | mikerod | Bronsa: well now we need some profiling snapshots :P |
| 16:11 | llasram | shriphani: It's starting to sound like you want to generate a class which you ship over to an entirely different JVM via a JAR? |
| 16:11 | shriphani | llasram, sort of |
| 16:11 | shriphani | not sure if a .jar is necessary |
| 16:12 | llasram | But it is in a different JVM? |
| 16:12 | shriphani | yes, different jvm. |
| 16:12 | puredanger | Bronsa: so, you're seeing sequence as slower and into as faster |
| 16:12 | justin_smith | shriphani: then why even speak of generating the class at runtime? you can just use gen-class in this case, right? |
| 16:12 | Bronsa | puredanger: seems like chunked-seqs come into play with those results |
| 16:12 | Bronsa | replacing (range 1000) with (take 1000 (iterate inc 0)) changes significantly the results |
| 16:12 | puredanger | Bronsa: into is reducing and avoid any intermediate stuff so that makes sense |
| 16:13 | stuartsierra | doall/dorun don't know about chunked seqs or transducers. |
| 16:13 | shriphani | justin_smith, some class members are going to be specified by the caller of the API |
| 16:14 | puredanger | Bronsa: I would still expect sequence with a transducer to be faster than lazy seqs in this case. |
| 16:14 | Bronsa | puredanger: http://sprunge.us/XVUc |
| 16:15 | llasram | shriphani: Then this is kind of tricky... So `gen-class` generates classes which proxy to a Clojure namespace, which they will `require`. So you need to ship over the Clojure code too, as well as Clojure itself and any dependencies. |
| 16:15 | Bronsa | lazyseq w/ chunked-seqs seems to be fastest, lazyseq w/o chunked-seqs slowest |
| 16:15 | Bronsa | but again, I'm testing on a bare repl, maybe criterium will give different results |
| 16:15 | llasram | shriphani: I can't help but feel there might be a simpler solution here somewhere. Can you provide any more specifics? |
| 16:16 | puredanger | Bronsa: chunked seqs can be surprisingly fast sometimes. you are munging the initial case from repeated cases. depending which hotspot compiler you're using you might not be getting compiled yet (-server takes 10000 reps I think before inlining). |
| 16:17 | puredanger | Bronsa: take has state that uses atoms. I have a patch prepped for Rich that replaces that with volatiles internally and is significantly faster. that will improve take, drop, partition, etc. |
| 16:17 | puredanger | Bronsa: the transducer version that is |
| 16:17 | shriphani | hmm so ok, there's a pipeline in the java app I am using. One of the components of the pipeline has a routine that I want to be able to implement in clojure (there's some libs I have in clojure). The java consumer keeps running and whenever I call my API, I should be able to set up a new pipeline with my clojure routine. |
| 16:17 | Bronsa | puredanger: cool but that has nothing to do with how I'm using it here |
| 16:18 | puredanger | oh right |
| 16:18 | Bronsa | puredanger: I'm using (take n (iterate inc 0)) to get the same sequence as (range n) but unchunked |
| 16:18 | shriphani | I was earlier spinning up a separate clojure process and using sockets to handle this but I would rather avoid using 2 running processes for this |
| 16:18 | azizur | hello everyone |
| 16:19 | puredanger | Bronsa: there are plans to transducerify range and some other "sources" as well which should help significantly |
| 16:20 | llasram | shriphani: Ok. So why does the Clojure code itself need to cross over to the consumer? |
| 16:20 | shriphani | llasram, is there a way to avoid this ? |
| 16:21 | stuartsierra | `transducerify` is the name of my new pharmaceutical start-up. |
| 16:21 | shriphani | the pipeline in the java consumer is specified in a spring config file as a sequence of classes. |
| 16:21 | justin_smith | shriphani: what about just having your generated class invoke a function inside an atom, and modifying the atom as needed at runtime? |
| 16:21 | justin_smith | you still get the updates at runtime, without needing to generate .class files |
| 16:22 | shriphani | justin_smith, would this require a second process ? |
| 16:22 | justin_smith | it really should not |
| 16:22 | llasram | shriphani: Could you link to documentation for this? I'm not really familiar with Spring |
| 16:22 | borkdude | what does xform stand for. |
| 16:22 | amalloy | transform |
| 16:22 | shriphani | llasram, here is an example of a config file: https://gist.github.com/shriphani/ef02b08a08fa1e0d6361 |
| 16:23 | justin_smith | you would have to figure out the logic for creating the function that your class invokes - but the class could just be there and not change, and what would change would be the atom it derefs to find the function it should call |
| 16:23 | shriphani | so the <bean id="###"... class="###" > are the classes that the java app loads |
| 16:24 | shriphani | justin_smith, actually that sounds smarter |
| 16:24 | shriphani | and I can say load the routine from a .clj file on disk ? |
| 16:24 | justin_smith | sure, or you could just generate it by calling another function |
| 16:25 | justin_smith | really it depends on how flexible this thing needs to be |
| 16:25 | llasram | shriphani: Oh, then to configure the instances, it calls the instance setters for the various properties's values? So for ConfigFile, it would call setPath("seeds.txt") ? |
| 16:25 | shriphani | llasram, yeah |
| 16:26 | justin_smith | ,(let [to-call (atom +)] [(map @to-call (range 3)) (do (reset! to-call -) (map @to-call (range 3)))]) |
| 16:26 | clojurebot | [(0 1 2) (0 -1 -2)] |
| 16:26 | TEttinger | stuartsierra: you'll be passe by 1.8.0. haven't you heard of megaducers? http://pastebin.com/3mwr5hBJ |
| 16:27 | shriphani | ideally I would have a ClojureComponent in the pipeline and the properties could specify that a routine is on disk and load it up ? |
| 16:27 | TEttinger | I spent like half an hour coming up with different kinds of *ducer to introduce in future clojure versions |
| 16:27 | llasram | shiranaihito: That should totally work. |
| 16:27 | turbofail | introducer |
| 16:27 | llasram | er, ^ shriphani |
| 16:27 | shiranaihito | :P |
| 16:28 | arohner | is clj-webdriver still the best option for browser-based testing? |
| 16:28 | shriphani | yeah that is much smarter. |
| 16:29 | llasram | shriphani: I'm still not entirely getting what part needs to be dynamic, but if you can have a concrete Java class which you can configure to load some arbitrary Clojure code, then your job gets waaaay easier |
| 16:29 | shriphani | llasram, that is exactly what I want |
| 16:30 | shriphani | all this would boil down to a simple (load-file ##) then. |
| 16:30 | justin_smith | shriphani: I'd say, use an atom to store the function to actually call, and use any of load or premade functions or a function generating function, plus reset! to set the function to actually be used |
| 16:31 | shriphani | justin_smith, yep that sounds correct. |
| 16:31 | justin_smith | sure, if storing the function in a file is preferable to having all your options be statically in the ns |
| 16:32 | justin_smith | I guess this is DI scenario where the client may be specifying the function via a file found at app init |
| 16:32 | shriphani | justin_smith, the user is going to be specifying a function in another jvm. |
| 16:32 | shriphani | so in a REPL I want to do (start-pipeline {:routine-1 (fn [a b] (println a b))}).... for example |
| 16:33 | justin_smith | yeah, so either have them put it in a file in the classpath you can find, or have them pass the function to your class as a "config" step - but with spring, the former is probably more familiar behavior |
| 16:34 | shriphani | justin_smith, how would the former work |
| 16:34 | shriphani | say the java app expects to see a pipeline component in org.foo.pipeline. |
| 16:35 | justin_smith | they would call an init or config function in your ns, telling it what function it uses. the class that spring finds invokes the class in your ns, and it invokes said function when needed |
| 16:35 | justin_smith | but like I said, just putting it in a .clj file that you call load on may play nicer with how the rest of the framework does things |
| 16:36 | shriphani | justin_smith, how would I do that from a different jvm ? |
| 16:36 | shriphani | not the .clj file |
| 16:36 | azizur5 | hi everyone can someone help me please |
| 16:37 | justin_smith | why does which jvm does this even matter? at runtime, they need to invoke the function in your ns (exposed as a method also) which tells it the function it will use |
| 16:37 | azizur5 | I am trying to let into an vector is that possible? |
| 16:37 | justin_smith | alternatively, there is no explcit setting step, and you just look for a file with a magic path / name |
| 16:38 | postpunkjustin | azizur5: can you explain a little more what you mean? |
| 16:39 | azizur5 | postpunkjustin I am trying to follow this: http://http-kit.org/client.html#combined |
| 16:39 | azizur5 | tryng to get response from a series of http request concurrently (asynchronously) |
| 16:40 | shriphani | justin_smith, makes sense - yeah this is much cleaner than mucking about with .class files. |
| 16:40 | postpunkjustin | azizur5: Ok, I'm with you so far. What do you mean by "let into a vector"? |
| 16:40 | azizur5 | where it gets chellenging is I want each response to be mapped into a named function for further processing... |
| 16:41 | justin_smith | azizur5: do you want to run multiple get requests, and return them all in a vector? |
| 16:42 | justin_smith | (all the results, that is) |
| 16:42 | azizur5 | correct |
| 16:42 | azizur5 | but before they go into vector I want to pass them into series of functions... |
| 16:43 | azizur5 | for example response1 passed to f1, resp2 to f2 and so on |
| 16:43 | amalloy | (map #(% %2) functions resps) |
| 16:43 | azizur5 | let me try that amalloy |
| 16:44 | justin_smith | (mapv #(% (http/get %2)) [f1 f2 f3] ["http://google.com" "http://twitter.com" "http://facebook.com"]) |
| 16:44 | justin_smith | (another option) |
| 16:45 | arohner | can someone remind me of the name of that macro for destructing, for when you want to write a macro that behaves like defn? |
| 16:45 | arohner | (defmacro deffoo [& args] (??? args)) |
| 16:46 | azizur5 | justin_smith thanks for that too. I will try that aswell |
| 16:47 | justin_smith | $(source let) |
| 16:47 | justin_smith | $source let |
| 16:47 | amalloy | arohner: it's not for destructuring at all, but you may be thinking of clojure.tools.macro/name-with-attributes |
| 16:47 | justin_smith | arohner: anyway, look at let's source, it is very concise, and it is called "destructure" |
| 16:47 | azizur5 | amalloy cant do that as http/get are future: ClassCastException clojure.lang.LazySeq cannot be cast to java.util.concurrent.Future |
| 16:47 | arohner | amalloy: yes, name-with-macro is what I was thinking of, thanks |
| 16:47 | amalloy | justin_smith: but there's no reason you'd use destructure for that! you'd just emit a call to let |
| 16:50 | shriphani | justin_smith, I have thought of a potential problem with using a .clj file, it is very possible that the user uses other libs that the main java app won't have loaded. |
| 16:50 | azizur5 | justin_smith thank you that worked... with some modifications |
| 16:50 | justin_smith | azizur5: cool, glad you figured it out |
| 16:54 | shriphani | justin_smith, I am still not sure I understand your idea to set this at runtime by calling a routine. |
| 16:55 | roshan_ | Hi i am new and would like to contribute can someone get me starteed |
| 16:56 | brehaut | …to clojure? |
| 16:56 | brehaut | http://clojure.org/contributing |
| 16:56 | roshan_ | Yes to clojure |
| 16:56 | brehaut | have you read that page? |
| 16:57 | SagiCZ1 | roshan_: hi! |
| 16:57 | roshan_ | I am reading |
| 17:08 | Fare | to map a function onto all the values of a map, is there simpler than #(into {} (map (fn [[k v]] [k (inc v)]) %)) ? |
| 17:09 | Fare | I can also see the ugly #(merge-with (fn [v _] (inc v)) % nil) |
| 17:09 | amalloy | Fare: that merge-with won't do anything |
| 17:09 | justin_smith | maybe % % |
| 17:10 | justin_smith | but that is way ugly |
| 17:10 | Fare | % % |
| 17:10 | amalloy | the former is fine, although i'd suggest for over map |
| 17:10 | Fare | yes |
| 17:10 | amalloy | (into {} (for [[k v] m] [k (f v)])) |
| 17:10 | amalloy | <3 into |
| 17:11 | bbloom_ | my favorite part of into is that there's no need for a billion conversion functions |
| 17:11 | shriphani | justin_smith, would there be a simpler way to dump my fn to disk ? |
| 17:12 | justin_smith | shriphani: why does it need to be on disk? technomancy has a project for serializable functions iirc |
| 17:12 | justin_smith | I mean other than in the sense that any namespace is on disk |
| 17:13 | Fare | ambrosebs, it was nice meeting you in Montreal! |
| 17:14 | ambrosebs | Fare: you too! |
| 17:14 | amalloy | but that's so hallmark, Fare: mine is clearly hand-crafted |
| 17:14 | shriphani | justin_smith, what if the fn depends on a lib that the main java process doesn't have loaded ? |
| 17:15 | Fare | amalloy: you didn't craft the individual underlying electrons, though, did you? |
| 17:17 | aperiodic | Fare: I'm sure he used locally sourced, free-range electrons |
| 17:18 | sdegutis | Hi. |
| 17:18 | amalloy | clojurebot: amalloy |only uses| locally sourced, free range electrons |
| 17:18 | clojurebot | You don't have to tell me twice. |
| 17:18 | stompyj | (inc amalloy) |
| 17:18 | TimMc | ♥ |
| 17:19 | stompyj | ‘(inc amalloy) |
| 17:19 | TimMc | ^ artisanal Unicode, I typed in the hex myself |
| 17:19 | stompyj | <— needs sleep |
| 17:19 | mthvedt | how about electrons that can roam, but are confined to energy bands? |
| 17:19 | mthvedt | ethical or unethical? |
| 17:19 | hyPiRion | (inc amalloy) ;; what you're looking for |
| 17:19 | hyPiRion | oh wait, lazybot is down |
| 17:19 | gfredericks | ,('inc 'amalloy) |
| 17:19 | clojurebot | nil |
| 17:20 | TimMc | ,'^:'^: |
| 17:20 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: :> |
| 17:20 | amalloy | hyPiRion: yes, although stompyj actually did misspell it both times |
| 17:21 | amalloy | &1 |
| 17:21 | lazybot | ⇒ 1 |
| 17:21 | stompyj | (inc amalloy) |
| 17:21 | lazybot | ⇒ 162 |
| 17:21 | stompyj | PHEW |
| 17:23 | gfredericks | (inc alimony) |
| 17:23 | lazybot | ⇒ 1 |
| 17:23 | sdegutis | I'm writing a package manager and would appreciate any feedback on its current architecture. |
| 17:23 | gfredericks | omg fellahs |
| 17:23 | gfredericks | if you spell amalloy backwards |
| 17:24 | Fare | https://github.com/Dobiasd/programming-language-subreddits-and-their-choice-of-words#happiness |
| 17:24 | sdegutis | Is it reasonable to ask that package authors submit both a metadata.json file and docs.json file for their extension, to my repository, where they will live until further update? |
| 17:24 | gfredericks | clojurebot: amalloy spelled backwards is Yo Llama |
| 17:24 | clojurebot | You don't have to tell me twice. |
| 17:25 | aperiodic | clojurebot: amalloy |spells| Yo Llama backwards |
| 17:25 | clojurebot | Alles klar |
| 17:25 | amalloy | you don't need *both* of those, guys |
| 17:25 | amalloy | ~amalloy |
| 17:25 | clojurebot | amalloy only uses locally sourced, free range electrons |
| 17:25 | gfredericks | the latter is more accessible |
| 17:26 | aperiodic | I thought gfredericks's factoid would only show up for ~(amalloy spelled backwards) |
| 17:26 | amalloy | it probably would |
| 17:26 | sdegutis | Fare: We are the most verbose? |
| 17:26 | sdegutis | Also, see Forth: https://raw.githubusercontent.com/Dobiasd/programming-language-subreddits-and-their-choice-of-words/master/img/happy_all.png |
| 17:29 | gfredericks | clojurebot: yo llama is amalloy |
| 17:29 | hyPiRion | Wonder why cobol programmers are so happy. |
| 17:29 | clojurebot | A nod, you know, is as good as a wink to a blind horse. |
| 17:30 | amalloy | whoa whoa what. i've never heard clojurebot say *that* before |
| 17:30 | gfredericks | me neither |
| 17:30 | amalloy | hiredman: hax? |
| 17:30 | sdegutis | clojurebot: what is amalloy |
| 17:30 | clojurebot | Ok. |
| 17:30 | brehaut | hyPiRion: one presumes that their rates make up for everything at this point |
| 17:30 | gfredericks | maybe it's only unlocked when you're talking about horse-shaped animals |
| 17:30 | sdegutis | sigh |
| 17:30 | metellus | ~what |
| 17:30 | clojurebot | what could possibly go wrong |
| 17:30 | sdegutis | ~amalloy |
| 17:30 | clojurebot | amalloy spells Yo Llama backwards |
| 17:30 | metellus | well I hope it doesn't. |
| 17:31 | sdegutis | how did.. |
| 17:31 | sdegutis | I don't even... |
| 17:31 | sdegutis | that's not what.. |
| 17:31 | metellus | sdegutis |is |
| 17:31 | metellus | | confused |
| 17:31 | hiredman | amalloy: https://github.com/hiredman/clojurebot/blob/master/src/hiredman/clojurebot/core.clj#L45 |
| 17:31 | sdegutis | he didn't type that string |
| 17:31 | sdegutis | where did clojurebot get that string!? |
| 17:31 | hyPiRion | brehaut: yeah, that's my stereotypical guess |
| 17:32 | sdegutis | "gfredericks: clojurebot: yo llama is amalloy" |
| 17:32 | sdegutis | "clojurebot: amalloy spells Yo Llama backwards" |
| 17:32 | sdegutis | where did "backwards" come from!? |
| 17:32 | amalloy | sdegutis: that was like ten minutes ago |
| 17:32 | justin_smith | he was fed both factoids |
| 17:32 | sdegutis | oh. |
| 17:32 | brehaut | hyPiRion: i imagine them sitting round laughing at the node programmers. cobol programmer never have to learn a new thing and their rates go up as a result! |
| 17:32 | sdegutis | phew |
| 17:32 | amalloy | clojurebot's knowledge about amalloy llamas is approaching critical mass |
| 17:33 | sdegutis | I'm glad it wasn't something more canister. |
| 17:34 | shriphani | justin_smith, have you given thought to my issue about more elaborate fn s? |
| 17:35 | justin_smith | shriphani: if they need to use some ns, they should be able to require it, and make sure it is in the classpath, right? |
| 17:35 | justin_smith | shriphani: or is that too much to expect? |
| 17:35 | shriphani | justin_smith, probably |
| 17:36 | shriphani | for instance, the pipeline component I am using combines some home-grown machine learning codebase and some other home-grown data mining utils |
| 17:36 | shriphani | so it can get quite elaborate. |
| 17:36 | justin_smith | OK - but all that will be available for a client to require at runtime |
| 17:36 | justin_smith | unless you decide not to ship it... |
| 17:36 | sdegutis | We may see a rainbow soon. |
| 17:37 | justin_smith | I feel like there is something I am not getting here |
| 17:37 | shriphani | justin_smith, that is quite possible isn't it ? |
| 17:37 | sdegutis | I am integrating Sass with the Clojure web app. |
| 17:37 | shriphani | um lets see if I can explain my situation better. |
| 17:37 | shriphani | So the java app that is running takes classes via a pipeline. |
| 17:37 | shriphani | Each new pipeline is typically a new thread spawned (not a new process). |
| 17:38 | shriphani | and I would like to specify pipeline components in clojure. |
| 17:39 | shriphani | and right now the idea is that the user of this API defines a few fn's in some other ns and wants to load these as components in a new pipeline (in an already-running process) |
| 17:39 | shriphani | and the functions can use any random lib. |
| 17:39 | justin_smith | I would say, expect them to use clojure in the standard way |
| 17:39 | shriphani | right. |
| 17:39 | justin_smith | and make a constructor for your class that takes a clojure function to shell out to as an argument |
| 17:39 | shriphani | right. |
| 17:40 | justin_smith | so they can conveniently create something to plug into spring to make a pipeline |
| 17:40 | sdegutis | wrap-reload seems to not work some of the time. |
| 17:40 | justin_smith | and just let them use clojure the normal way (with require, and a project.clj or something like alembic.still to manage deps in the classpath |
| 17:40 | justin_smith | ) |
| 17:40 | technomancy | sdegutis: yeah I have no idea what that is about. |
| 17:40 | technomancy | sdegutis: just run from a repl |
| 17:41 | sdegutis | technomancy: are you saying you have noticed this as well? |
| 17:41 | shriphani | the thing I am not clear about is how to pass my fn to the pipeline. https://github.com/technomancy/serializable-fn doesn't look like what I want for example |
| 17:41 | justin_smith | sdegutis: are you passing a var to ring as your handler? |
| 17:41 | technomancy | sdegutis: I haven't noticed any problems with it other than "why would anyone use this" |
| 17:41 | sdegutis | justin_smith: yes |
| 17:41 | sdegutis | justin_smith: hence my confusion |
| 17:42 | sdegutis | technomancy: how does running it from the repl hepl me? |
| 17:42 | justin_smith | shriphani: you make the fn a slot on the class (better yet, make a factory that takes the fn as an argument) |
| 17:42 | sdegutis | technomancy: changed routes/files will still need to be reloaded manually, right? |
| 17:42 | shriphani | umm is there an example of this ? |
| 17:43 | justin_smith | shriphani: I don't really know - you mentioned earlier that you needed to pass a generated class to spring, I could misunderstand how that needs to work |
| 17:43 | technomancy | sdegutis: C-c C-k and you're done |
| 17:44 | sdegutis | technomancy: that just cancels a magit commit or a dired edit |
| 17:44 | sdegutis | technomancy: is there some context I'm missing here??? |
| 17:44 | lazybot | sdegutis: How could that be wrong? |
| 17:44 | sdegutis | inorite |
| 17:44 | shriphani | justin_smith, that was probably the wrong way |
| 17:44 | justin_smith | sdegutis: I think that is a key combo to relaod an ns |
| 17:45 | sdegutis | With what emacs plugin? |
| 17:45 | shriphani | in this case, I am not sure how to make the class see the fn the user has written. |
| 17:45 | sdegutis | I miss Rails more and more. |
| 17:50 | stompyj | I missed rails, until I ported a service to clojure and went from 8 servers to 1, reduced my code by 20% and needed about 50% less test coverage |
| 17:51 | stompyj | There, I got my mandatory programmer snark out of the way today. |
| 17:51 | turbofail | yeah i'm totally over rails |
| 17:52 | schmee | I have a core.async question: how does c.a and blocking interact? |
| 17:52 | shriphani | justin_smith, essentially I want to pass my clojure function to an already running java process to use. |
| 17:52 | schmee | can I do something like this (go (while true (>! c (receive socket))))) |
| 17:52 | schmee | without exhausting a thread pool somewhere? |
| 17:55 | justin_smith | shriphani: OK - you can send it a string to eval, give it a file to load, give it a serialized function it can deflate, or give it a jar file to add to classpath and require via alembic.still |
| 17:56 | justin_smith | s/deflate/deserialize |
| 17:57 | amalloy | schmee: that only looks like one thread to me |
| 17:58 | shriphani | justin_smith, of all these the jar approach seems best. |
| 17:58 | amalloy | each (go ...) has a single thread of execution (actually less than that, because if you do something that looks blocking, your work is suspended and the thread is reused for something else that can make progress |
| 17:58 | justin_smith | shriphani: yeah, I think so too - alembic is really easy to use |
| 17:58 | shriphani | esp since there is quite a lot of diversity in the functions I expect |
| 17:59 | justin_smith | shriphani: at runtime you would specify the jar to load and the ns to require / the defn within that ns to use |
| 17:59 | shriphani | exactly |
| 17:59 | shriphani | those can be put in the config file |
| 17:59 | schmee | amalloy: so if I run, say, 1000 of those and all are blocking on the socket then they're just suspended, and not tieing up any threads? |
| 17:59 | shriphani | yeah this sounds right. |
| 17:59 | justin_smith | that way instead of some hacky mechanism, you have standard clojure best practices |
| 17:59 | shriphani | I'll let you know how this goes. |
| 17:59 | schmee | amalloy: on different sockets, that is |
| 18:00 | shriphani | is there a way to make an uberjar from clojure ? |
| 18:00 | amalloy | i mean, it depends on what your socket primitive is. if it's something actually-blocking that isn't part of the core.async ecosystem, you're probably using up one thread per go |
| 18:00 | shriphani | as opposed to shelling out and calling lein |
| 18:00 | justin_smith | shriphani: the one tricky thing would be if someone added some jar, and then later tried to add a jar providing the same namespaces - the first one would remain I think |
| 18:00 | amalloy | but if it's a channel of some kind, then yeah, they're just idling |
| 18:00 | shriphani | justin_smith, but that is a random edge case |
| 18:01 | shriphani | and I can sort-of restrict the ns to be (say) the pipeline name |
| 18:01 | mdeboard | amalloy: go channels just reside on lightweight green threads? |
| 18:02 | schmee | amalloy: I'm using ordinary java.io sockets |
| 18:02 | amalloy | mdeboard: i never really figured out what green threads are |
| 18:03 | mdeboard | amalloy: are you being cheeky or are you serious |
| 18:03 | shriphani | justin_smith, I am guessing there is a simple fn call somewhere in leiningen to make an uberjar from the current project ? |
| 18:03 | schmee | amalloy: I'm just trying to figure out if I should use go blocks or the regular blocking operations |
| 18:03 | justin_smith | amalloy: I think they are simulated threads - ie. your vm acts as a "scheduler" but this may all be within one process with no hardware mp |
| 18:03 | amalloy | mdeboard: for serious |
| 18:05 | mdeboard | the wikipedia article is pretty well rounded |
| 18:07 | amalloy | okay. well. core.async threads are not green threads, and channels are not threads of any kind, but i don't really want to get into a "core.async from the ground up" to get at a real answer your question |
| 18:08 | schmee | amalloy: I'll experiment some and see where this goes, thanks for your help! |
| 18:09 | jkj | i don't think you have to think about them as threads |
| 18:09 | clojurebot | Pardon? |
| 18:09 | mdeboard | HE SAID HE DOESN'T THINK YOU HAVE TO THINK ABOUT THEM AS THREADS |
| 18:10 | jkj | :D maybe i should've read the backlog |
| 18:11 | mdeboard | I was talking to Clojurebot |
| 18:11 | mdeboard | "Pardon?" |
| 18:51 | fifosine | ,(print test) |
| 18:51 | clojurebot | #<core$test clojure.core$test@bf123f> |
| 18:52 | fifosine | ,(loop [input (read-line)] (print input) (recur (read-line))) |
| 18:52 | fifosine | l |
| 18:52 | fifosine | t |
| 18:52 | clojurebot | eval service is offline |
| 18:52 | fifosine | when I enter the above in my repl, it doesn't print what I enter, why is that? |
| 18:53 | Bronsa | fifosine: because the output is buffered |
| 18:54 | aperiodic | fifosine: the buffer doesn't get flushed. by default it's flushed on newlines, so you want a println there most likely |
| 18:54 | Bronsa | fifosine: if you use println rather than print, it will work |
| 18:56 | fifosine | Bronsa: I've modified the above to https://www.refheap.com/89354 |
| 18:56 | fifosine | how do I enter the nil character to exit the loop? |
| 18:56 | fifosine | ctrl-c and ctrl-d don't work |
| 18:57 | Bronsa | fifosine: ctrl-d should work |
| 18:58 | fifosine | not in my local repl |
| 18:58 | fifosine | in yours? |
| 18:58 | Bronsa | fifosine: it works on my repl but I see it doesn't work with lein repl |
| 18:59 | fifosine | Why would that be? |
| 18:59 | Bronsa | no idea, I don't use lein repl, maybe technomancy knows |
| 19:02 | technomancy | works for me |
| 19:02 | amalloy | calling System/exit is like running around with a chainsaw. of course bad things are going to happen |
| 19:03 | fifosine | amalloy: I'm not sure how else to break out of the loop on ctrl-d |
| 19:03 | amalloy | just don't put a recur in. if the only way out of a loop were System/exit, we'd bein rough shape |
| 19:04 | amalloy | here the System/exit looks like it adds a race condition in there between flushing the buffer and killing the process |
| 19:04 | technomancy | oh, during a tight loop, I see |
| 19:04 | fifosine | amalloy: But the point is to continually read stdin until nil is read |
| 19:04 | fifosine | without the recur, it only happens once |
| 19:05 | technomancy | fifosine: reduce or doseq over a line-seq |
| 19:05 | technomancy | that will end the seq upon eof IIRC |
| 19:05 | amalloy | right. you put a recur in only if you want to recur. if you don't want to recur, you don't have to call System/exit, you just have to not call recur |
| 19:05 | amalloy | there are two branches to that if. one of them should recur, and the other not |
| 19:05 | Bronsa | amalloy: maybe he is writing a script and wants to exit the repl |
| 19:05 | technomancy | recur is super low-level; there's usually a better way to do things |
| 19:05 | fifosine | technomancy: Why is line-seq preferrable to read-line? |
| 19:06 | technomancy | fifosine: ^ |
| 19:07 | technomancy | working in terms of seqs is just a better abstraction |
| 19:07 | amalloy | fifosine: you want like (loop [...] (if keep-going (do (something) (recur)))) |
| 19:07 | amalloy | technomancy: yes, fine, but understanding loop is important too |
| 19:07 | technomancy | meh |
| 19:07 | amalloy | fifosine: your recur is currently unconditional, coming after the if. it should instead be "recur only if we weren't supposed to stop" |
| 19:08 | fifosine | (doseq [line (line-seq (java.io.BufferedReader. *in*))] |
| 19:08 | fifosine | (when line (println line))) |
| 19:08 | fifosine | ^ that should work, no? |
| 19:08 | fifosine | but still, ctrl-d doesn't exit |
| 19:13 | lazylambda | can anyone help me understand this?... |
| 19:13 | lazylambda | (def fib (lazy-seq (cons 0 (reductions + 1 fib)))) |
| 19:13 | lazylambda | This fibonacci seq works fine as intended, however it behaves strangely if I remove the lazy-seq call.. can anyone explain why? |
| 19:15 | fifosine | technomancy: This also doesn't exit on ctrl-d in lein repl |
| 19:15 | fifosine | https://www.refheap.com/89355 |
| 19:15 | amalloy | lazylambda: it's trickery. self-recursive data structures are not really a great idea in clojure |
| 19:16 | amalloy | the first version works because fib refers to itself through the var fib, and doesn't look that var up until you try to realize the first element; if you don't put a lazy-seq in there, the sequence tries to refer to itself before any part of it is defined |
| 19:16 | lazylambda | I know that now, the question is why.. I can't really figure out what's going on internally to understand why it's behaving like that..basically it returns a different output everytime i compile |
| 19:16 | amalloy | it's probably referring to old versions of fibs |
| 19:17 | lazylambda | that makes sense |
| 19:17 | bbloom_ | lazylambda: the semantics of (def foo init) are as follows: |
| 19:17 | amalloy | if you defined a whole new var, with a new name, using this style of definition, it wouldn't work at all |
| 19:17 | bbloom_ | foo is declared to be undefined, then init is evaluated in that environment, then that evaluation result is assigned to foo |
| 19:18 | TimMc | 1. Cut a hole in your namespace |
| 19:18 | TimMc | oh wait |
| 19:18 | bbloom_ | ,(def asdf asdf) |
| 19:18 | clojurebot | #'sandbox/asdf |
| 19:18 | bbloom_ | ,asdf |
| 19:18 | clojurebot | #<Unbound Unbound: #'sandbox/asdf> |
| 19:19 | bbloom_ | ,(class asdf) |
| 19:19 | amalloy | in fact if you do this with a brand-new var, you get (cons 0 (cons 1 (lazy-seq (throw an error)))) |
| 19:19 | clojurebot | clojure.lang.Var$Unbound |
| 19:19 | TimMc | bbloom_: Cute. |
| 19:20 | amalloy | also i don't understand why that's a correct definition of fib. apparently it is, but it's not one i recognize |
| 19:21 | bbloom_ | amalloy: i think it's the co-inductive definition |
| 19:21 | lazylambda | I learned it a while back when I was fiddling with haskell |
| 19:21 | amalloy | the one i'm familiar with from haskell (which works just as badly in clojure as the one you pasted) is: fibs = 0 : 1 : zipWith (+) fibs $ tail fibs |
| 19:22 | martinklepsch | what would be a good way to rate-limit the execution of the function with some sort of cached result for the time it's "rate-limited"? |
| 19:22 | xeqi | fifosine: work as in print all lines and never retrun? |
| 19:22 | fifosine | xeqi: I expect it to return on ctrl-d |
| 19:23 | fifosine | because I expect (read-line) to return nil on ctrl-d |
| 19:23 | technomancy | fifosine: my bad; I thought line-seq worked that way. it's a bit silly if not. |
| 19:23 | technomancy | I still maintain that using a seq is better than loop/recur though |
| 19:23 | bbloom_ | lazylambda: the reason that the lazy-seq version works is b/c all top level names are dynamically scoped, so the thunk introduced in lazy-seq does not get evaluated until you traverse the seq |
| 19:24 | fifosine | technomancy: You still might be right, this example uses (read-line), not line-seq |
| 19:24 | bbloom_ | lazylambda: which is very different at the user level, but very similar internally to how it works in haskell |
| 19:24 | fifosine | I'll test with line-seq |
| 19:24 | amalloy | martinklepsch: https://github.com/flatland/useful/blob/develop/src/flatland/useful/fn.clj#L142 is a simple version, but returns nil instead of caching |
| 19:26 | fifosine | technomancy: Yup, the following doesn't return on ctrl-d in lein repl https://www.refheap.com/89356 |
| 19:26 | fifosine | (as I would expect it to) |
| 19:26 | fifosine | any advice on writing a loop that continuously reads from stdin until an exit signal? |
| 19:26 | lazylambda | bbloom_: I see |
| 19:27 | technomancy | you might be stuck calling java methods directly; yuck. |
| 19:27 | lazylambda | bbloom_: I didn't clojure had dynamic scoping |
| 19:27 | technomancy | if it weren't for jira, I would tell you to open an issue re: line-seq, because the current behaviour seems dumb. |
| 19:27 | lazylambda | bbloom_: didn't know* |
| 19:27 | bbloom_ | lazylambda: top levels are dynamically scoped (with optional thread local scoping) and locals are lexically scoped |
| 19:27 | martinklepsch | amalloy: I have a function that lists files on disk, calling that a few hundred times becomes slow. I could def it but I'd like to be able to "refresh" it every now and then. My thinking was: if I could make that function only go to disk and lookup files once in five minutes I should be fine. — probably my thinking is flawed and there is a more clever way of doing this |
| 19:28 | amalloy | ah. there's a different function in useful that's just for that |
| 19:28 | amalloy | https://github.com/flatland/useful/blob/develop/src/flatland/useful/state.clj#L78 |
| 19:28 | lazylambda | bbloom_: I see. well thanks for the explanation, it's clear now |
| 19:31 | amalloy | so the idea there, martinklepsch, would be to (def cached-fs (periodic-recompute really-read-fs {:unit :min, :num 5})) |
| 19:31 | amalloy | and then call (cached-fs) instead of (really-read-fs) |
| 19:32 | bbloom_ | Bronsa: that dmiller guy is a porting machine |
| 19:35 | martinklepsch | amalloy: yup got it. the state thing seems a bit big though |
| 19:37 | amalloy | well if you want to get background threads mutating your app's state *right*, you have to do some work. but mostly there's not much going on, just a large number of short lines |
| 19:39 | martinklepsch | amalloy: also ideally I thought it'd be nice to be able to recompute it on demand, it's not really much of an issue to me but I wonder how that could be done |
| 19:42 | martinklepsch | amalloy: could probably be done in a similar way to the periodic-recompute function |
| 20:02 | turbofail | bah. can't do `contains?' on transients |
| 20:03 | Bronsa | turbofail: http://dev.clojure.org/jira/browse/CLJ-700 |
| 20:04 | holo | I have this exception - https://www.refheap.com/89357, which happens everytime I use my app from a uberjar. I'm clueless about the offending code :( any ideas? (it's not env variables fault. I printed them to check) |
| 20:10 | holo | I tried AOT compile and not at all with the same result |
| 20:11 | turbofail | on an unrelated note, java.lang.String.split is pretty durn slow |
| 20:12 | turbofail | probably because of the whole regex splitting thing |
| 20:13 | TEttinger | holo, are any of your namespaces mentioned in there? |
| 20:13 | holo | turbofail, is that a comment about someone else's code? (cause I can't see that in my trace) |
| 20:14 | TEttinger | before you got here, holo, he was working through a speed-related problem I think |
| 20:15 | imanc | In this definition (defn home [& [name message errr]] .. what does the & mean/do? |
| 20:15 | TEttinger | imanc, it allows variable number of args after that & |
| 20:16 | TEttinger | here, it binds name, message, and errr to the first 3 in those args |
| 20:16 | holo | Tettinger, yes, everything starting with 'app.'. Still, it pretty much crosses several namespaces, and NullPointerException is not really helpful |
| 20:16 | TEttinger | seems like an odd way of doing it, imanc |
| 20:16 | TEttinger | holo, indeed |
| 20:17 | holo | Tettinger, my hope would be someone here remembered a similar experience when running with uberjar |
| 20:18 | imanc | I'm reading Web development with Clojure and ti's shown as a view func.... so 3 args are passed to the home function which then get bound to those symbols locally? |
| 20:18 | akurilin | I'm really puzzled by the clojure.java.shell/sh function |
| 20:18 | akurilin | I'm trying to run pandoc with some params, so I'm doing (sh "pandoc" "-f markdown -o /tmp/sometfilename.pdf") and it's somehow stripping the dash from the -o |
| 20:19 | akurilin | confused about how exactly I'm to use it with multiple single-letter arguments |
| 20:19 | TEttinger | ,((fn home [& [name message errr]] (str name " " message " " errr)) "TEttinger" "called like this" "I think") |
| 20:19 | clojurebot | "TEttinger called like this I think" |
| 20:19 | TEttinger | ,((fn home [& [name message errr]] (str name " " message " " errr)) "TEttinger" "called like this" "I think" "extra args") |
| 20:19 | clojurebot | "TEttinger called like this I think" |
| 20:20 | TEttinger | ,((fn home [name message errr & _] (str name " " message " " errr)) "TEttinger" "more idiomatic" "I think" "extra args") |
| 20:20 | clojurebot | "TEttinger more idiomatic I think" |
| 20:20 | TEttinger | ,((fn home [& [name message errr]] (str name " " message " " errr)) "TEttinger" "called like this") ; this might be used to only sometimes pass errr |
| 20:20 | clojurebot | "TEttinger called like this " |
| 20:20 | TEttinger | yep |
| 20:21 | TEttinger | so that's the purpose of & there, it allows more or less args than those 3 |
| 20:22 | imanc | Awesome. Makes sense. |
| 20:22 | holo | akurilin, are you sure the arg after 'sh' isn't a []? |
| 20:23 | akurilin | holo: hm let me try |
| 20:23 | TEttinger | (sh "pandoc" "-f" "markdown" "-o" "/tmp/sometfilename.pdf") |
| 20:23 | TEttinger | maybe that, akurilin? |
| 20:25 | holo | sure Tettinger is right. all cl arguments should be separated strings akurilin |
| 20:25 | akurilin | let me try, sec |
| 20:26 | TEttinger | the args it lists here http://clojuredocs.org/clojure_core/clojure.java.shell/sh are not that helpful, but that's the conclusion i came to reading it, holo |
| 20:27 | akurilin | the magic starts here: https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/shell.clj#L112 |
| 20:27 | akurilin | but yeah that worked, thank you very much |
| 20:27 | TEttinger | woo |
| 20:32 | imanc | Just doing some testing in the repl - when I do (fn home [x]... ) it doesn't seem to bind 'home' as it would with (defn home... does home symbol in the context of the anon function mean something different? |
| 20:33 | TEttinger | imanc, defn home will define it as a symbol you can call later |
| 20:33 | TEttinger | fn home is exactly the same as just fn here |
| 20:33 | hiredman | TEttinger: it will not |
| 20:33 | TEttinger | hiredman, err var? |
| 20:33 | hiredman | TEttinger: def sticks it in a var named by a symbol |
| 20:34 | hiredman | the name home is bound lexically in the body of the function there, similar to a let binding |
| 20:34 | TEttinger | well you get the idea, fn will return the fn, defn will define it for later |
| 20:34 | imanc | TEttinger: so why does (fn allow you to specify a function name when it isnt' used? |
| 20:34 | hiredman | you may want (let [home (fn [x] ...)] ...) |
| 20:34 | TEttinger | imanc, it can be used for recursion or clarity |
| 20:35 | imanc | OK, makes sense |
| 20:35 | TEttinger | fn with no name given can't call itself recursively |
| 20:43 | holo | ,((fn [] (recur))) |
| 20:43 | clojurebot | eval service is offline |
| 20:48 | fifosine | technomancy: Can you see why this doesn't echo like I'd expect? https://www.refheap.com/89358 |
| 21:04 | akurilin | random question: I want to read a pdf into memory and serve it to the caller through Ring. I would use file-response but then I don't really get to delete the file after I'm done serving it. Slurp won't work since it's a pdf and contains non-ascii characters |
| 21:05 | akurilin | Are there any libraries out there that might let me read that file into memory perhaps and return it as a byte blob in Ring? |
| 21:07 | celwell | Hi, I have a seq of maps, and a lazy seq of maps. I need to combine each corresponding map and end up with a single seq of maps. I was thinking something along the line of: apply merge ... but I got all confused. Any ideas? |
| 21:08 | hiredman | you get to write a join |
| 21:09 | Fare | is there already a primitive a bit like merge-with, but that always call the merge function? |
| 21:12 | hiredman | https://gist.github.com/hiredman/db6a94b0bdfdd2e95277 is my favorite |
| 21:15 | celwell | hiredman: impressive, but there's gotta be a simpler way to do what I want, right? |
| 21:16 | akurilin | actually ztellman's byte-streams seems to be a good fit for this, exploring |
| 21:16 | hiredman | you can get a, what do you call it, cartesian product via for |
| 21:17 | hiredman | ,(for [a (range 3) b (range 3) :where (= a b)] {:a a :b b}) |
| 21:17 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Invalid 'for' keyword :where> |
| 21:17 | hiredman | ,(for [a (range 3) b (range 3) :when (= a b)] {:a a :b b}) |
| 21:17 | clojurebot | ({:a 0, :b 0} {:a 1, :b 1} {:a 2, :b 2}) |
| 21:18 | hiredman | ,(for [a (range 3) b (range 3) :when (= a (inc b))] {:a a :b b}) |
| 21:18 | clojurebot | ({:a 1, :b 0} {:a 2, :b 1}) |
| 21:18 | ztellman | akurilin: you want to delete the file after it's served once? |
| 21:18 | ztellman | in a decent webserver, file-response will use zero-copy mechanisms, which will be more efficient |
| 21:19 | ztellman | byte-streams will let you transform a file into anything you like, though, if that's what you want |
| 21:21 | akurilin | ztellman: yeah, the web service generates a one-time pdf that doesn't need to be used again. it uses pandoc internally, which dumps the file to /tmp (pandoc doens't support stdout for PDF generation) |
| 21:22 | akurilin | ztellman: basically I want to read it into memory as byte array, nuke it from /tmp and then serve it |
| 21:22 | ztellman | that'll work, then |
| 21:22 | akurilin | ztellman: byte-streams doesn't actually do the reading for you, does it? Only the conversion. |
| 21:23 | ztellman | what's the difference? |
| 21:23 | ztellman | (bs/to-byte-array (File. x)) works like you'd expect |
| 21:23 | lazylambda | celwell if I understand correctly, is this what you want? https://www.refheap.com/89359 |
| 21:23 | akurilin | oh I was giving it a string, expecting it to treat it like a URI, let me try the file way |
| 21:24 | ztellman | no, it treats a string as a string, not a path |
| 21:24 | ztellman | that's something that really bugs me about clojure.java.io |
| 21:24 | ztellman | sometimes a string is a string, sometimes it's not |
| 21:24 | akurilin | exactly, I was workign with that assumption, but reading your source clarified it |
| 21:25 | hiredman | oh, pfft, if the maps are already sorted |
| 21:26 | akurilin | ok that works, thanks ztellman, very very handy library there sir |
| 21:26 | ztellman | np, glad it's helpful |
| 21:26 | lazylambda | celwell: if I understand correctly, is this what you want? https://www.refheap.com/89359 |
| 21:26 | TEttinger | (inc ztellman) |
| 21:26 | lazybot | ⇒ 11 |
| 21:27 | akurilin | ztellman is friggin batman, disappears into the night as soon as his mission is accomplished |
| 21:58 | akurilin | yogthos: hey, did you guys ever support index-based vector access in Selmer? |
| 21:58 | akurilin | e.g. if I want to do {{foos[0]}} |
| 22:28 | seancorfield | akurilin: you can write {{foos.0}} |
| 22:28 | seancorfield | for example (p/render "{{foo.1}}" {:foo [:a :b :c]}) ;;=> ":b" |
| 23:21 | ToxicFrog | How in the hell do I do an exponent? |
| 23:22 | justin_smith | ToxicFrog: Math/pow |
| 23:22 | ToxicFrog | I've tried **, ^, pow, exp, and expt, and found some docs online to use clojure.contrib.math/expt which doesn't seem to exist anymore. |
| 23:22 | ToxicFrog | Aah. |
| 23:22 | lpvb | the java function |
| 23:22 | arrdem | yeah. clojure/core packages exactly zero math functionality. Math/* is all you have out of the box :/ |
| 23:22 | justin_smith | I think that pow may be in numeric-tower, not sure though |
| 23:22 | arrdem | justin_smith: it is |
| 23:22 | justin_smith | arrdem: unless you count set ops |
| 23:23 | ToxicFrog | justin_smith: "unable to find static field pow in java.lang.Math" |
| 23:23 | justin_smith | only the really heady kind of math for us, thanks |
| 23:23 | arrdem | ToxicFrog: lolwut |
| 23:23 | lpvb | ToxicFrog: invoke it as a function |
| 23:23 | arrdem | $google java.lang.Math |
| 23:23 | justin_smith | ,(Math/pow 2.0 2.0) |
| 23:23 | lazybot | [Math (Java Platform SE 7 ) - Oracle Documentation] http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html |
| 23:23 | clojurebot | 4.0 |
| 23:24 | ToxicFrog | ...invoking it as a function works, but I can't bind it to a more convenient name with either let or def. |
| 23:24 | ToxicFrog | Wtf. |
| 23:24 | justin_smith | welcome to interop |
| 23:24 | arrdem | it's a host interop special form... |
| 23:24 | justin_smith | ,(do (def pow #(math/pow % %2)) (pow 3 3)) |
| 23:24 | clojurebot | #<CompilerException java.lang.RuntimeException: No such namespace: math, compiling:(NO_SOURCE_PATH:0:0)> |
| 23:24 | justin_smith | ,(do (def pow #(Math/pow % %2)) (pow 3 3)) |
| 23:24 | clojurebot | 27.0 |
| 23:26 | justin_smith | ,(do (defn ka-pow [m n] (reduce *' (repeat n m))) (ka-pow 200 200)) |
| 23:26 | clojurebot | 1606938044258990275541962092341162602522202993782792835301376000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000... |
| 23:27 | arrdem | (inc *print-limit*) |
| 23:27 | lazybot | ⇒ 1 |
| 23:28 | justin_smith | the above does not work for fractional exponents of course |
| 23:28 | Jabberz | anyone ever see "lein show-profiles" not include user? On Ubuntu, it looks like lein doesn't read ~/.lein/profiles.clj |
| 23:28 | Jabberz | or if it does, it doesn't recognize :user |
| 23:32 | TEttinger | justin_smith, numeric-tower calls it expt |
| 23:32 | TEttinger | instead of Math/pow |
| 23:32 | justin_smith | OK |
| 23:32 | justin_smith | cool |
| 23:33 | TEttinger | I import it by default in my lazybot |
| 23:34 | TEttinger | ,(reductions *' (range 10 50)) |
| 23:34 | clojurebot | (10 110 1320 17160 240240 ...) |
| 23:34 | TEttinger | ##(reductions *' (range 10 50)) |
| 23:34 | lazybot | ⇒ (10 110 1320 17160 240240 3603600 57657600 980179200 17643225600 335221286400 6704425728000 140792940288000 3097444686336000 71241227785728000 1709789466857472000 42744736671436800000N 1111363153457356800000N 30006805143348633600000N 840190544013761740800000N 2436552... https://www.refheap.com/89362 |
| 23:34 | TEttinger | ##(reduce *' (reductions *' (range 10 50))) |
| 23:35 | lazybot | ⇒ 314256214665654935069669414608723076387294240253819104596268903680392926625597373991392280747021265151099105417866042642723067221250640681422440746183425462658741187054893837240598439629346556980030906792723655184260873825005119722647334252032322938433828446722536552... https://www.refheap.com/89363 |
| 23:57 | akurilin | seanaway: ooh that's really cool, thank you! |
| 23:57 | akurilin | ooops not sure if that's the same person :P |