#clojure log - Mar 01 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

1:41 Guthur: how do i get a global var that allows me to assign to it, and how do i do the assignment?

1:45 TEttinger: Guthur, you probably want an atom.

1:45 ,(def mutable (atom 10))

1:45 clojurebot: #'sandbox/mutable

1:45 TEttinger: ,(reset! mutable 20)

1:45 clojurebot: 20

1:45 TEttinger: ,@mutable

1:45 clojurebot: 20

1:45 TEttinger: ,(swap! mutable inc)

1:45 clojurebot: 21

1:45 TEttinger: ,@mutable

1:45 clojurebot: 21

1:46 TEttinger: reset! will set the value of the atom without regard to its current value

1:46 swap! changes it by calling a given fn on the current value

1:47 get the current value (not within swap!) by calling (deref mutable) or shorthand @mutable

1:47 Guthur: TEttinger: ah ok, cheers

1:47 TEttinger: there are other ones, but I've found I mostly use atoms

1:48 atoms are certainly the simplest

1:48 Guthur: I just need the simplest at the moment, this is just to ease testing at the REPL

1:48 ah ok, well then all good

1:48 thanks again

1:49 TEttinger: java classes are always mutable unless the java that wrote them defined them in some immutable way (like clojure's data structures, which are written in Java behind the scenes), and arrays are always mutable

1:49 arrays being the harder-to-use, only-one-type, non-resizable cousin of vectors :)

2:44 kryft: I finally managed to set redirect-on-auth? to false in friend, but now a successful login returns 404 instead of redirecting. The 404 response does include the authentication cookie, so the only problem is the status code itself

2:53 justin_smith: kryft: what route is it trying to hit?

2:55 kryft: justin_smith: I don't know (but apparently it ends up hitting my (route/not-found ..)

2:55 )

2:56 justin_smith: I was trying to figure out if its trying to GET some other route by looking at the friend source, but didn't figure it out yet

2:57 I don't have :default-landing-uri set at least (and in any case I assumed that was only used when redirect-on-auth? is set to true)

2:58 justin_smith: kryft: if it isn't redirecting, shouldn't it try to land on the same URI that friend handles, but after the friend middleware?

2:59 kryft: justin_smith: You mean that if I'm POSTing to /login, it should try to GET /login and return that?

3:00 justin_smith: well, I don't see why it would change the request method

3:00 it should try to post to /login if you don't redirect it

3:02 kryft: justin_smith: Ahhh. Yes, now it works, thanks. :) I falsely assumed that I wasn't supposed to define the /login route and that friend somehow handles that, but of course friend is just middleware that does something special for that route

3:02 justin_smith: exactly, but if you told friend to redirect, then you would not need to define that route

