2015-09-20
| 00:09 | TEttinger | domokato_: still around? |
| 00:10 | rritoch | What is a "dev-resources" folder for? I've never really noticed it before but when I setup a new clojure project in eclipse it added a dev-resources to the java build path but didn't actually create the folder. |
| 00:11 | rritoch | I also don't recall seeing dev-resources in any project, or ever needing anything comparable. |
| 00:11 | rhg135 | resources you don't want to ship |
| 00:14 | rritoch | rhg135: Cool thanks. So it's more useful for proprietary projects, like a licence key for developers to bypass restrictions, or for parts of the system that aren't yet ready for release. |
| 00:23 | rritoch | rhg135: Is there a comparable folder for source code? Such as a main entry point that isn't needed in a distributable library but is provided for testing other than unit tests? |
| 00:38 | amalloy | rritoch: you can roll your own by adding to :source-paths in your :dev profile |
| 00:39 | amalloy | nothing built in that i know of. i think mostly nobody minds including their -main in a library jar |
| 00:41 | rritoch | amalloy: Thanks. I'm not entirely sure I'll ever need that, I haven't needed it so far, but at least I can add it to my stockpile of coding trivia :) |
| 01:15 | rritoch | Is there a "best practice"/naming convention for a "with" function that returns a promise instead of a value? Such as (with-gui-thread #(do (print "GUI OK") true) . Using with for this seems deceptive since the return value won't yet be fully defined when it returns. |
| 01:17 | justin_smith | when you say promise, do you mean function? |
| 01:17 | justin_smith | because we have promises, and that isn't one |
| 01:19 | rritoch | justin_smith: I'm writing a function, that with the aid of a macro and some other magic is going to perform a given function and arguments and return a promise. That promise will be fulfilled when the function is executed in that other thread. |
| 01:19 | justin_smith | OK, your code example didn't have any promise in it, so I wasn't sure |
| 01:20 | rritoch | sorry, t was just simpled that that function was in some way defined to return a promise instead of a value. |
| 01:20 | rritoch | err |
| 01:20 | rritoch | It was just implied |
| 01:21 | jeremylite | rritoch: "with" usually implies some additional context. in this case, it's your gui thread. so i think that's fine |
| 01:21 | jeremylite | to return a promise |
| 01:22 | justin_smith | I still have no idea where the implied promise was supposed to be in that example. Does with-gui-thread return it? does the anonymous function return it? |
| 01:22 | justin_smith | I mean the one that never gets called |
| 01:23 | rritoch | justin_smith: Yes, with-gui-thread will create and return a promise |
| 01:24 | jeremylite | rritoch: on second though, maybe "on-gui-thread" or "invoke-gui" or something like that |
| 01:24 | rritoch | I was just thinking that with seems deceptive, like maybe it should be future-with or some other name. |
| 01:25 | justin_smith | to my eye, a with-* is a macro that takes your code and puts it in some other context, so it would take a &body instead of a lambda |
| 01:25 | jeremylite | yeah |
| 01:25 | justin_smith | also, how is this different from future - just the fact that it runs something on a specific existing thread? |
| 01:25 | rritoch | jeremylite: Hmm, I think invoke is a good idea, like "invoke-with" |
| 01:26 | rritoch | justin_smith: Yes, that's the only difference. It is going to run on a specific thread. |
| 01:27 | justin_smith | I'd make that function, and call it call-in-gui, then make a macro that expands to putting the body in an anonymous function supplied to call-in-gui and call that with-gui-thread |
| 01:28 | justin_smith | and yeah, return a promise that the caller can access later |
| 01:35 | rritoch | justin_smith: If I use a macro instead of a function won't that eliminate the possiblity of being able to map over it? Such as (map #'invoke-with-gui-thread job-list) |
| 01:36 | justin_smith | rritoch: I said invoke a function, the macro is just a convenience |
| 01:36 | justin_smith | and it becomes inconvenient if you want to map (but don't do that, because map is not for side effects) |
| 01:37 | justin_smith | rritoch: I only suggested the macro because you suggested with-foo and that's how a with-foo would work, turn a body of code into a function and then put it into the right context for evaluation |
| 01:38 | rritoch | justin_smith: Well, I'm still debating function -vs- macro for this, the function is using a macro internally. I really don't know a way to do this without macros. |
| 01:39 | justin_smith | def is a macro, let is a macro, everything uses macros internally |
| 01:39 | jeremylite | rritoch: he's talking a function like (defn call-on-gui [f] (call-on-thread *thread* f)) and a macro like (defmacro [&body] `(call-on-gui (fn [] ~@body))) |
| 01:40 | jeremylite | the functino is more useful, but the macro adds sugar |
| 01:41 | justin_smith | functino, heh, I do that typo all the time |
| 01:42 | jeremylite | lol |
| 01:42 | justin_smith | we should totally make something called functino for making small inline functions or something |
| 01:42 | jeremylite | justin_smith: i keep typing "litearl" instead of a "literal" and i think of james earl jones being high |
| 01:42 | justin_smith | haha |
| 01:43 | jeremylite | you know, functino, the core.logic operator for functin, duh |
| 01:44 | justin_smith | "duude - hear me out now, what if the death star is just a symbol of our hubris, man, like we have an intergalactic empire but want to be gods, create worlds, destroy them" *puffs* |
| 01:45 | emdashcomma | well |
| 01:45 | emdashcomma | you're not wrong |
| 01:45 | jeremylite | lol |
| 01:46 | justin_smith | I can totally picture Vader getting stoned. Of course he would vape though. |
| 01:48 | justin_smith | alternately, Thulsa Doom, he would roll blunts |
| 01:48 | emdashcomma | he'd try to force choke the wall, and giggle unconrtollably |
| 01:48 | justin_smith | haha |
| 01:51 | justin_smith | emdashcomma: force lightning to spark the bowl, followed by a force-choke on his piece instead of using a carb |
| 02:11 | rritoch | What about x-quiet vs x-stfu , I really prefer the stfu but god-forbid clients ever look at the code. |
| 02:11 | domgetter | Is there a way to make a set of maps where the uniqueness of the members is determined by one of the values of a key each of them has? |
| 02:12 | justin_smith | domgetter: sorted-set-by will only keep 1 of each return value for its sorting function |
| 02:13 | domgetter | awesome Ill look at the docs for that, thank you |
| 02:13 | justin_smith | domgetter: so if what you want is to keep only one map for a given value of :key, then (sorted-set-by :key ...) would do what you want (as a side effect of the sorting that I am sure you don't need) |
| 02:13 | rritoch | my last question was rhetorical, for entertainment purposes only. |
| 02:13 | justin_smith | ,(sorted-set-by :k {:k 1} {:k 2 :v 1} {:k 2 :v 2}) |
| 02:13 | clojurebot | #error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Comparator"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Comparator"\n :at [clojure.core$sorted_set_by invokeStatic "core.clj" 412]}]\n :trace\n [[clojure.core$sorted_set_by invokeStatic "core.clj" 412]\n [clojure.core$sorted_set_by doInvoke "core.clj" -1]\n [cloj... |
| 02:14 | domgetter | justin_smith: well I do want them sorted by their :create_at date, but I want them to be unique by their :id |
| 02:14 | justin_smith | err... |
| 02:15 | justin_smith | ,(sorted-set-by #(apply compare (map :k %&)) {:k 1} {:k 2 :v 1} {:k 2 :v 2}) |
| 02:15 | clojurebot | #{{:k 1} {:k 2, :v 1}} |
| 02:16 | domgetter | And that will enforce uniqueness and sortedness on the same key, correct? |
| 02:17 | justin_smith | yes |
| 02:17 | domgetter | okay cool, thank you |
| 02:17 | justin_smith | that is how sorted-set-by works - it always enforced uniqueness by the sorting key |
| 02:44 | rritoch | I ended up using a macro for my invoke-with ... it was the cleanest solution. |
| 03:08 | rritoch | Short of assigning all defrecord fields as atoms, is there a way to establish two-way bindings between a defrecord and a user interface? I need events triggered each time a field changes so the system can update the GUI. |
| 03:11 | amalloy | since a record (which is just a fancy map) is immutable, you can't really have a specific instance of defrecord be synched with something that can change. you could, of course, have an atom that points to different records over time |
| 03:11 | justin_smith | sounds like react |
| 03:11 | justin_smith | the api for reagent is pretty close to that |
| 03:22 | domgetter | Is there a reason why this is happening? https://gist.github.com/anonymous/e8e658619f9b92f2bfca |
| 03:22 | domgetter | I thought swap! ran apply, so I wouldn't get a nested vector |
| 03:22 | rritoch | Thanks,. For this case it sounds like I need two record types, one for values which don't change often so it can reasonably be maintained in a "watched" atom, and another which contains values which change often and need individual fields watched. |
| 03:22 | justin_smith | domgetter: no, swap! does not run apply |
| 03:22 | justin_smith | domgetter: just use into, or provide the 3 and 4 as separate args |
| 03:23 | justin_smith | ,(def a (atom [1 2])) |
| 03:23 | domgetter | How do I supply them as separate args |
| 03:23 | clojurebot | #'sandbox/a |
| 03:23 | justin_smith | ,(swap! a conj 3 4) |
| 03:23 | clojurebot | [1 2 3 4] |
| 03:23 | domgetter | that is, if I can't do it literally |
| 03:23 | justin_smith | ,(swap! a into [5 6]) |
| 03:23 | clojurebot | [1 2 3 4 5 ...] |
| 03:23 | justin_smith | domgetter: literally works, as above |
| 03:23 | domgetter | ah I see |
| 03:23 | domgetter | ok thank you |
| 03:24 | justin_smith | or you can use into if you need to provide them as a coll |
| 03:24 | justin_smith | domgetter: it mentions apply ... args but note that it's arg list has & args |
| 03:25 | justin_smith | so args will be a coll, containing all your args, I hope that makes it more clear |
| 03:25 | justin_smith | (doc atom) |
| 03:25 | clojurebot | "([x] [x & options]); Creates and returns an Atom with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn If metadata-map is supplied, it will become the metadata on the atom. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validate-fn should return false or thro |
| 03:25 | justin_smith | (doc swap!) |
| 03:25 | clojurebot | "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in." |
| 03:25 | domgetter | ah okay, that makes sense |
| 03:25 | justin_smith | oh, that's a bad doc string :P |
| 03:26 | domgetter | so I'm not crazy :P |
| 03:26 | justin_smith | if you are going to refer to "args", then bind args in the doc string, hah |
| 03:26 | justin_smith | I mean in the args list |
| 03:26 | justin_smith | but you get what I mean |
| 03:26 | domgetter | I think into works for what I want |
| 03:29 | justin_smith | the funny thing is when you combine swap! with update* |
| 03:29 | justin_smith | ,(swap! a update 2 * 42) |
| 03:29 | clojurebot | [1 2 126 4 5 ...] |
| 03:29 | justin_smith | like forth in reverse |
| 03:53 | sotojuan | justin_smith: do you ever sleep? Every time I log on you are here ;D |
| 04:19 | roelof | Hello, Im looking at living clojure for learning clojure. Can I start with the exercises and read the chapters that are involved or can I better read everything first and do the exercises after it |
| 04:21 | domgetter | roelof: Probably better to read a chapter and then try the exercises. |
| 04:22 | roelof | domgetter: that is what I mean. but the book has two parts. First the explanations and after that a training part. |
| 04:38 | amalloy | justin_smith: in my 1.6 repl that docstring reads "args", not "..." |
| 04:39 | roelof | domgetter maybe first read everything and look at the examples and then do the training weeks |
| 04:50 | javahippie | roleof: why not 'code along' on your own while reading the theory? This way you could get a better grasp of it and afterwards do the trainings |
| 04:53 | domgetter | roelof: My only advice is to not spend too much time thinking about the best way to do it. Just choose a strategy and do a little each day. |
| 04:54 | roelof | javahippie: I could do that but then I have to have a idea what to programm |
| 04:54 | roelof | domgetter: oke, thanks for the tip |
| 04:56 | domgetter | Once you learn that you can do things, you'll dream up projects, I guarantee it |
| 04:56 | domgetter | And the more tools in your toolbelt, the more imaginative and confident you'll be |
| 04:56 | domgetter | And Clojure offers some pretty powerful tools :) |
| 04:56 | roelof | domgetter: I think I know a project for in the future. or a ecommerce site or a accounting site |
| 05:12 | javahippie | roleof: I meant, coding along the examples in the relp. Maybe, read a chapter about sequences, fool around with them in the repl |
| 05:12 | roelof | javahippie: thanks for the tip |
| 05:14 | roelof | I have a quick read of chapter 1 of the Living book and I think I can do something with it |
| 05:19 | roelof | First install clojure on my ubuntu box :) |
| 05:27 | roelof | Can I just do apt-get clojure or can I better make a project and use the newest version as a dependency |
| 05:28 | javahippie | roleof: does your book mention leiningen? |
| 05:29 | roelof | yes, it does |
| 05:29 | roelof | it says first make a project |
| 05:30 | javahippie | that sounds good. See following link: http://clojure.org/downloads section 'Get Clojure via Leiningen'. |
| 05:31 | roelof | aha, and I see if I do lein repl clojure 1.7.0 is installed :) |
| 05:31 | javahippie | Yep, it is part of the initialization routine (if you want to call it that way) |
| 05:45 | roelof | Thanks all, Im now working trought chapter 1 of living clojure |
| 05:47 | javahippie | roleof: have fun! maybe give a little feedback from time to time about how you like the book ;) |
| 05:56 | domgetter | If I'm in the lein repl, how do I load core.async so I can play with channels? |
| 05:57 | domgetter | Or do I have to explicitly set it as a dependency in a project.clj file? |
| 05:59 | javahippie | As far as i know, dynamically adding dependencies is quite difficult, without additional tools. I remember it being a classloading issue |
| 05:59 | javahippie | I prefer to work with the project.clj |
| 05:59 | domgetter | ah okay fair enough |
| 06:00 | javahippie | never tried it, but maybe this is what you are looking for: https://github.com/pallet/alembic |
| 06:13 | roelof | javahippie: did you write it ? |
| 06:17 | javahippie | Oh, no. Far from it :D I am just interested in the quality of different books. I find it incredibly difficult to keep track about it |
| 06:23 | Raynes | Well AWS sure just ain't doing well right this moment. |
| 06:23 | Raynes | DynamoDB is ded and apparently everything depends on it according to newrelic telling me all my shits dying :D |
| 06:24 | Raynes | How's everyone else's Sunday morning? |
| 06:28 | roelof | javahippie: I did read the first chapter and did the examples and I like it. Everything is explained very well on a way a beginner understand it |
| 06:31 | mungojelly | what does ^{} mean |
| 06:36 | mungojelly | ok so my problem involves numerous things that are just slight variations on one another, which persistent data structures are awesome for, except i'd also like to persist them as in write them to disk sometimes, how can i remember things and maintain that space sharing, except of course to use datomic |
| 06:41 | hellofunk | mungojelly: ^{} is for adding meta data, not something you will need most of the time |
| 06:41 | hellofunk | Raynes: pretty good, yours? still in l.a.? |
| 06:41 | Raynes | Well pretty terrible since all my shit's dead and all but hey I could be dead. |
| 06:42 | Raynes | Still in LA, yessir. |
| 06:42 | lodin___ | mungojelly: IIRC transit does that, i.e. it can refer to a previously serialized entry in the structure. |
| 06:42 | hellofunk | your shit is dead? isn't shit supposed to be dead? that is why it is flushed.. ? |
| 06:42 | mungojelly | hellofunk: i'm not trying to do it but i'm reading the code for JDBC and it's used a lot there so i wanted to understand what i'm reading :) |
| 06:42 | Raynes | You're looking for lodin- sir. |
| 06:42 | Raynes | Not hellofunk. |
| 06:42 | hellofunk | mungojelly: for understanding basic logic, you don't really need to pay attention to metadata most of the time |
| 06:43 | Raynes | Oh wait, nevermind |
| 06:43 | Raynes | I can't read. |
| 06:43 | Raynes | I should go to bed. |
| 06:43 | hellofunk | Raynes: how are those fires out there, did you start them? |
| 06:43 | Raynes | Or play Heroes of the Storm. |
| 06:43 | Raynes | I mean unless I somehow stepped on a butterfly and caused a hurricane in us-east-1, doubt it was my fault. |
| 06:43 | mungojelly | lodin-: this transit-clj thing from cognitect? ok i'll learn about that thanks :) |
| 06:45 | mungojelly | in general it seems sad to me how bad our programs are at communicating so far, i bet sometime soon all the programs will start talking, the silence will end, but we'll think about it just in terms of some particular data exchange format, like how we understood the hypertext transformation to be about "HTML" |
| 06:46 | lodin- | mungojelly: Right. I'm not 100 % sure, so please let me know if I remembered correctly. :-) |
| 06:55 | mungojelly | lodin-: transit seems to know how to serialize basic values, compound values and can be extended by teaching it new types, but i don't see anything about preserving structure sharing or references. looks useful in general, certainly better than speaking directly to JSON! :) |
| 06:57 | ianhedoesit | am I stupid or is there a problem with the invite site for the clojurians slack channel? |
| 06:57 | ianhedoesit | clojurians.net gives an error when I try to get an invite. it's saying the token provided has insufficient privileges, basically. |
| 07:06 | mungojelly | lodin-: oh ok well i'm not sure i quite understand yet how to do it but this http://swannodette.github.io/2015/02/19/transit-js-caching/ says you can get it to cache references by writing custom handlers that say to do the caching hm |
| 07:24 | lodin- | mungojelly: I have not used transit myself, so I thought that the caching was not only for map keys. |
| 07:39 | mungojelly | lodin-: it's for nothing and anything, it'll handle things based on a custom handler, so if your write handler says put my symbol by which i mean backreference, and your read handler reads and reinflates the back references, voila |
| 07:41 | mungojelly | i don't need to drag the data back out often so i'm trying the strategy of just compressing it, i find that's wiser often than trying to be clever :) |
| 08:05 | visof | hi guys |
| 08:05 | visof | what is the performance of take and concat? |
| 08:06 | roelof | hello, how can I take care that a character is printed out instead of #<Atom@1322f9d: here is my code so far : http://lpaste.net/141361 |
| 08:07 | domgetter | roelof: You need to "dereference" the atom. Every time you want what's inside an atom, put a @ in front of its name |
| 08:07 | roelof | oke, I will try that |
| 08:08 | mungojelly | ,(let [a (atom "contents")] (println @a)) |
| 08:08 | domgetter | so on line 28, it should be (println @directionX))))) |
| 08:08 | clojurebot | contents\n |
| 08:09 | mungojelly | that's the first time i ever said @ yay it worked |
| 08:09 | roelof | domgetter: then there is more wrong. I do not get a output at all |
| 08:09 | domgetter | also, on lines 22 and 25, you need @thorX |
| 08:10 | domgetter | since it's an atom, and youre trying to compare its value |
| 08:10 | roelof | oke, changed it |
| 08:10 | roelof | I try to do a challenge of codeingame with clojure |
| 08:11 | domgetter | May I ask what (= thorX > lightX) means? |
| 08:11 | domgetter | are you trying to check if @thorX is equal to lightX? Or are you trying to check if it's larger than lightX? Or something else? |
| 08:12 | roelof | of course it means if the current postion (ThorX) is smaller then the end-position(LightX) then the direction must be W |
| 08:13 | domgetter | I think you might want (< @thorX lightX) |
| 08:13 | roelof | you are right |
| 08:13 | domgetter | that says "@thorX is less than lightX" |
| 08:16 | roelof | oke, now this part (if (< @thorX lightX) (swap! directionX "E")) gives this error message : xception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn |
| 08:17 | domgetter | roelof: You want to use reset! instead of swap! to set an atom to something in particular |
| 08:17 | domgetter | you'd use swap! if you want to use a function on the atom, but here, you just want to set it to the string "E" directly |
| 08:17 | roelof | oke, I wil try that |
| 08:18 | domgetter | change (swap! directionX "E") to (reset! directionX "E") |
| 08:18 | mungojelly | the second argument to swap! is a function that gets applied to the thing to change its value, like (swap! thing inc) is like thing++ |
| 08:20 | roelof | yes, first part is working :) |
| 08:21 | roelof | is this good clojure : http://lpaste.net/141362 |
| 08:22 | domgetter | looks alright. The important thing is, do you understand it? |
| 08:47 | crocket | uncle bob said clojure deserved to be the last programming language or the seed of the last programming language in 2011. |
| 08:49 | crocket | The last programming language to rule it all. |
| 08:50 | crocket | If only clojure could handle the metal directly. |
| 08:51 | roelof | yes, I wrote every piece of it |
| 08:52 | roelof | then now the y part and chancing the ThorX and ThorY. I can use the swap for the last one |
| 08:54 | roelof | but is every time using a def for a variable in a loop is good ? Can I not better do the def before the loop and do also a reset! to make them empty ? |
| 08:55 | mungojelly | there is no metal, modern cpus just pretend to be the old cpu architecture so that's a virtual machine now too |
| 08:58 | mungojelly | they split the asm "instructions" into parts, they smashed even those, and then the actual metal rearranges how those smashed partial instructions are pipelined for efficiency, so it jit compiles everything down into a language that very few humans can begin to understand and that literally no one speaks |
| 09:08 | xikuuky | Hey guys. |
| 09:09 | xikuuky | I came from a Hylang/Python background, I use functional coding and what not. Will Clojure be a good language? |
| 09:09 | mungojelly | xikuuky: i just started a few weeks ago but in my opinion clojure is a ridiculously good language. so good. |
| 09:10 | mungojelly | what's a hylang, never heard of it, sounds like it would be the programming language of hyrule |
| 09:10 | xikuuky | mungojelly: Is it static? |
| 09:10 | xikuuky | mungojelly: A Pythonic Lisp |
| 09:10 | mungojelly | is what static? are what static? |
| 09:11 | xikuuky | mungojelly: Static is where every type is set in stone while dynamic is where every type is defined on a need to know basis. |
| 09:11 | mungojelly | it allows mutable state but strongly encourages a style focused on immutability, by providing and supporting awesome practical immutable structure |
| 09:11 | mungojelly | oh in its typing. it's very dynamic. |
| 09:12 | crocket | Is it possible to have dependent types in clojure? |
| 09:12 | crocket | Would it be wieldable? |
| 09:12 | mungojelly | there's a typed variant called typed clojure that i've just started to find out about, but around here it's mostly untyped. |
| 09:12 | xikuuky | mungojelly: Yay! |
| 09:13 | xikuuky | I really don't like static languages. I worked with C#, F#, VB, the whole deal and I didn't think it was so great all the time/ |
| 09:17 | mungojelly | in fact the style around here is very terse, there's this clever thing where hashmaps can be used as functions, from key->value, and also hashmap keys can be used as functions, from map->value, which sounds odd for a moment but then reads just splendidly |
| 09:17 | mungojelly | ,({:a 1 :b 2} :a) |
| 09:17 | clojurebot | 1 |
| 09:17 | mungojelly | ,(:a {:a 1 :b 2}) |
| 09:18 | clojurebot | 1 |
| 09:19 | mungojelly | so that's used eeeeeeeeeverywhere to just say, i want the :this from the {that}, i've got a map called stuff, i want the thingy from the stuff, so either (:thingy stuff) or (stuff :thingy) gives me what i want |
| 09:22 | crocket | Can clojure go close to the metal? |
| 09:22 | mungojelly | ,(let [thingy {:a 2 :b 5}] (* (thingy :a) (thingy :b))) |
| 09:22 | clojurebot | 10 |
| 09:22 | mungojelly | crocket: there is no metal |
| 09:23 | crocket | You don't know what I mean by metal. |
| 09:23 | budai | is it possible to check if a record implements a specific protocol? |
| 09:24 | gfredericks | ,(doc satisfies?) |
| 09:24 | clojurebot | "([protocol x]); Returns true if x satisfies the protocol" |
| 09:24 | budai | gfredericks: thanks :) |
| 09:25 | mungojelly | crocket: the ground reality for clojure is the jvm, or for clojurescript javascript, it doesn't help you dig below there. because you really really shouldn't for almost every purpose. |
| 09:26 | crocket | 'almost'. |
| 09:26 | crocket | For writing kernel, you should. |
| 09:26 | crocket | For writing system libraries, you should. |
| 09:26 | crocket | That's not 'almost'. |
| 09:26 | gfredericks | well the answer for clojure will be the same as whatever platform you're on, generally |
| 09:26 | mungojelly | write just the performance sensitive parts in c and expose them as a library. it's not ideal but that's what everyone does. |
| 09:27 | gfredericks | so by deciding to use clojure on platform X you're agreeing to whatever restrictions platform X has in that category |
| 09:27 | crocket | I'd like to see a natively compiled variant of clojure. |
| 09:27 | crocket | NativeClojure, maybe. |
| 09:27 | crocket | The platforms are x86 and so on. |
| 09:28 | crocket | It should have built-in garbage collection. |
| 09:28 | mungojelly | clojure as a language is tied closely to the semantics of the jvm and indeed to the java libraries |
| 09:28 | crocket | So, I said 'variant'. |
| 09:28 | crocket | Or, a new langauge heavily inspired by clojure. |
| 09:28 | gfredericks | mungojelly: that's not true, cljs and clj-clr are both things |
| 09:29 | mungojelly | gfredericks: i've been wondering, how much code actually works across all of them? |
| 09:29 | wasamasa | not much |
| 09:29 | gfredericks | mungojelly: more and more, thanks to cljc |
| 09:29 | mungojelly | it seems like in practice things are mostly for one platform or another, but i don't have a sense for the details |
| 09:29 | gfredericks | except for the clj-clr part but only because nobody uses it |
| 09:29 | wasamasa | yup |
| 09:30 | crocket | cljs is terrific except tooling. |
| 09:30 | crocket | gfredericks, Is it possible to create a single source folder for both clojure and clojurescript? |
| 09:31 | gfredericks | crocket: yes, reader conditionals is a new feature in clojure 1.7 for sharing the same files |
| 09:31 | gfredericks | e.g., test.check will soon have a mostly unified codebase that works on the jvm and cljs |
| 09:31 | crocket | gfredericks, Do the build tools facilitate using single source folder for multiple languages? |
| 09:32 | gfredericks | crocket: yep |
| 09:32 | crocket | I haven't read a tutorial that teaches how to do it yet. |
| 09:32 | mungojelly | do we have any libraries for generating c? oh there's this c-in-clj thing, how's this work |
| 09:32 | crocket | I started learning clojurescript a while ago |
| 09:32 | gfredericks | crocket: github.com/gfredericks/test.chuck does |
| 09:33 | crocket | Can a web app pull it off, too? |
| 09:33 | crocket | isomorphic source base for server and client. |
| 09:33 | gfredericks | you can certainly share source when that makes sense |
| 09:33 | gfredericks | e.g., if you want business logic shared on both ends then you can do that easily |
| 09:34 | crocket | What kind of build tools support that? |
| 09:34 | gfredericks | leiningen |
| 09:34 | crocket | lein-cljsbuild? |
| 09:34 | gfredericks | yep |
| 09:34 | gfredericks | see test.chuck linked above |
| 09:34 | crocket | I'm not sure how it's done, yet. I'll get there. |
| 09:34 | gfredericks | another portable lib: https://github.com/gfredericks/exact |
| 09:35 | crocket | gfredericks, Can you recommend the best clojurescript learning material? |
| 09:35 | crocket | Clojurescript: up and running is quite old. |
| 09:35 | crocket | I already know clojure. |
| 09:35 | gfredericks | crocket: I think the wiki on github is supposed to be decent |
| 09:36 | dnolen | mungojelly: re: code sharing, ClojureScript is easily the most significant .cljc project, some 7000 lines of shared code so the compiler can run on JVM or JS |
| 09:37 | crocket | gfredericks, It refers me to several tutorials. |
| 09:37 | crocket | They all overlap. |
| 09:37 | crocket | They all overlap largely |
| 09:41 | crocket | gfredericks, Did you read clojurescript: up and running? |
| 09:45 | crocket | Damn... |
| 09:45 | crocket | If clojure could be used to write kernels and operating systems, it would rule the world. |
| 09:47 | gfredericks | crocket: no; I've been using cljs for >3yrs now so have no idea what modern tutorials are like |
| 09:48 | crocket | God damn you |
| 09:48 | crocket | 3 years |
| 09:48 | crocket | You should be a clojure expert by now. |
| 09:49 | crocket | gfredericks, Do you think dependent types can be introduced to clojure? |
| 09:51 | gfredericks | crocket: any static type system is a tough fit, as the language just wasn't designed with that in mind |
| 09:52 | crocket | Static typing and dependent typing might save big projects with many devs. |
| 09:52 | crocket | Haskell comes into mind. |
| 09:52 | crocket | If google is found today, it'd use haskell instead of C++. |
| 09:52 | crocket | Haskell wasn't mature enough when google was growing. |
| 09:53 | gfredericks | crocket: I've been seeing a lot of similar benefits from prismatic/schema + test.check |
| 09:53 | crocket | What do they do? |
| 09:54 | hyPiRion | crocket: Google uses mainly Java internally, actually. |
| 09:54 | crocket | Oh |
| 09:54 | crocket | They do the work of static typing. |
| 09:55 | emauton | That's not at all true, FWIW: the languages used there are mostly C++, Java, Python and Go, in roughly that order. |
| 09:57 | crocket | I'm not sure if clojure should be the langauge for writing AI infrastructures. |
| 09:57 | crocket | JVM |
| 09:57 | crocket | JVM deters me. |
| 09:57 | crocket | It's hungry of RAM. |
| 09:58 | emauton | RAM is cheap, please try to forget that. |
| 09:58 | crocket | RAM is not cheap |
| 09:58 | crocket | RAM is cheap for big companies |
| 09:58 | crocket | That kind of thinking only makes hardware manufacturers richer. |
| 09:58 | hyPiRion | emauton: re C++: Really? Has it changed the last 1.5 years, or have I only been in contact with the "higher level" infrastructure? |
| 09:59 | crocket | Compared to OCaml, JVM uses ungodly amounts of RAM. |
| 09:59 | emauton | hyPiRion: I guess the latter. I've been out for 1.5 years myself. :o) |
| 09:59 | crocket | Now, OCaml is quite performant. |
| 10:00 | crocket | emauton, If RAM was so cheap, why don't you run linux on JVM? |
| 10:00 | emauton | crocket: I'm sorry, I won't be engaging with this anymore. |
| 10:00 | crocket | Write kernel in java |
| 10:00 | emauton | J |
| 10:01 | sotojuan | o.O |
| 10:02 | crocket | I want to see C killed. |
| 10:02 | hyPiRion | emauton: hah, alright then, I stand corrected. I've only talked to some Chrome devs, and they said that most services was Java, only outliers like Chrome/"low level" infrastructure was C++. |
| 10:04 | crocket | People nowadays launch java processes in VMs because dev time is as expensive as or more expensive than hardwares. |
| 10:04 | crocket | That doesn't mean hardware is cheap. |
| 10:05 | crocket | If you're desining client applications, you'll realize that ordinary people do not have 64GB of RAM. |
| 10:06 | nooga | that's why you move logic to the "cloud" |
| 10:07 | nooga | it's called SaaS ;D |
| 10:07 | crocket | Well, if you are designing native GUI applications and system libraries, you don't have that kind of luxury. |
| 10:07 | crocket | Smartphones have 1-4GB of RAM. |
| 10:09 | crocket | So, the assumption is that you're a cloud app developer. |
| 10:09 | crocket | Then, RAM is cheap. |
| 10:10 | crocket | However, people still miss the experience of native GUI apps. |
| 10:10 | sotojuan | I think most people nowadays are. |
| 10:10 | crocket | web browsers are slower. |
| 10:10 | crocket | They are limited |
| 10:10 | crocket | sotojuan, That's because of web bubble. |
| 10:11 | visof | hi |
| 10:12 | visof | i have list and function and want to apply function of list per element but each result of invocation is the input for other? |
| 10:13 | visof | (defn foo [x] (* x x)), (foo x), (foo (foo x)), (foo (foo (foo x))) |
| 10:13 | visof | how can i do this? |
| 10:14 | emauton | visof: Sounds like you might want http://clojuredocs.org/clojure.core/iterate |
| 10:18 | emauton | ,(take 4 (iterate (fn [x] (* x x)) 2)) |
| 10:18 | clojurebot | (2 4 16 256) |
| 10:57 | jimmy--- | If anyone's got a moment to critique a macro that's like defn, but produces a curried version of the function, I'd love feedback. Notes, questions, and usage supplied in the link. Many thanks! http://pastebin.com/mBLMtLkX |
| 11:01 | justin_smith | (-> args count (= 0)) => (zero? (count args)) |
| 11:07 | justin_smith | actually no => (empty? args) |
| 11:10 | justin_smith | jimmy---: you don't need gensyms, because no symbols created in that let body are emitted - it's just transforming forms and using existing symbols, not emitting any new symbols |
| 11:14 | justin_smith | jimmy---: `(defn ~name ~args ~body) => (list 'defn name args body) |
| 11:15 | justin_smith | (list `~args `~body) => (list args body) |
| 11:16 | justin_smith | (cons 'defn (cons `~name (seq `~all-bodies))) => `(defn ~name ~@all-bodies) |
| 11:19 | lodin- | jimmy---: I don't know if it's good or bad, but I almost always prefer syntax quote over constructing the result manually, even if it's just (list args body). |
| 11:19 | justin_smith | lodin-: to me it just ends up looking like cargo cult macro making. Use syntax quote if it's more concise and clear, if it isn't don't use it. |
| 11:20 | lodin- | justin_smith: I use it precisely because I think it's clearer. :-) |
| 11:20 | jimmy--- | justin_smith: re:gensyms: OK. I personally didn't see any way that I could clobber anything, but I've been wrong plenty of times before. |
| 11:20 | justin_smith | lodin-: there's no way (list `~args `~body) is clearer than (list args body) |
| 11:21 | justin_smith | jimmy---: no symbol you create ends up in the output form |
| 11:21 | lodin- | justin_smith: I mean of course `(~args ~body). |
| 11:21 | justin_smith | lodin-: OK, I was talking about the actual code |
| 11:22 | justin_smith | and even compared to `(~args ~body) I find (list args body) much more clear |
| 11:22 | lodin- | justin_smith: Interesting. |
| 11:23 | jimmy--- | justin_smith: I haven't thought it through entirely, but isn't it possible to clobber something in the code to be transformed by the macro within something like a let within the macro? |
| 11:24 | lodin- | I use `() as a way to tell the reader (= me) that "this will (probably) end up in macroexpand". I don't use it if I plan to pick it apart and manipulate it further. |
| 11:24 | justin_smith | jimmy---: your macro does not transform any symbol that comes in, and it does not emit any symbol that isn't a: in clojure.core or b: in its input already |
| 11:24 | justin_smith | jimmy---: you can't possibly clobber within those constraints |
| 11:25 | justin_smith | lodin-: `() is valid both inside and outside macros |
| 11:25 | lodin- | justin_smith: Sure. |
| 11:28 | jimmy--- | justin_smith: Sorry, I wasn't clear. I just meant in general when writing macros, but I guess the fact that gensyms exist answers my question. |
| 11:30 | lodin- | I also tend to write `([~@args] ~@body), and not care about which sequence type args happens to be. I think this is much clearer than e.g. (conj args body), which might sound weird, but if I were to highlight only the syntax quoted code in a macro (and in code-returning functions used in the macro), I get a pretty good picture of how the resulting code will look. |
| 11:30 | justin_smith | jimmy---: that's true, and for that reason if you use let or defn inside ` it will force you to use gensyms |
| 11:32 | jimmy--- | justin_smith: Ahh, OK, I didn't know it was forced within `. Good to know. |
| 11:33 | lodin- | jimmy---: Another point: I think it is customary that body is a seq, e.g. (defmacro foo [stuff & body] ...). If it's not several statements, call it "expr" or something. This is just my experience from having looked at some macros. |
| 11:33 | justin_smith | it's essentially a side effect of ` ns-resolving every symbol, and you can't let-bind ns-qualified names |
| 11:41 | jimmy--- | lodin-: OK, I'll move away from the name 'body' in my case then. Thanks. |
| 11:41 | jimmy--- | justin_smith: Ahh, right, that makes sense then. |
| 11:42 | lodin- | jimmy---: Why not change to [... & body] and adjust accordingly? |
| 11:56 | jimmy--- | lodin-: Hmm... I'm trying to work it out. I just wonder if someone were to then look at it, if they'd expect to be able to send arities themselves, and then there's a whole new problem. |
| 11:56 | lodin- | jimmy---: I don't follow. |
| 11:59 | jimmy--- | lodin-: Now one just sends a single argument, expr. If they saw it takes [name args & body], they might try to supply their different arities as such: (defcurried f ([] "no args") ([x] "one arg") ([x y] "etc.")) |
| 12:00 | jimmy--- | lodin-: And then maybe expect (if there were gaps in the arities) for the currying to "just work." |
| 12:00 | lodin- | jimmy---: Maybe, but I don't find it likely, really. |
| 12:01 | lodin- | [name args & body] is not [name & fn-tails]. The args is outside the seq, but in your example the args are in the seq. |
| 12:01 | jimmy--- | lodin-: I agree, the likelihood is extremely small as I expect the number of users who use this to be countable on one thumb. :) |
| 12:01 | lodin- | jimmy---: I wouldn't worry about it. |
| 12:03 | lodin- | It's not necessary to use & body either, since you can always just use (do ...), but I think it is more likely that your users assume that you can add a leading assert or prn without it (and end up being confused by the error message). |
| 12:06 | lodin- | jimmy---: What are you porting, btw? |
| 12:07 | jimmy--- | lodin-: OK. Got it afloat with & body now. Good practice if nothing else. |
| 12:08 | jimmy--- | lodin-: I was going through the functional parsers section of the Graham Hutton Haskell book. |
| 12:10 | jimmy--- | lodin-: I was giving pixie-lang a whirl, saw it could read json, but not output it, and realized I didn't really know much about parsing and looked into that. |
| 12:10 | jimmy--- | lodin-: But then I ended up using protocols instead, but am going back to the parsing stuff now because it seems useful. |
| 12:23 | justin_smith | jimmy---: why would you parse anything in order to generate json? |
| 12:23 | justin_smith | jimmy---: usually when generating json you have data structures already in your program that you want to emit |
| 12:24 | justin_smith | and there's no parsing in that, unless you are doing it the hard way, turning the structures into strings, parsing them again, and then making json out of that? |
| 12:27 | jimmy--- | justin_smith: For a json-in, json-out program, it's not simply emitting. |
| 12:28 | justin_smith | OK, you already mentioned it had json reading, I guess I misunderstood |
| 12:29 | justin_smith | so, you realized it couldn't write json, so decided to implement both reading and writing? |
| 12:32 | jimmy--- | justin_smith: I've only done the writing thus far, which was a breeze, and was all that I actually needed given the reading was provided. But parsers weren't covered in my school's curriculum, so I'm just looking to fill that void at this point. |
| 12:36 | justin_smith | ahh, got it |
| 12:36 | justin_smith | hopefully they at least covered FSMs |
| 12:39 | jimmy--- | justin_smith: It was gone over pretty quickly when covering regex. So we saw them and the BNF notation, but didn't put it to code unless you count regex. |
| 12:40 | justin_smith | got it |
| 12:47 | kavkaz | I know this isn't #emacs, but do you guys have any idea how to change the color of the menu bar and the scroll bar? |
| 12:48 | triss | so is there any work in the pipeline to make it possible to have :pre and :post conditions emit custom error messages? |
| 12:49 | triss | I'd love to be able to embed Strings that described the problem encountered in the error thrown |
| 12:51 | hellofunk | kavkaz: what menu bar? what scoll bar? :) |
| 12:52 | kavkaz | hellofunk: one second, i'll send you a screenshot |
| 12:52 | hellofunk | kavkaz: i am jesting with you |
| 12:52 | kavkaz | haha |
| 12:52 | hellofunk | kavkaz: most emacs users (well many) do not use those features in emacs at all and have the GUI turned off |
| 12:53 | hellofunk | triss: the pre/post map already shows which pre/post expression failed, in its message |
| 12:54 | justin_smith | kavkaz: there's faces defined for the menu and scroll bar and tool bar that you can use to set foreground and background colors |
| 12:55 | triss | cheers hellofunk. I'd love to be able to provide a message like I do would with `assert` |
| 12:55 | triss | could make my library a lot more friendly |
| 12:56 | justin_smith | yeah, pre / post are very uninformative, I just do asserts instead, much more flexible in representation and in output |
| 12:56 | justin_smith | I mean it's an OK idea just not polished enough to be actually useful for me |
| 12:56 | justin_smith | also I can throw an assert into the middle of a let block, etc. |
| 13:00 | kavkaz | Ah thank justin_smith |
| 13:00 | kavkaz | thanks hellofunk, but I'll probably try first with my GUI version |
| 13:01 | justin_smith | kavkaz: my favorite idiom (assert (ok? input) (str "input was not ok: " (pr-str (select-keys input [:relevant :keys])))) |
| 13:01 | justin_smith | pr-str so that things containing strings and/or symbols will be readable |
| 13:01 | kavkaz | haha justin_smith did you mean triss |
| 13:02 | justin_smith | ahh, oops |
| 13:02 | justin_smith | got my channels crossed |
| 13:02 | kavkaz | Yes the assert thing changed the colors of my emacs haha |
| 13:03 | triss | pleased to know it bothers more than just me justin_smith |
| 13:04 | triss | Would it really be so hard to implement? Are there reasons it hasn't been? |
| 13:04 | kavkaz | ,(assert (colors-ok? my-colors) (println "keep using emacs") (println "keep working on your .emacs file")) |
| 13:04 | clojurebot | #error {\n :cause "Wrong number of args (3) passed to: core/assert"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (3) passed to: core/assert"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6797]}]\n :trace\n [[clojure.lang.Compiler macroexpand1 "Compiler.java" 6797]\n [clojure.lang.Compiler macroexpand "Compiler.java" 6853]\n [clojure.lang.Compiler ... |
| 13:05 | kavkaz | oh true |
| 13:05 | kavkaz | haha didn't do it right |
| 13:05 | justin_smith | kavkaz: also, assert messages don't work like that |
| 13:25 | justin_smith | ,(assert false (str "this guy, " 'kavkaz " does not use assert.")) |
| 13:25 | clojurebot | #error {\n :cause "Assert failed: this guy, kavkaz does not use assert.\nfalse"\n :via\n [{:type java.lang.AssertionError\n :message "Assert failed: this guy, kavkaz does not use assert.\nfalse"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Comp... |
| 15:06 | roelof | Can I take care that 2 expressions are executed after a if then is true. And if so, how can I do this ? |
| 15:07 | justin_smith | roelof: do |
| 15:07 | justin_smith | roelof: if your if would be only one branch, use when |
| 15:08 | justin_smith | ,(if true (do (print 'a) (print 'b)) 'c) |
| 15:08 | clojurebot | ab |
| 15:08 | justin_smith | ,(when true (print 'a) (print 'b)) |
| 15:08 | clojurebot | ab |
| 15:09 | roelof | oke, I have this http://lpaste.net/141379 and after the W , I have to update another variable thorX with 1 |
| 15:10 | roelof | and after the E I have to decrease the same variable with 1 |
| 15:11 | justin_smith | roelof: that looks more like a case for cond |
| 15:11 | justin_smith | ,(cond (> 0 1) "W" (< 0 1) "E" :else "") |
| 15:11 | clojurebot | "E" |
| 15:11 | justin_smith | I think that's what you want |
| 15:13 | roelof | justin_smith: no, what I want is something like this if var1 < var2 then W ; var1 = var1 + 1 else |
| 15:13 | roelof | "" |
| 15:13 | oddcully | ,(let [thor-x 5 light-x 2] (get {-1 "W" 0 "" 1 "E"} (compare thor-x light-x))) |
| 15:13 | clojurebot | "E" |
| 15:14 | roelof | oddcully: is thor-x there updated ? |
| 15:14 | justin_smith | roelof: what is "+ 1" |
| 15:15 | roelof | +1 means that var1 is increased by 1 |
| 15:15 | justin_smith | oh, you aren't using clojure = there, OK |
| 15:15 | roelof | sorry |
| 15:17 | justin_smith | (let [var1 0 var2 1 [result var1] (case (> var1 var2) ["W" (inc var1)] (< var1 var2) ["E" var1] :else ["" var1])] ... (code using var1 and result)) ; something like this? |
| 15:18 | justin_smith | you can easily make a new binding for var1, actually changing it is a whole other mess |
| 15:19 | roelof | justin_smith: I think so . I have to try it out |
| 15:26 | roelof | hmm, still errors on this code : Exception in thread "main" java.lang.RuntimeException: Unmatched delimiter: ), compiling:(Player.clj:21:42) |
| 15:27 | justin_smith | OK, so you have too many close parens somewhere? |
| 15:29 | roelof | justin_smith: I think so, Clojure is more difficult then I thought after reading 4 chapters of Living Clojure |
| 15:31 | justin_smith | roelof: it can help to have an editor which has paren highlighting, or auto indent, or paren-colorizing |
| 15:32 | roelof | justin_smith: the challenge site has one but still I do not see it. I have deleted all the ) after the [] except the last one and still the same error |
| 15:32 | justin_smith | can you share the updated code? |
| 15:33 | roelof | justin_smith: yes, here you have : http://lpaste.net/141381 |
| 15:35 | justin_smith | roelof: for starters, on line 10 you should be providing a binding vector for the results of the case on line 10 |
| 15:35 | justin_smith | roelof: second problem, there is nothing in your code that will actually propagate the new bindings when the while does its next iteration |
| 15:35 | justin_smith | you can fix this by changing while to loop, and passing the new bindings to recur |
| 15:37 | roelof | oke, the W must be in the variable directionX or directionY. If I read the code right thor-x and thor-y are already updated |
| 15:37 | justin_smith | roelof: nothing can update in that code |
| 15:37 | justin_smith | it's impossible, there is no mechanism by which this would occur |
| 15:38 | roelof | pff, I think Clojure is not for me. Im struggeling the whole day with this problem |
| 15:38 | justin_smith | you can shadow bindings with new bindings, but by the time the while does its next loop, the old bindings don't even exist any more |
| 15:39 | justin_smith | roelof: there's one root misunderstanding going on for you here, and once you sort that out everything else comes from understanding the consequences of it |
| 15:39 | justin_smith | roelof: clojure bindings do not change, ever. They can be shadowed, or replaced in a new iteration, but nothing changes them. |
| 15:40 | justin_smith | roelof: so you need mechanisms to propagate new bindings to their context |
| 15:40 | justin_smith | these include loop/recur, recursive functions, or shadowing within a single let block |
| 15:40 | roelof | yes, I read that So I have to use things like reset! ? |
| 15:40 | justin_smith | no |
| 15:40 | justin_smith | roelof: the syntax problem is that you don't close the let binding vector |
| 15:41 | justin_smith | the reason it's complaining about an unexpected ")" is because it needs a "]" first |
| 15:42 | justin_smith | in order to rebind thor-x and thor-y, you need to rewrite the case call so that every result returns thor-x, thor-y, and the direction string |
| 15:42 | justin_smith | currently you aren't even using the result of the case |
| 15:44 | roelof | oke, back to the books then |
| 15:46 | justin_smith | ,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 10) iterations (recur new-x new-y (inc iterations)))) |
| 15:46 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 15:47 | justin_smith | ,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 10) iterations (recur new-x new-y (inc iterations))))) |
| 15:47 | clojurebot | Execution Timed Out |
| 15:47 | justin_smith | ,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 10) iterations (recur new-x new-y (inc iterations))))) |
| 15:47 | clojurebot | Execution Timed Out |
| 15:47 | justin_smith | that immediatly returns a number (about 250k) on my box |
| 15:47 | justin_smith | ,(loop [x 0 y 0 iterations 0] (let [new-x (+ x (dec (rand-int 3))) new-y (+ y (dec (rand-int 3)))] (if (= new-x new-y 5) iterations (recur new-x new-y (inc iterations))))) |
| 15:47 | clojurebot | 17 |
| 15:48 | justin_smith | roelof: that's a random walk that stops when x and y are both 5 |
| 15:48 | justin_smith | you should be able to use the same basic structure as above (modified for your own logic of course) |
| 15:48 | roelof | justin_smith: thanks |
| 15:49 | justin_smith | oh wow, I guess my first try with 10x10 was lucky |
| 15:49 | justin_smith | the second run locally is taking forever... |
| 15:50 | roelof | oops, not good |
| 15:50 | justin_smith | execution time of a random walk to a determined point is very unpredictable :P d'oh |
| 15:51 | roelof | I think you are right here |
| 15:52 | justin_smith | I wonder what the minimum coordinate distance from 0 is where integer overflow is more likely than hitting the target |
| 15:52 | roelof | but im going to bed. it's late here. and thanks for the explantion and patience with me |
| 15:56 | justin_smith | roelof: no problem, thank you for your patience as well, I know it's not always easy |
| 16:01 | roelof | nope, maybe if I look at it with a fresh look there will be a aha moment |
| 16:01 | roelof | till now I find it all very confusing |
| 16:02 | roelof | maybe wait for the new brave and true and try to learn from that. I did now use living clojure and the click is not there |
| 16:03 | justin_smith | In the long run, immutability makes things much less confusing. Clojure isn't a harder way to do things, just a different one. Give it time to sink in, like a new language. |
| 16:11 | sobel | I think immutable data has made my programming life simpler |
| 16:13 | roelof | for me as beginner at this moment not. Like I said earlier I m the whole day busy with this challenge which seems to be easy |
| 16:16 | roelof | maybe someone knows a good beginners book with a lot of exercises |
| 16:17 | justin_smith | roelof: this task you picked would be easier for you right now if you didn't know how to program already, the mistakes you are making are basically caused by assumptions about programming languages that clojure doesn't follow |
| 16:19 | jakesyl | #join facebook |
| 16:19 | roelof | justin_smith: that can also be a reason |
| 16:21 | roelof | and I see that loops and recurr are not explained in the living clojure book |
| 16:22 | roelof | so I think I wait for the new brave and true and hopefully that book will explain that |
| 16:23 | roelof | in this example there is also no recur ;; a var to be used for its side effects (def a (atom 10)) ;; #'user/a (while (pos? @a) (do (println @a) (swap! a dec))) ;; 10 ;; 9 ;; 8 ;; 7 ;; 6 ;; 5 ;; 4 ;; 3 ;; 2 ;; 1 ;;=> nil |
| 16:23 | amalloy | justin_smith: another way of writing the random walk that i think is interesting: |
| 16:23 | amalloy | ,(count (take-while (complement #{[3 3]}) (reductions (partial map +) [0 0] (repeatedly #(repeatedly 2 (fn [] (dec (rand-int 3)))))))) |
| 16:23 | clojurebot | 47873 |
| 16:24 | roelof | but im now really goto bed. Good night all |
| 16:27 | justin_smith | amalloy: nice, you could do that one with iterate too I think |
| 16:28 | amalloy | yeah, but the lambda you give to iterate is bigger, since it needs the + and the randomness. i like keeping them separate, and this *almost* survives with no lambdas |
| 16:46 | justin_smith | Now I am asking myself why I committed myself to do a live performance using software that wasn't done yet. I had my code all ready to go and see at the last stretch that my raspberry pi (which was going to run this synth code) doesn't boot. Now trying to reinstall and crossing my fingers this is not a hardware problem... |
| 17:45 | mungojelly | have any of you tried funding your programs chits and then charging them for resources? i'm sick of my programs getting a free ride :p |
| 17:53 | mungojelly | for disk space i guess i'm going to auction blocks of database inserts or something, that's easy to quantify, i could even charge them by the byte. i'm less sure how to charge for processing, maybe auction off slices of time and warn and terminate!? |
| 17:55 | justin_smith | mungojelly: just like in macroeconomics, the ideal is 100% resource usage because savings is meaningless under inflationary pressure. I want all my CPUs at 100% - and then I optimize so that more work is getting done. |
| 17:56 | justin_smith | introducing a systemic pressure to prevent resource usage is counterproductive if you have any task you are undertaking. |
| 17:57 | mungojelly | justin_smith: you always decide manually about specific resources, though, eh? what i'm saying is i want the resources to be maxed out and distributed, but instead of saying who specific resources go to i want just to say which things are important without specifying what resources that translates into |
| 18:00 | justin_smith | mungojelly: if your app is complex enough to have more than one task workflow, you can use a system like onyx which allows task prioritization, but most everything I've made before my current onyx process has client requests, and then a set of unconditional tasks which are needed to fulfil each request |
| 18:02 | mungojelly | justin_smith: what i'm making is evolving processes, they reproduce when they can so there's always (more than) the maximum of them, so i can't just always say yes to them i have to have some way of dumping/ignoring low priority (potential) tasks |
| 18:15 | mungojelly | today i managed to get "lein run" to run the same thing i got working in the repl, but it was more complicated than i expected. :/ is there something i should read or watch about leiningen that'll make things clearer? |
| 18:15 | justin_smith | mungojelly: no top level side effects |
| 18:15 | justin_smith | mungojelly: that means don't call def with args that alter state |
| 18:16 | justin_smith | once you are following that rule, it's easy |
| 18:16 | justin_smith | all stateful initialization should be done explicitly inside -main, or by some function called by -main |
| 18:17 | mungojelly | i learned this -main thing and also i learned to say :main somewhere else pointing at the namespace with -main in it |
| 18:17 | mungojelly | but there's clearly a zillion other things i'm missing, i need leiningen 101 |
| 18:17 | justin_smith | eh |
| 18:18 | justin_smith | leiningen is mostly declarative, once you learn what the valid keys are that's usually it |
| 19:54 | cammellos | join haskell |
| 20:34 | hlolli | ,(defn print-hello [] (prn "hello-atom")) |
| 20:34 | clojurebot | #'sandbox/print-hello |
| 20:34 | hlolli | ,(print-hello) |
| 20:34 | clojurebot | "hello-atom"\n |
| 20:35 | justin_smith | hlolli: so I was going to be performing using a csound thing tonight, but my raspberry pi broke at the wrong moment |
| 20:35 | hlolli | ,(def atomic-eval (atom {:eval #'print-hello})) |
| 20:35 | clojurebot | #'sandbox/atomic-eval |
| 20:36 | hlolli | ok, I tried using csound on the raspberrym it's very unstable. Very slow for sure. |
| 20:36 | hlolli | Haven't tried the new one, is it compleatly broken or just a bug? |
| 20:36 | justin_smith | the device is refusing to boot |
| 20:36 | justin_smith | I think some hardware is bust |
| 20:37 | hlolli | ,(eval (:eval @atomic-eval)) |
| 20:37 | clojurebot | #'sandbox/print-hello |
| 20:37 | hlolli | why didn't that work? |
| 20:37 | justin_smith | hlolli: you aren't calling the var |
| 20:37 | justin_smith | hlolli: you are just returning it |
| 20:38 | justin_smith | ,((:eval @atomic-eval)) |
| 20:38 | clojurebot | "hello-atom"\n |
| 20:38 | justin_smith | hlolli: eval isn't for calling functions, it is for compiling them |
| 20:38 | hlolli | wtf, ok, return it then eval. ok I see |
| 20:38 | justin_smith | when you give it something that doesn't need any resolution or compilation, it just gives you the thing |
| 20:38 | justin_smith | hlolli: no, no eval |
| 20:38 | justin_smith | eval is for compiling, the thing you have is already compiled |
| 20:39 | hlolli | ok, Im getting the grips of this difference of compile time and run time. |
| 20:39 | justin_smith | hlolli: every form you type into the repl is implicitly evaled already, and having to use eval otherwise is usually a sign you are doing something wrong, unless you are writing a compiler |
| 20:40 | hlolli | ok ok |
| 20:40 | justin_smith | the repl is a loop, it reads forms, compiles them, then prints the result, then loops |
| 20:40 | justin_smith | REPL |
| 20:40 | hlolli | I just would not have guessed on double parenthesis |
| 20:40 | justin_smith | hlolli: parenthesis are the syntax for calling things |
| 20:40 | hlolli | ok ok |
| 20:41 | justin_smith | if you have a function, and want to call it, you need to wrap it in parens. If something returns a function and you want to call it immediately, you need double parens |
| 20:41 | justin_smith | if you had a function returning a function returning a function, triple parens would be the thing you want |
| 20:42 | mungojelly | ,(let [x (fn [] (fn [] (fn [] "hi")))] (((x)))) |
| 20:43 | clojurebot | "hi" |
| 20:43 | hlolli | haha ok, funny how thinking about some language feature before knowing that it's a feature, that's how I usually learn best, to see it in practice. |
| 20:43 | hlolli | triple! |
| 20:44 | rhg135 | The factories of factories are useful |
| 20:45 | gfredericks | ,(let [f (nth (iterate constantly 42) 10)] ((((((((((f))))))))))) |
| 20:45 | clojurebot | 42 |
| 20:46 | hlolli | 10 parenthesis, winner |
| 20:48 | gfredericks | I wonder what the upper limit on that is |
| 20:48 | domgetter | And that was the last time we saw gfredericks alive... |
| 20:49 | hlolli | jvm nuke |
| 22:30 | rritoch | Is there any way to create a new class that extends another class overriding some methods without using a gen class? I've been trying to get away from gen-class dependence but for this issue I can't see a way around it. |
| 22:48 | domgetter | If I have a clojurescript app and I want to maintain a list of stuff that's updating, like a chatlog, is it better to use an atom or one of the immutable persistent data structures? |
| 22:54 | namra | domgetter: i think a chatlog can become quite large, and immutable means higher memory requirements. using an atom in this case would you save memory, but don't know if it would also be faster, something to test. and because of clojure easy and safe way to actually work with atoms, why not use it. |
| 22:56 | namra | cljs not clojure ^^ |
| 22:56 | domgetter | namra: That's sensible. I'll try to get to a point where I would understand how to test that. |
| 22:59 | namra | a simple way i can think of is using included time fns near the code that updates i.e. the chatlog |
| 23:01 | namra | there's even a time macro |
| 23:01 | namra | (doc time) |
| 23:01 | clojurebot | "([expr]); Evaluates expr and prints the time it took. Returns the value of expr." |
| 23:01 | namra | .(doc time) |
| 23:07 | amalloy | "should i use an atom or a persistent data structure" seems like the wrong question to me: almost the only sensible thing to put in an atom *is* a persistent data structure |
| 23:23 | python476 | hi there |
| 23:23 | python476 | I'm having trouble converting this Path path = FileSystems.getDefault().getPath("logs", "access.log"); |
| 23:24 | python476 | Started with this (.. FileSystems getDefault), ok, (.. FileSystems getDefault (getPath "/var")) fails |
| 23:25 | python476 | (and btw, I'm not trying to be idiomatic, it was about learning java interop) |
| 23:36 | Sauken | Hello! |
| 23:36 | mal_ | hola |
| 23:37 | amalloy | python476: http://stackoverflow.com/q/5638541/625403 |
| 23:37 | python476 | Apparently one has to ... (Paths/get "/" (into-array String ["bar" "baz"])) sometimes |
| 23:37 | python476 | makes me cry all inside |
| 23:37 | python476 | amalloy: heh, was just reading this. |
| 23:37 | Sauken | I've got a question. So I made a random letter generator in C++, and I made it write 10,000 random capital letters from A-Z |
| 23:38 | Sauken | How do I look for my name inside of those letters? |
| 23:39 | python476 | unless you (Paths/get (URI. "file:///var/log")) then interop lands on its feet |
| 23:41 | python476 | oh and you were the author of the final answer, how convenient |