3:05 kryft: Right, which is what I did before (because I couldn't manage to set :redirect-on-auth? to false - after a lot of googling I finally figured out that you need to give it to workflows/interactive-form as a parameter)

3:06 That was weird given that all the other parameters (:allow-anon? etc.) can be passed in a map to friend/authenticate

3:24 TEttinger: Well someone just got interested in clojure after I pasted a gibberish compressed name generator into a channel's eval, started reading Brave Clojure and then he and I went back and forth trying to implement a fibonacci sequence generator (I was trying to remember how to do it cleanly, he was trying to figure out how to do it), and in less than maybe 4 hours since hearing about clojure, he was understanding tons of it.

3:25 lazy sequences as generators of the next step one step at a time, reduce/reductions (he guessed what reductions did after seeing what reduce does), iterate, destructuring

3:25 there are so many cool features that clojure has it's hard to tell where to start, apparently brave clojure hit the main points very well

3:26 justin_smith: interesting

3:30 TEttinger: &(map second (take 10 (iterate (fn [[a b]] [b (+ a b)]) [0 1])))

3:30 lazybot: ⇒ (1 1 2 3 5 8 13 21 34 55)

3:30 TEttinger: that's the generator I came up with

3:30 it demonstrates destructuring and fns as args, lazy seqs with take, etc.

3:57 robindunbarr: Hi all, what is the difference between ratio? and rational?

3:57 They seem to return the same thing.

4:07 TEttinger: ,(ratio? Math/PI)

4:08 clojurebot: false

4:08 TEttinger: ,(rational? Math/PI)

4:08 clojurebot: false

4:08 TEttinger: (doc rational?)

4:08 clojurebot: "([n]); Returns true if n is a rational number"

4:08 TEttinger: oh

4:08 ,(rational? 10)

4:08 clojurebot: true

4:08 TEttinger: ,(ratio? 10)

4:08 clojurebot: false

4:09 TEttinger: ratio is true for stuff like 1/2, but false for 2

4:11 wow... http://www.canonware.com/download/rb/rb_newer/rb.h

4:11 Guthur: TEttinger, on the learning that's probably why Scheme was used a lot in academia

4:12 Lisp is a very neat family of language for learning

4:12 TEttinger: probably, I'm surprised people can learn clojure so quickly now, the resources used to be not-great when it was new

4:12 Guthur: it's less to do with programming a computer and more about computation

4:12 TEttinger: yup

4:14 Guthur: I like to think of the fact that John McCarthy was trying to convey and idea with his initial paper rather than create a programming language

4:14 it was just that his students seen that they could actually implement it

4:15 devll: ,bots

4:15 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: bots in this context, compiling:(NO_SOURCE_PATH:0:0)>

4:16 devll: ,bots

4:16 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: bots in this context, compiling:(NO_SOURCE_PATH:0:0)>

4:24 ehurrell: I agree on the computation aspect of it, lisps read quite like mathematical notation, and implementations of machine learning etc are as readable as the maths they are based on. Harks back to Turing talking of a 'computer' and refering to a person who does computation

4:26 Guthur: it's what i love most about the lisps, if you want to you devise you solution completely in the abstract

4:26 of course one often has to think about the reality of computer system

4:56 robindunbarr: Thanks, TEttinger.

4:56 I didn’t know you could run the REPL from irc.

4:56 (str “That’s pretty cool.”)

4:56 ,(str “that’s pretty cool")

4:57 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

4:58 TEttinger: heh, smart quotes

5:00 robindunbarr: Gah

5:00 Lol

5:05 (str "Removed the smart quotes, finally.")

5:05 ,(str "Removed the smart quotes.")

5:05 clojurebot: "Removed the smart quotes."

5:05 robindunbarr: Heheh!

9:07 crazydiamond: Hi. Is clojure.contrib alive?

9:09 hyPiRion: clojure.contrib is long ago

9:11 justin_smith: ~contrib

9:11 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

9:11 crazydiamond: and... are transducers already avaliable?

9:17 hyPiRion: on 1.7.0 alphas, yes

12:57 crazydiamond: How to exec file other than core?

12:57 core.clj

12:59 justin_smith: crazydiamond: how are you running clojure?

12:59 with lein there is a :main option in project.clj

12:59 crazydiamond: ok

12:59 justin_smith: crazydiamond: are you using lein run?

13:00 crazydiamond: no, so...

13:00 I have vim with fireplace.vim

13:00 lein repl in separate window

13:00 justin_smith: that's not executing a file - that's just loading one

13:00 but OK

13:00 crazydiamond: and using :Connect

13:00 and :%Eval

13:01 justin_smith: whatever your :main ns, lein will make the repl use that as the init-ns (the first ns in the repl) iirc

13:02 but no matter which ns you start in, you can require any ns you like (that is accessible to your project) and then switch the repl to that ns

13:03 Kristien: Should I use io! for effectful subroutines? I've never seen it used TBH.

13:03 * gfredericks has never used it

13:03 justin_smith: Kristien: I don't see a reason not to use it

13:03 but yeah, most people don't use it

13:04 Kristien: I think it's related to contract programming.

13:04 justin_smith: if you explicitly want your routine to throw an error where retries may occur, go for it

13:04 Kristien: which people tend not to do even when available :

13:04 :p

13:04 justin_smith: Kristien: kind of - think about what your routine would do in a retry situation, if doing it twice would be really bad, us io!

13:05 Kristien: yeah, I kind of wish contracts were used more

13:10 dnolen: Kristien: io! is really most useful for STM, but the STM isn't used very frequently in Clojure

13:18 gfredericks: ,(def a (atom 0))

13:18 clojurebot: #'sandbox/a

13:18 gfredericks: ,(swap! a (fn [x] (io! (inc x))))

13:18 clojurebot: 1

13:19 gfredericks: ^ a retry situation

13:20 juggernot: dnolen: Hi, posted a message on the group RE GSOC expressing interest in clojurescript but it seems it hasn't been moderated as yet.

13:21 dnolen: juggernot: did not see it

13:21 juggernot: I don't modern Clojure much which is where it probably got sent?

13:21 s/modern/moderate

13:21 juggernot: dnolen: yea

13:21 Kristien: gfredericks: why does it not fail?

13:22 Does io! only throw when there was in fact a retry?

13:22 juggernot: dnolen: its not so much of an issue

13:22 gfredericks: Kristien: my guess is only the STM pays attention to it

13:22 dnolen: juggernot: if you PM me your email I can fix this for you

13:22 juggernot: dnolen: I just wanted to know what's the difference between the project here: http://dev.clojure.org/display/community/Project+Ideas#ProjectIdeas-ClojureScriptGoogleClosure ...

13:22 dnolen: and the foreign libs support that was added recently

13:24 dnolen: juggernot: :foreign-libs doesn't involve CommonJS/AMD/ES6 transformation passes

13:24 juggernot: doesn't automate or validate externs, etc. etc.

13:25 juggernot: dnolen: oh i see

13:25 dnolen: juggernot: you should be able to post now

13:26 juggernot: there's tons of stuff Google Closure can do that we don't take advantage of wrt. JavaScript interop

13:26 justin_smith: gfredericks: yeah, you would have to use (dosync (swap! ...)) if you cared about the protection io! ofers

13:26 *offers

13:28 juggernot: dnolen: thanks... and where could i start reading about those features in particular? is reading 'Closure the Definitive Guide' enough?

13:28 dnolen: juggernot: I don't think Closure covers the internal APIs much, but I'm not sure I've never read it (probably should)

13:28 juggernot: working with Closure means reading a lot of Java source

13:28 fortunately it's pretty well written Java source

13:30 juggernot: ok well i have no issue with java. I have significant experience there... i guess i just need to get a bit more familiar with Closure and how ClojureScript is using it

13:32 dnolen: juggernot: cljs.closure is more or less the extent of it at the moment

13:33 juggernot: source mapping, :simple/:advanced optimizations, and Google Closure Modules

13:33 juggernot: we do rely on the basic abstractions in goog.base (Google Closure Library) everywhere in order to have the same dependency model regardless of browser, iOS, Nashorn, Android etc.

13:34 mbac: https://xkcd.com/625/

13:36 juggernot: dnolen: yea i read up on all that recently

13:36 dnolen: as for the tools.reader project whats the difficulty level for a beginner to intermediate level person?

13:36 dnolen: juggernot: in anycase that's a high priority ClojureScript one, would love to see us be able to consume anything JavaScript people might write

13:37 juggernot: all ClojureScript people need to bring is externs

13:37 juggernot: tools.reader is a nice to have / lower priority, not hard at all and a big step towards bootstrapping

13:38 juggernot: but bootstrapping is not nearly as impactful today and won't be even long after it lands

13:38 all the important library stuff, dependency management etc. is all on the JVM

13:39 juggernot: dnolen: yea I'm guessing majority of the grunt work would be to port the existing macros etc.

13:40 dnolen: juggernot: no, there's very little to do w/ regard to porting macros

13:40 CLJS has many of it's own core macros, just need to port over the few things we still piggieback on Clojure for

13:41 juggernot: dnolen: oh ok

13:42 dnolen: well thanks for clearing things up ill be applying for that interop project

13:42 dnolen: juggernot: so of the 3 ClojureScript projects I wrote up - highest priority goes to cljs.core.async & Google Closure enhancements

13:42 juggernot: cool

13:42 juggernot: dnolen: are there any open discussions around it i should be aware of?

13:43 dnolen: juggernot: around what? interop?

13:43 juggernot: yea

13:43 dnolen: juggernot: ah no not really - largely because for a long time ClojureScript JS interop was very ad-hoc

13:43 juggernot: now that :foreign-libs is a thing I think people will want more/better suppport

13:44 juggernot: but also JS community is pushing in weird gross directions

13:44 so we have to follow along

13:45 juggernot: that is CommonJS/AMD/Node.js style require/ES6 is going to become more and more desirable

13:46 React-only components have already started going down the require route

13:48 juggernot: dnolen: ok, so you dont like that approach? i actually thought having require would be nice for modularity...

14:24 Mandus: kj\t\ti

14:27 dnolen: juggernot: the problem is it isn't a standard, shipping libraries that need is ugh

14:28 juggernot: if you want to use it internally OK

14:31 juggernot: the point of GSoC project to protect CLJS from the vagary of JS fads

14:36 juggernot: dnolen: ok... thats understandable

15:14 nicferrier: anyone else use hickory?

16:01 whodidthis: anyone know how re-frame deals with event dispatching when users needs to event.preventDefault()? x_X

16:02 woops wrong channel

16:46 nicferrier: raaaaaar. frustrated.

16:47 I've got a zipper that if I call next x times returns the right thing... but in a recursive loop never finds the right thing.

16:47 clearly broken... I expect it's obvious.

16:47 crazydiamond: hi nicferrier

16:47 can you share both?

16:48 nicferrier: I can't. code is locked inside a firewall. Sorry. just venting.

16:49 crazydiamond: all that stuff is not that obvious. for me - clojure is "programming right away", i.e. when you start you already must think hard

16:50 I think that "thinking functionally" is a skill, but we learn on own mistakes

16:50 nicferrier: I feel like I understand zippers.

16:50 crazydiamond: better there to exercises

16:51 but it's not easy to compose good ones

16:51 nicferrier: I feel like I think functionally... I do agree with you.... it's not trivial to bend your head round new things.

16:51 I've just obviously made a mistake in this function. just can't see what it is.

16:51 my data is quite large. I should probably cut it down.

16:52 the trouble is the data is a particular confluence page.

16:52 hard to cut down.

16:59 ho. the problem seems to be I'm getting hickory and not hiccup.

16:59 not sure why.

17:05 marcos22OX: Good day guys, I'm having troubles doing a remote debug with a vertx app...(using lein vertx) I posted in SO here http://stackoverflow.com/questions/28799405/configuring-java-options-for-remote-debug-i-always-get-error-jdwp please if anyone know how fixed I'll appreciate it

17:07 justin_smith: marcos22OX: is the error with the vertex server's port, or with the dt_socket?

17:07 if the problem is actually the latter (which I doubt) you can just not provide a socket arg and it will pick an available one

17:08 marcos22OX: tl:dr: don't change the socket arg in your :jvm-opts, change the socket the vertx server is using

17:28 marcos22OX: hi justin_smith...let me try

17:32 nicferrier: my understanding of zippers was that zip/next descended along all axes. but I've got a zipper here that is not stepping into a structure with next. it just steps over it.

17:35 justin_smith: $grim clojure.zip/next

17:35 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.zip/next

17:35 justin_smith: hmm, that grimoir page could use some examples

17:37 nicferrier: it says depth first. all the examples I've seen are depth first.

17:37 justin_smith: nicferrier: do you have a minimal example showing the behavior that surprises you?

17:37 nicferrier: the node that's coming back looks like [:table {} [:tbody ...]] but it's not finding that.

17:38 I'm finding the table... but not the tbody.

17:38 when I find the table (zip/next the-table) produces the element _after_ the :table, not from inside.

17:39 so not really depth first.

17:39 I suspect I'm doing something wrong because it's late and I'm using a crappy environment.

17:39 but it does seem odd.

17:46 you're right though. I started to work with a smaller dataset. I'm being dumb.

17:47 justin_smith: I just suspect some of use here could likely help (maybe even myself, though I am not an expert on clojure.zip), but you'll get more help if you have a small example showing the behavior that confuses you

17:47 nicferrier: sure.

17:48 fwiw I just cut it down massively and still getting the same behaviour.

17:48 totally weird.

17:48 oh wait.

17:48 justin_smith: I think I got something close to what you are talking about -- https://www.refheap.com/97978

17:48 nicferrier: if the zipper is made of a sequence but contains vectors... will the zipper not step into them?

17:49 justin_smith: that totally depends on how you define your check

17:49 ,(seq? [])

17:49 clojurebot: false

17:49 justin_smith: ,(sequential? [])

17:49 clojurebot: true

17:49 justin_smith: ,(coll? [])

17:49 clojurebot: true

17:49 justin_smith: often coll? is the right general thing to do when walking things

17:49 nicferrier: what check?

17:49 justin_smith: first arg to the function "zipper"

17:50 (doc clojure.zip/zipper)

17:50 clojurebot: Huh?

17:50 nicferrier: :-|

17:50 justin_smith: :P

17:50 $grim clojure.zip/zipper

17:50 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.zip/zipper

17:50 nicferrier: I am talking about zip/seq-zip, for example.

17:50 justin_smith: seq-zip is just a wrapper for zipper

17:51 nicferrier: gotcha. zipper is generic.

17:51 justin_smith: and seq-zip uses seq?

17:51 nicferrier: so you can make something that uses seqs or vectors.

17:51 and that's my problem!

17:51 :-D

17:51 justin_smith: see above, a vector fails the seq? test

17:51 right

17:51 nicferrier: awesome. thanks.

17:51 justin_smith: in my refheap paste above I create a zipper that uses coll? as the test

17:51 np

17:57 nicferrier: that looks definitely like it... though now I'm touching too many nodes. still I can hack it now. thanks.

18:00 justin_smith: np

18:53 emaczen: can someone point me to a flowchart or reference on clojure variables and which one to use in which case (atoms, agents, ... )

19:00 shoky: emaczen: donno if it's what you're looking for but it's helped me in the past http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

20:32 emaczen: shoky: thanks that was exactly what I was looking for

20:33 Do you refer to vars, refs, agents, and atoms as variables?

20:33 What is the terminology here?

20:46 JJJollyjim_: Hi there, I've got a small question, could I have some help?

20:47 Oh nevermind, found it in the docs! :-)

20:51 gfredericks: emaczen: those are called "reference types"; there's not really anything in clojure called "variables", but "locals" are close

21:00 enn: I'm trying to deploy something (just a snapshot, so not worried about signing/promoting at this point) to Clojars for the first time, and I must be missing something. I run lein deploy clojars, enter my username and password, and it says things like "Sending blah.jar (80k) to https://clojars.org/repo/&quot;, and in general acts as though it was successful

21:02 emaczen: what should I do when I don't need any concurrency features?

21:02 just a plain old def does not seem recommended

21:02 enn: But then when I pull up the project it tells me I have a missing pom, missing jar, and a number of missing things in my project.clj (description, etc.) -- even though my project.clj has all of those things defined (and indeed the :description from my project.clj appears at the top of the Clojars page for my project, above the complaint that description is missing)

21:05 nuwanda_: emaczen: why do you think a plain old def is not recommended?

21:07 emaczen: nuwanda: I need to mutate this variable

21:08 TEttinger: ,(def mutable (atom 0))

21:08 clojurebot: #'sandbox/mutable

21:08 TEttinger: ,(reset! mutable 11)

21:08 clojurebot: 11

21:08 TEttinger: ,@mutable

21:08 clojurebot: 11

21:08 gfredericks: emaczen: atoms for that normally, but we try pretty hard to avoid them

21:09 TEttinger: avoiding mutation in general

21:09 enn, that sounds odd

21:10 can you link to the clojars page?

21:10 emaczen: Ok, so I am new to clojure and am struggling a bit with where to start -- here is a good scenario

21:11 Say I am making a card game (I am) what would you do to add and remove cards from a player's hand?

21:11 Which variable type would you use?

21:11 gfredericks: how is the program being driven?

21:11 enn: TEttinger: https://clojars.org/enaeher/contrail

21:11 gfredericks: is this a terminal game? some sort of web server?

21:11 emaczen: I'm interested in both

21:12 gfredericks: in either case we usually try writing all of the game logic with data and functions, and then having just one top level piece of state to store the whole state of the game

21:12 enn: TEttinger: http://hastebin.com/eqihapeqas.py is the transcript of my lein deploy clojars session

21:13 emaczen: gfredericks: Can you be precise with what you mean by data?

21:13 gfredericks: but that atom or whatever is kept at the top level where you're coordinating interaction with the user, it doesn't usually overlap with the code that has game logkc

21:13 logic*

21:13 emaczen: the immutable data structures, keywords, numbers, etc

21:13 values

21:15 you might write a pure function (fn act [game-state action] ... return new game state ...)

21:15 that can handle any possible thing that happens in the game, and doesn't need any reference types or mutation

21:15 emaczen: gfredericks: wouldn't that be inefficient?

21:16 TEttinger: enn, I wonder if you were pushing to releases without it telling you

21:16 https://github.com/ato/clojars-web/wiki/Releases

21:17 emaczen, for a terminal-based game, printing to the console will be slower than processing the next step

21:17 for a web-based game, your network connection is more important

21:18 emaczen: TEtinger: so in either case I should go with a completely immutable solution?

21:19 TEttinger: probably not completely. you can probably do quite well storing anything that needs to change in one central map

21:19 that's how play-clj does it

21:20 ,(def central {})

21:20 clojurebot: #'sandbox/central

21:20 TEttinger: ,(def central (atom {}))

21:20 clojurebot: #'sandbox/central

21:20 emaczen: def is a var right?

21:20 Oh an atom

21:20 TEttinger: yeah, which is just a name

21:20 gfredericks: vars are almost never used for application state

21:21 emaczen: on #clojure, do people look at paste.lisp.org?

21:22 TEttinger: ,(swap! central update-in [:player1 :hand 0] [:clubs 10])

21:22 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer>

21:22 TEttinger: gah, how did I do it

21:22 gfredericks: assoc-in?

21:22 TEttinger: right

21:22 ,(swap! central assoc-in [:player1 :hand 0] [:clubs 10])

21:22 clojurebot: {:player1 {:hand {0 [:clubs 10]}}}

21:22 gfredericks: ,(def assoc-in? [x] (= x assoc-in))

21:22 clojurebot: #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)>

21:22 gfredericks: ,(defn assoc-in? [x] (= x assoc-in))

21:22 clojurebot: #'sandbox/assoc-in?

21:22 gfredericks: ,(assoc-in? assoc-in)

21:22 clojurebot: true

21:22 gfredericks: ,(assoc-in? assoc)

21:22 clojurebot: false

21:23 TEttinger: haha

21:23 gfredericks: #protip

21:23 ,(defn assoc-in?? [x] (= x assoc-in?))

21:23 clojurebot: #'sandbox/assoc-in??

21:23 lazybot: clojurebot: What are you, crazy? Of course not!

21:23 clojurebot: Pardon?

21:23 gfredericks: lol

21:24 TEttinger: emaczen, so ideally you'd make changes immutably whenever possible, passing the whole immutable map storing everything from one fn to the next. (this is a reference, so you aren't copying a big map every time you return it)

21:25 emaczen: TEttinger: Thanks, this should get me far.

21:25 TEttinger: play-clj has an interesting approach that has certain fns return a big list of "entities" and when they do it updates the map of entities internally in an atom that isn't externally visible

21:26 gfredericks: I bet you could get infix arithmetic in cljs by extending IFn to Number

21:26 TEttinger: so it has the advantage of your entities being up-to-date whenever you call one of those fns

21:27 gfredericks, see if you can, this could be very good or very bad

21:27 gfredericks: I can't remember how to use cljs anymore

21:38 emaczen: TEttinger: To be clear, so far I have defined a central atom which points to a map and so far each entry is a vector -- what do you think? Did I comprehend correctly?

21:41 TEttinger: emaczen, its organization really depends on your game

21:43 emaczen: TEttinger: As long as I got the overall theme (an atom containing immutable datastructures) I am happy at the moment

21:44 TEttinger: cool

21:44 that's just about it yeah

21:46 there's a big advantage if you only have the core data structures like maps, sets, seqs/lists, and vectors -- you can pr-str the whole value of the atom like (pr-str @central) to get a simple, re-readable version of central that you can write to a file and read back

21:46 emaczen: pr-str? (doc pr-str) isn't too helpful to me either

21:47 TEttinger: ,@central

21:47 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: central in this context, compiling:(NO_SOURCE_PATH:0:0)>

21:47 TEttinger: ,(def central (atom {}))

21:47 clojurebot: #'sandbox/central

21:47 TEttinger: ,(swap! central assoc-in [:player1 :hand 0] [:clubs 10])

21:47 clojurebot: {:player1 {:hand {0 [:clubs 10]}}}

21:47 TEttinger: ,(pr-str @central)

21:47 clojurebot: "{:player1 {:hand {0 [:clubs 10]}}}"

21:47 TEttinger: now here it gets cool

21:48 that string could be written to a file like (spit "mysave.sav" (pr-str @central))

21:48 (doc spit)

21:48 clojurebot: "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer."

21:48 TEttinger: then read back with (slurp mysave.sav)

21:49 emaczen: What's so cool about that? I'm pretty sure I have done that with python?

21:49 fading: emaczen: might want to look at http://www.chris-granger.com/2012/12/11/anatomy-of-a-knockout/ for how he designed game for clojurescript?

21:49 TEttinger: ,(def that-str "{:player1 {:hand {0 [:clubs 10]}}}")

21:49 clojurebot: #'sandbox/that-str

21:49 TEttinger: ,(eval (read-str that-str))

21:49 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: read-str in this context, compiling:(NO_SOURCE_PATH:0:0)>

21:49 TEttinger: ,(eval (read-string that-str))

21:49 clojurebot: {:player1 {:hand {0 [:clubs 10]}}}

21:50 TEttinger: and there it is fully loaded with no dependencies on pickling libs or anything

21:50 gfredericks: no need for eval eh?

21:50 TEttinger: err

21:50 ,(read-string that-str)

21:50 clojurebot: {:player1 {:hand {0 [:clubs 10]}}}

21:50 TEttinger: right

21:50 (inc gfredericks)

21:50 lazybot: ⇒ 119

21:53 gfredericks: ,(* 7 17)

21:53 clojurebot: 119

21:54 TEttinger: not prime

21:54 gfredericks: it's a semiprime I'm gonna use it for crypto

21:54 my public key is 119 everybody

21:54 TEttinger: heh

22:22 TimMc: That's crazy enough it just might work.

22:32 niac: (defn new-image

22:32 "Creates a new BufferedImage with the specified width and height.

22:32 Uses BufferedImage/TYPE_INT_ARGB format by default,

22:32 but also supports BufferedImage/TYPE_INT_RGB when alpha channel is not needed."

22:32 (^java.awt.image.BufferedImage [width height]

22:32 (new-image width height true))

22:33 (^java.awt.image.BufferedImage [width height alpha?]

22:33 (if alpha?

22:33 (BufferedImage. (int width) (int height) BufferedImage/TYPE_INT_ARGB)

22:33 (BufferedImage. (int width) (int height) BufferedImage/TYPE_INT_RGB))))

22:33 what dose ^ for?

22:33 justin_smith: niac do not do that

22:33 use refheap or something

22:33 niac: sorry

22:33 justin_smith: ^ adds metadata

22:33 in this case it is a type hint

22:33 letting the clojure compiler create faster code

22:34 niac: justin_smith: type hint. i see

22:35 godd2: ,(defn str_len [^String s] (.length s))

22:35 clojurebot: #'sandbox/str_len

22:35 godd2: ,(str_len "hello")

22:35 clojurebot: 5

22:36 godd2: otherwise you'd just do str_len [s] and let clojure divine that you always send s string

22:36 a string*

22:36 justin_smith: godd2: kind of similar, but in niac's example it is declaring the type returned

22:37 which may even be redundant in that case, since statically you can know every arity returns the result of a call to that constructor

22:37 but maybe clojure isn't smart enough to derive such things

22:37 gfredericks: yeah I doubt it

22:37 godd2: they might have turned on warn-on-reflection and went around type-hinting until it stopped yelling at them

22:38 justin_smith: godd2: in that case you would type hint args, not return values surely?

22:39 godd2: No clue. I don't have as much nitty-gritty knowledge on the matter

Logging service provided by n01se.net