#clojure logs

2012-07-28

00:02teurastajaif i dont know java, should i learn it before learning clojure? i know scheme
00:04emezesketeurastaja: Knowing some java basics will probably make your life easier
00:06arohner_let's say you have a datastructure, that's a (ref {}). In general, you do you write defns that take the ref, or the deref'd map?
00:06teurastajawhat features does someone who uses clojure and doesnt know java misses
00:06teurastaja?
00:07arohnerteurastaja: don't bother "learning" java. Just write what you want to write, and learn java lazily
00:08emezesketeurastaja: Well, for one thing, the error messages you will get from the clojure compiler are just java stack traces
00:08teurastajacan one write a metacircular interpreter in clojure alone?
00:08arohneryes
00:09teurastajadoes it have continuations?
00:09teurastajacan it do systems programming?
00:10arohnerno
00:10teurastajano for which?
00:10arohnerboth, on the JVM
00:11arohneryou can use JNA or JNI to load and call C libraries, but it wouldn't be useful for embedded systems, or interrupt handling
00:11teurastajaso what are clojures strengths
00:11teurastaja?
00:11arohnerIt's a practical lisp
00:12arohnera lot of people use it for web stuff, and map reduce kinds of things
00:13arohnerand it's good anywhere you'd use java, python or ruby
00:14teurastajaclojure vs common lisp vs scheme...?
00:16arohnerclojure has much better multi-threading support. The UI bindings are good enough. It can be trivially embedded in any existing java program
00:16arohnerprobably bigger community at this point
00:19arohneryou get to use JVM web servers and JVM DB drivers, so you can 'steal' from existing java libs when needed
00:20teurastajajava is not really an argument for me but its goode to know
00:21teurastajawhat networking protocols does it support?
00:22Raynes*
00:23emezesketeurastaja: You want an exhaustive list?
00:24arohnerjava is good in the sense that there's usually an available library for interacting with the outside world. If you're just going to be doing project euler, then yeah, you probably don't need it
00:27teurastajajust want to be sold clojure so i know if its good for me
00:28arohnerwhat are you looking to do with it?
00:34teurastajathings i cant do easily with scheme
00:34teurastajai dont know exactly
00:58RaynesIf you can't easily do something in Scheme, it's usually related to there not being a library for it.
02:15jestinepaulWhy is my membership to clojure-dev google group still pending? I have already sent my CA last week.
10:17xumingmingvI know that there is a function named assoc-in to put something into a nested structure
10:17xumingmingvwhy there is no corresponding function to remove something from the nested structure?
10:18xumingmingvuser=> (swap! x assoc-in [:handlers :lst 0] "hello")
10:18xumingmingv{:handlers {:lst ["hello"]}}
10:18xumingmingvhow do i remove the "hello" I just assoc-ined?
10:20uvtcxumingmingv: dissoc
10:20xumingmingvuvtc: I'd expect there is a dissoc-in
10:20xumingmingvbut apparently there is no dissoc-in in clojure.core
10:22uvtcThe clojuredocs for dissoc mention a dissoc-in in the legacy monolithic contrib... Is that now somewhere in the current contrib libs?
10:24xumingmingvjust found the update-in, seems that's what I want
10:24xumingmingvmaybe just because update-in is more useful than dissoc-in
11:11bordatouecould anyone tell me how to change a value of a variable within a loop , for example maininting a running total of sequence
11:13augustlbordatoue: pass it as an argument
11:13augustl(recur (inc i))
11:14bordatoueis there any other option without using recur
11:15augustlbordatoue: what's wrong with recur?
11:15uvtcbordatoue: what in particular are you trying to do?
11:16bordatoueuvtc: augustl i want to konw if this possible using doseq
11:16augustlbordatoue: not that I'm aware, just recur it I guess :)
11:17uvtcbordatoue: If what's possible using doseq?
11:17bordatoueso what is purpose of doseq,
11:17clojurebotdoseq is like for, but for side effects instead of values
11:18bordatoueokay, in py- for i in range(10): print i, i+10, i+=i , how do i do this in clojure using doseq
11:18bordatouenot recur
11:18rlbbordatoue: say you want a program that prints the integers, increasing, one per line -- doseq might be useful.
11:18augustlbordatoue: why do you have to use doseq?
11:18augustlbordatoue: you can use a ref or an atom or whatever, but that seems like a very bad idea
11:18bordatouebecause doseq is like for ,
11:19augustlbut you can't do what you want to do with doseq
11:19xumingmingvwe cannt remove an item from the middle of a vector or list, right?
11:19rlb(doseq [x (range)] (prn x))
11:19uvtc&(doseq [i (range 10)] (let [j (+ i 10)] (println i j)))
11:19lazybot⇒ 0 10 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 nil
11:20uvtcbordatoue: ^^
11:20bordatoueuvtc: , would you be able to add the new value to i in your example using doseq
11:21bordatouei+=i+10
11:21bordatouei+=10
11:21uvtcOh, right, you want to keep a running total.
11:21bordatoueyes,
11:21bordatouei want to chang the binding within a loop
11:22bordatouewihtout using recur
11:22augustlbordatoue: why is that?
11:22bordatoueaugustl: swap function
11:22rlbbordatoue: are you saying "can I write a C style for loop in clojure"? If so, then no, not easily.
11:22rlb(and not efficiently)
11:22bordatoueif x>y then x=y
11:23rlbbordatoue: but there are other ways to accomplish whatever you're trying to do.
11:23bordatouerlb: can you find a sloution using doseq
11:23bordatoueand let
11:23craigbrohola
11:24bordatouerlb would you be able to find a max of a given range of number using doseq not using recur or max fn
11:24thorwilbordatoue: (min x y) ?
11:24rlbbordatoue: loop/recur *is* clojure's closest analog to for.
11:24rlb(C-style for)
11:24rlbdoseq is not
11:24bordatouerlb: in that case , when should we use doseq
11:24augustlbordatoue: doseq is for doing side effects on sequences
11:24augustlsuch as calling methods on java objects
11:25rlbbordatoue: whenever you want to traverse a sequence and produce side-effects.
11:25craigbroand not return anything?
11:25rlb(as the docs say)
11:25rlbRight
11:25craigbrolike printing a list of strings
11:25uvtcbordatoue: you might be looking for `reduce`.
11:25bordatouerlb: okay , then why can't you find max of a given range of numbers using doseq
11:25craigbrobut I don't care about the return value
11:26bordatoueuvtc: i don't want to use other fn
11:26ToxicFrogbordatoue: because it's the wrong tool for the job, and you're asking the wrong question.
11:26rlbbordatoue: the same reason you can't do it with prn?
11:26ToxicFrogIt's like asking "why can't I read a file using printf"
11:26craigbroboardatoue you could actually
11:26ToxicFrogcraigbro: don't give him ideas, it's going to be ugly
11:26bordatoueif doseq helps to iterate a sequence then all that is left to swap a values
11:27augustlbordatoue: you don't seem to understand what a side effect is
11:27craigbrobordatoue: you would use a atom
11:27bordatouecraigbro: can you provide an example , i
11:27augustlbordatoue: since you're promtly ignoring that part :)
11:27ToxicFrogbordatoue: doseq is for when you have a lazy sequence and you need to force it to be evaluated because generating the sequence involves side effects that you care about.
11:27bordatoueaugustl: i do know side effect, fn that are not pure
11:27ToxicFrogIt is not a general purpose iteration construction.
11:27rlbbordatoue: and technically, yes, you *could* do it in clojure with an atom or simlar, but that would be "the wrong way" (and inefficient).
11:28rlbi.e doseq + let + atoms
11:28augustlbordatoue: here's an example of doseq https://www.refheap.com/paste/3855
11:28craigbrobordatue: yah, let to bind an atom to a variable, and then inside your doseq you reference the atom and swap! the new max in
11:28craigbrobordatoue: but that's shitty
11:29rlbIt's a complete misuse of clojure -- like using a file for the same purpose in C.
11:29craigbrobordatoue: specifically, you end up with alot of overhead for accessing the atom value and swapping the new value in
11:29rlbthough it you're just interested in it for academic purposes, then yes, it'll work.
11:30bordatoueso if you are given a sequence and what to iterate it , then doseq isn't the right tool
11:30augustlscroll up ;)
11:30craigbrobordatue depends on the type of iteration you want, and what you want out of the iteration
11:31craigbrobordatoue: think of it like the old saying that eskimos have a hundred words for snow
11:31bordatoueaugustl: i saw it , but is it wrong to do soemething like doseq [x (range 10)]
11:31craigbrobordatoue: lisps, have a half dozen ways to process a list.
11:31craigbrobordatoue: and the differences appeart sublte and unimportant at first
11:32augustlbordatoue: that's ok, if you're calling functions that have side effects and pass in x
11:32bordatoueso every time we are given a seq then it is loop and recur we need to use
11:33craigbrobordatoue: not really. you can use map, filter, reduce, select, doseq, or a loop/recur, just for starters
11:33rlbbordatoue: no, you'll probably more often want map/reduce/filter/etc.
11:33rlbbordatoue: or for.
11:33bordatouei thought loop and recur should be rarely used as there are HOF functions
11:33craigbrobordatoue: hmm, never heard of that opinion before
11:34augustlHOF = higher order functions?
11:34rlbbordatoue: you can often use the other functions, but you'll still be using loop/recur reasonably often -- of course, depends on what you're doing.
11:34augustlI've never used them I think :)
11:35craigbrobordatoue: it might be helpful to think of these as tools for transofrming a list, or reducing a list
11:36rlb...and I would be surprised if loop/recur is more common at first, for anyone coming from more strictly imperative languages.
11:36rlbs/would/wouldn't/
11:37rlbbordatoue: often you can recast your problem to use the other functions (i.e. max. min, etc.)
11:37bordatoue(let [x 10] ... (let [x (+ x 10)] ...)) ,can anyone explain what happens with the stack allocation
11:37bordatouebasciall i have got one outer let with binding to x and inner let with binding to x
11:38craigbroin my 15k+ line app, loop is used 5 times
11:38craigbroand most of those are in code I have for walking tree-zipper data structures
11:38craigbroa naturaly "recursive" task
11:38bordatouei just want to know if x ref to same object
11:38rlbbordatoue: no
11:38rlbbordatoue: the inner binding shadows the outer one.
11:38craigbroinner will shadow outer in the code that is lexically (typographically) inside the inner let
11:39craigbrothey will not point to the same object
11:40craigbroalso, letting something is not the same as saying "push this value onto the stack and let me refer to it as x"
11:40ToxicFrogYeah, I have yet to use loop or recur at all
11:40rlb...and the system is welcome to gc the outer bits iff they're no longer reachable, but I have no idea what clojure actualy does, implementation-wise wrt to that.
11:40craigbroin some lisp implementations it is close to that tho
11:40bordatouecraigbro: what happens during letting
11:43rlbbordatoue: conceptually, the inner x and the outer x are two different variables/names, bound to two different values.
11:43bordatouethanks
11:43rlbcode can only see the "nearest" binding
11:45bordatoueso if you are given a seq what is best way to iterate them lazily without using take,loop,first,rest,map,reduce,
11:45ToxicFrog...why would you want to avoid using those?
11:46craigbrosorry, network bounce
11:46bordatouei just want to know if it is possible to write a fn that would return a max of value in a given seq without using any high order funtions or loop and recur , also atom . just using let and doseq
11:47antares_bordatoue: for but I see no reasons to avoid take, map, filter, reduce and so on
11:47bordatoueofcourse no max or min
11:47craigbrobordatoue: sure, you can use doseq, and an atom
11:47bordatoueantares_: this is just for understanding what can be done with the language ,
11:47craigbrobordatoue: an atom is a way to have mutable state in clojure
11:48craigbrobordatoue: avoiding HOFs in a lisp is not advised 8)
11:48rlbbordatoue: are you allowed to use fn?
11:48bordatoueso craigbro, what happens during atom operation does it use CAS
11:48craigbroCAS?
11:48clojurebotparedit screencast is http://p.hagelb.org/paredit-screencast.html
11:48bordatouerlb: that is good way, acutally you could pass it as an argument
11:49bordatoueCAS compare and swap
11:49craigbrorlb: I end up doing that with macros alot, when I want a macro that binds a bunch of helper variables
11:49rlbbordatoue: and loop/recur is (more or less) just syntactic sugar for recursion (i.e. recursive fn calls).
11:49craigbrobordatoue: the atom itself doesn't give a fuck, but yah, you could compare and swap
11:49craigbroan atom is just a box
11:49bordatouebut jvm does not do a Tail call optims
11:49craigbroloop/recur handles that for you
11:50bordatoueis atom just a box like the var
11:50ToxicFrogbordatoue: no, but the clojure compiler does (by translating it into forms that the JVM can process in constant stack space)
11:50rlbbut no, doeseq has *no way* to preserve state across sequence elements
11:50craigbrolike a var, but you can change it, and the ways you change it handle synchronization and all that
11:51rlbbordatoue: doseq *can not do it*, by itself
11:51craigbrohttp://clojure.org/Atoms
11:51rlb(since you said "no atoms" above)
11:52bordatoueokay thanks everybody, very informative
11:52craigbrosocratic method!
11:54uvtcI wonder why clojurebot pointed out that paredit screencast above...
11:54uvtcCAS?
11:54clojurebotparedit screencast is http://p.hagelb.org/paredit-screencast.html
11:54uvtcHm.
11:54craigbroSCREE
11:54craigbroSCREE?
11:54clojurebotparedit screencast is http://p.hagelb.org/paredit-screencast.html
11:54craigbroPARE?
11:54clojurebotparedit tutorial is http://p.hagelb.org/paredit-outline
11:54craigbroOUTLINE?
11:54craigbroweird
11:54uvtcDidn't know about those pages. Nice.
11:55duck1123that's why clojurebot told you, he knew you hadn't seen the paredit screencase
11:55uvtcThe uncanny clojurebot.
11:58casionis there a page that has a list of common algorithms and/or tasks in clojure?
11:58casioni know of rossetta code, anything elsse?
12:01uvtcA cookbook, perhaps?
12:01uvtccasion: Maybe some at http://en.wikibooks.org/wiki/Clojure_Programming#Cookbook.
12:02_zachIs there a core fn that can convert a map of the form {index val} into a seq/vec where index corresponds to the index of the val in the new seq?
12:03casionuvtc: most othe stuff there is beyond me atm, but thank you :)
12:03_zachsuch that {0 :x 1 :y 3 :z} => (:x :y nil :z)
12:05rlbcasion: for educational purposes, clojures own code for various operations can also be helpful.
12:05rlbs/clojures/clojure's/
12:06rlbcasion: and if you haven't seen them, there are links to the source in the documentation.
12:06tmciver,(vals {0 :x 1 :y 3 :z}) ; _zach
12:06clojurebot(:x :y :z)
12:06tmcivernope, but close
12:06casionthanks rlb
12:06_zachtmciver: indeed, thanks
12:07uvtc_zach: Hm.. You might first start with `(vals m)` ...
12:07rlbi.e. http://clojuredocs.org/clojure_core/clojure.core/reverse#source
12:07uvtcOh, wait. `map-indexd`.
12:08_zachuvtc: I think I have something figured out. I'll post my solution in a second.
12:08_zachthere's likely a nicer way.
12:08uvtc&(map-indexed (fn [idx entry] [idx (val entry)]) {:a "aa" :b "bb" :c "cc"})
12:08lazybot⇒ ([0 "aa"] [1 "cc"] [2 "bb"])
12:09uvtc_zach: er, though maybe I didn't read your question carefully enough.
12:10_zachuvtc: :) I have a map where index => val
12:10_zachso {3 :d 2 :c 0 :a 1 :b} should become (:a :b :c :d)
12:11uvtc_zach: Ok, so you want `(vals m)`, but you want them sorted by their keys in `m`.
12:11_zachuvtc: Exactly.
12:12Bronsauser=> (vals (into (sorted-map) {3 :d 2 :c 0 :a}))
12:12Bronsa(:a :c :d)
12:12tmciver_zach: but you also want indexes missing from the map to be represented as nil in the ouput, right?
12:12_zachtmciver: Yes.
12:17uvtc&(for [e (sort (fn [a b] (compare (a 0) (b 0))) (seq {3 :d 2 :c 0 :a 1 :b}))] (e 1))
12:17lazybot⇒ (:a :b :c :d)
12:17uvtc_zach: ^^
12:17uvtcSo, take a seq of the map to turn it into a list of entries,
12:17Guest82661where do I find a core.logic binary(jar?) published? Sonatype or something?
12:17uvtcthen sort those entries by their keys,
12:18mich2here do I find a core.logic binary(jar?) published? Sonatype or something?
12:18uvtc_zach: and finally use `for` to just take the 2nd item of each entry.
12:18_zachuvtc: Thank you for this solution. I think Bronsa had another one as well, which is (vals (into (sorted-map) {3 :d 2 :c 0 :a 1 :b}))
12:19Bronsa,(#(vals (into (into (sorted-map) (map vector (range (inc (reduce max (keys %)))) (repeat nil))) %)) {0 0 3 3 1 1})
12:19clojurebot(0 1 nil 3)
12:19Bronsathis way you get also missing keys
12:19_zachBronsa: Awesome!
12:19BronsaI'm sure it can be done better but this is the first way that came to my mind
12:19_zachBronsa: Thank you for your help. uvtc as well.
12:20uvtc_zach: Ah, missed that. ... Oooh, Bronsa's is nicer. :)
12:28tmciver_zach: here's another for good measure: ##(take 5 (map {0 :x 1 :y 3 :z} (range)))
12:28lazybot⇒ (:x :y nil :z nil)
12:29alex_baranoskyI'm trying to connect to clojure jack in, via M-x clojure-jack-in -- I have a project.clj file that I can use fine from lein repl. However when I try to use clojure-jack-in from Emacs it just says: "Starting swank server…" (and nothing else happens)
12:29_zachtmciver: I was just writing that same thing :). Thanks!
12:30alex_baranoskyany ideas what might be the issue?
12:31duck1123alex_baranosky: if you check the hidden buffers, there's probably one that has the output of the jack-in call
12:31tmciveralex_baranosky: I get that problem after I kill a previously running swank.
12:32duck1123M-x slime-selector c (I think)
12:38alex_baranoskyhmmm… my *swank* buffer had this message in it: "Process swank exited abnormally with code 127
12:38alex_baranoskyzsh:1: command not found: lein"
12:39lnostdalhi, (class (Long. (int 261))) ==> java.lang.Long but (class (Long. (Integer. 261))) ===> No matching ctor found for class java.lang.Long what's going on here?
12:40alex_baranoskyI just reproduced it -- every time I redo M-x clojure-jack-in it is giving me an extra entry in the *swank* buffer
12:43alex_baranoskyI think I've found the issue: Emacs isn't configured to get my PATH from my .zshrc
12:43alex_baranoskyhttp://stackoverflow.com/questions/9435019/how-do-i-source-my-zshrc-within-emacs
12:44duck1123I hate emacs on osx due to the path issues
12:45uvtcduck1123: I'm not crazy about the issue there with having that extra Command/Clover key...
12:45duck1123I don't think I ever got my path quite right. I ended up just setting up a vm
12:46duck1123I use a MBP, but I run my emacs over SSH forwarding from my linux server. I can't tell you how many times I've gone to copy, and closed the entire window
13:01xumingmingvI want to develop a producer-consumer queue, if use java, I will use ConcurrentLinkedQueue, how to do it in clojure?
13:08xumingmingvhttp://stackoverflow.com/questions/11703024/producer-consumer-queue-in-clojure
13:22antares_xumingmingv: typically some queue implementation from j.u.c. is sufficient. Consumer can just loop and take/remove/poll items in a separate thread.
13:23xumingmingvis it possible to implement it in pure clojure way?
13:24xumingmingv...because clojure is claimed to be very good at concurrency programming, dont know if i understand it correctly? antares_
13:25antares_xumingmingv: it is possible to implement a lot of things in just Clojure, but why would you reinvent j.u.c. queue implementations?
13:25antares_there are not that many ways in which you can improve them
13:26xumingmingvantares_: my intension is not to beat j.u.c
13:26antares_if you insist on having a Clojure version, use an atom that stores a collection. Appending items to it is as straightforward as (swap! an-atom conj item)
13:27antares_consuming correctly is a bit trickier but also will use swap! and sequence/collection operations
13:29xumingmingvyeah, this is what in mind now(use atom, swap!), but if multiple threads producing/consuming the messages concurrently
13:29xumingmingvthen I need to use ref and dosync
13:29antares_xumingmingv: why?
13:29antares_atom is atomic reference
13:29antares_it is pretty hard to be safer than that
13:30xumingmingvoh, maybe I didnt really understand atom, let me learn it again |o|
13:31antares_for just one identity (like a queue), using a ref over an atom makes no sense. It will work the same way but carry more overhead.
13:32xumingmingvso it is safe to have multiple threads adding/removing from the collection in a atom?
13:32xumingmingvconcurrently
13:34devn"Changes to atoms are always free of race conditions."
13:34xumingmingvbut the performance is bad, right? because the swap! use compare-and-set, so technically the producer and consumer cannt adding/removing items from the atom at the same time
13:40duck1123xumingmingv: this is probably not what you're looking for, but have you looked at lamina?
13:41xumingmingvthanks duck1123 devn antares_
13:41devnxumingmingv: the comment on your SO post is worth looking into -- clojure.lang.PersistentQueue
13:44devnxumingmingv: maybe you do want a ref... hm...
13:44xumingmingvdevn, how to solve this concrete problem is not really my biggest concern
13:44xumingmingvduck1123, devn: I think what I'm really confused is that: clojure is claimed to be good at concurrency programming, but for this producer-consumer case we need to looking java for help
13:45duck1123I think it's less that you *need* to look to clojure, but rather that java already has it covered
13:45duck1123look to java
13:46antares_xumingmingv: Clojure makes concurrency easier where Java itself does not. Clojure was designed to be a symbiotic/hosted language. Why reinvent concurrent queues if there is already several implementations in the JDK?
13:48devnxumingmingv: clojure.lang.PersistentQueue is a clojure thing.
13:52xumingmingvthanks all, maybe I just too focused on solve problems using pure clojure
13:53devnxumingmingv: clojure.lang.PersistentQueue is "pure" clojure.
13:53devnit also used to be implemented using ConcurrentLinkedQueue
13:53xumingmingvdevn: haha I will take at look at it
13:55devnnow i feel bad -- i am now thinking he probably shouldn't use persistentqueue :\
13:58craigbrohaha
14:36ToxicFrogdevn: it kind of feels like you could implement reader/writer architectures in clojure without needing a shared queue at all, to me
14:36ToxicFrogAnd possibly should
15:27michaelr525good evening!
15:47cldwalkerhi all, anyone know of a parser for maven-metadata.xml? if not I was just going to do it with clojure.xml/parse
15:50cldwalker_ato: this is for showing clojar dependencies, thoughts?
15:52FrozenlockAmazing to see how the channel is slower on weekends
15:52Frozenlockin/on weekends?
16:09cldwalkernevermind, found org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader
16:47KyleBrodiehola clojurians
16:47duck1123hello
16:48KyleBrodiehows it going?
16:48duck1123pretty good, you?
16:48KyleBrodiealright. are you an experienced clojurian?
17:18duck1123I've been using clojure for a couple years. There are certainly better than me. Did you have a question?
17:30dsantiagoDoes clojurescript support clojure's (.fieldname myrecord) access style on defrecords?
17:45hiredmandsantiago: (.-
17:46dsantiagoAh.
19:40prestoIs there a way of introducing a local binding without having to use it in a new scope (IOW: introducing a binding in the current scope)? For instance: (let a 1) so I can use 'a' in the next statements instead of inside the 'let' form.
19:41prestoAlso: would this be a good idea? Why?
19:44antares_,(let [a 1 b a] b)
19:44clojurebot1
19:44antares_presto: if I understand your question correctly, that is very common
19:45antares_but you can only use locals inside a scope created with let, if-let, with-open and so on
19:45prestoantares_, not quite. I mean something like (let a 1) a ; return 1
19:45prestoAs you would do in Javascript, for instance. var a = 1; a;
19:46brainproxypresto: how about def
19:46brainproxy(def a 1)
19:46prestobrainproxy, def introduces the binding in the whole thread, as far as I know, not only in the current scope.
19:46brainproxyoh sorry, didn't read your question carefully enough
19:47antares_presto: no necessarily the whole thread but namespace, yes
19:47prestoI mean, using (let [?] ?) is no big deal, but I guess that it would be easier to teach (and sometimes visually), if it would have some parallel with other dynamic languages, where doing a simple "a = b; b" would suffice.
19:47prestoantares_, oh ok.
19:47antares_presto: that's what let does
19:47antares_and let-like forms
19:48brainproxy(let [a b] (...) (...) )
19:48prestoantares_, indeed, but you have to use the bindings *inside* the let form. That's my point.
19:48antares_presto: yes and that is by design
19:49antares_you can have the entire function body to be a let statement, there is nothing wrong with that
19:50prestoantares_, sure, I do get that.
19:50prestoMy point is that it is still one level deeper that it would be if let would introduce the bindings in the *current* scope, instead of creating a new one.
19:51prestoI'm not saying that it's wrong, by the way. :D
19:51gfrederickspresto: that kind of makes it more imperative than expression-based
19:51brainproxypresto: can you gist an example where let and def don't give you quite what you want?
19:51prestoJust that it would be simpler to teach someone as an introductory language if that was not the case.
19:51prestogfredericks, yes, I do agree with you there.
19:52gfrederickspresto: have you had trouble teaching programming-beginners non-imperative languages?
19:52antares_presto: in that case you would have a lot more unexpected side effects (well, shadowing)
19:52prestobrainproxy, they both do. My point is not about functionality. Just about how it looks for a beginner.
19:53antares_which is not unheard of in JavaScript, for example, where scoping is one of the most common sources of issues
19:55prestogfredericks, well, yes, and imperative ones as well. But I'm not a teacher anyway, I probably suck at explaining things. :D
19:56brainproxypresto: okay, i think i get it, you're suggesting that it may seem complicated to a beginner to have to introduce/nest a let statement in order to create a binding
19:56antares_it would be a serious disservice to beginners
19:56antares_it would be convenient for the first 3 days
19:56antares_then they would start hitting the same issues as in JavaScript
19:56casion`so with a condp, you have an expression, then if the expression matches one of the values... the subsequent predicate is returned immediately, correct?
19:56brainproxyyeah, have to agree, coming from a few years of javascript
19:57casion`no concept of break; it just returns the predicate?
19:57casion`and goes to the next expresssion?
19:58antares_explicit scoping is not "right" but it does discipline and protect you from many issues that have nothing to do with your problem's complexity
19:58antares_casion`: yes, "first match wins"
19:59prestoantares_, Javascript do have issues, but I think you're referring to some specific one that is related to binding values, right?
19:59casion`what's the difference with (cond _ _) then?
19:59prestoantares_, like forgetting to use "var"?
19:59antares_yes, that kind of issues, implicit scoping
19:59brainproxyyes, particularly inside of a function definition
19:59brainproxyif you're reusing a var name
20:00brainproxybut your intent is actually to shadow
20:00prestoI see, well I'm doing only javascript nowadays (more than one year), I don't remember having binding issues but I'm using a javascript compiler, which do catch errors. So I guess I'm not the common case...
20:01casion`condp seems like a simple switch with implicit breaks, I get that (I assume I do)... what would the C equivalent of cond be then?
20:01gfrederickspresto: I find clojure's let much easier to reason about than anything imperative
20:02prestogfredericks, yes, I also don't see any problem reasoning with let forms.
20:02prestoI guess what I'm saying is...
20:02prestoIf there was a kind of let form that would introduce a binding in the *current* scope, I would probably use it sometimes.
20:03gfredericksand most clojure users would get angry at anyone who used it
20:04prestoYes, it's not Clojure-y. :D Not even Lispy I think.
20:05prestoAnyway? I was just wondering if I was missing something. Thank you guys.
20:05gfrederickscasion`: I don't think condp is like anything in C; nor cond; case is probably pretty similar to what you're describing
20:05casion`gfredericks: gah, why can't this shit all be like C :P
20:06gfrederickscuz then we wouldn't have much reason to use it
20:06hyPiRioncasion`: condp would be like, hmm
20:06casion`someone should make C-lojure
20:06casion`gfredericks: yeah, well I'm learning this sspecifically because it's nothing like what I'm used to
20:06casion`still frustrating at times
20:06hyPiRion(cond expr1 stat1 expr2 stat2 expr3 stat3 ...) -> if (expr1) {stat1} else if (expr2) {stat2} else if ....
20:07gfrederickscasion`: I've been using clojure for years and have never once used condp and didn't know what it did
20:07hyPiRionOh wait, condp.
20:07casion`hyPiRion: I'm getting a bit lost in the differenc between cond and condp
20:08hyPiRion&(doc condp)
20:08lazybot⇒ "Macro ([pred expr & clauses]); Takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either: test-expr result-expr test-expr :>> result-fn Note :>> is an ordinary keyword. For each clause, (pred test-expr expr) is evalu... https://www.refheap.com/paste/3861
20:08gfrederickscasion`: but I use cond all the time
20:08antares_casion`: cond matches on equality. condp lets you decide what to use to match.
20:09antares_casion`: also, everything in Clojure is an expression while in C it is usually the opposite. I think you want cond, not condp.
20:09hyPiRionantares_: cond isn't matching on equality, I think you're talking about case.
20:09gfredericksthat :>> thing is a little ugly; I hadn't ever seen that before
20:09antares_err
20:10casion`ok ok
20:10casion`I think maybe I get it?
20:10casion`condp is an expression, followed by value predicate pairs, if the value matches the expression the predicate is returned
20:10antares_hyPiRion: more or less, I was talking about cond but did not explain it correctly
20:11antares_case is used even more often than cond
20:11casion`cond is just expresssion predicate pairs
20:11hyPiRioncasion`: It's probably best with examples, I'll give you the cdoc examples in a second.
20:11casion`hyPiRion: ok thank you
20:12antares_casion`: so yes, you probably want case. cond is a nice way to avoid some if … elseif … elseif kind of code.
20:13casion`antares_: it's not so much of what I want, I'm just learning atm
20:13hyPiRioncasion`: https://www.refheap.com/paste/3862
20:13casion`going through code and referencing
20:14casion`what is :>>
20:14casion`I haven't come across that yet
20:15antares_just a keyword
20:15antares_it could be :joe
20:15antares_or :rightright
20:15antares_this example seems to be from http://clojuredocs.org/clojure_core/clojure.core/condp
20:16casion`ah
20:16hyPiRioncasion`: Think of it like this: :>> means that you're using a function on the value given instead of a value to return.
20:16casion`the second example there was confusing me for a second
20:18hyPiRionso for instance, (condp even? n true (inc n) false (dec n)) would be the same as (condp even? n true :>> inc false :>> dec)
20:19casion`hmm
20:19antares_I am afraid that's even more confusing :)
20:19casion`I understand, but I also don't
20:19casion`:>> is just a normal keyword?
20:19hyPiRionYeah
20:19casion`I don't get how :keyword form works there?
20:20casion`or am I confused even more than I think
20:20antares_casion`: don't worry about it, I think case and cond are what you really need to understand to work with Clojure, condp is rarely used
20:20hyPiRionI would recommend you to do the following: Ignore the :>> usage and use the "standard" way of using condp
20:21casion`will I be encoutnering that syntax elsewhere?
20:21hyPiRionNot as far as I know.
20:21casion`the :>> inc instead of say (inc n)
20:22hyPiRionI don't believe so, casion`.
20:22gfrederickscasion`: the :>> only distinguishes the ternary case from the binary case; you should, though, get used to seeing functions referenced without being called
20:22gfredericksthat is the nature of a functional language
20:23casion`gfredericks: I believe I understand that
20:23casion`but I don't get why :>> inc does anything?
20:23gfredericks:>> is specific to condp
20:24gfredericksthe fact that it's used that way is very peculiar in clojure; I've never seen it anywhere else
20:25gfredericksanywhere else in clojure I mean
20:25gfredericks(not "in any other language")
20:27casion`I'm stuck on it saying "Note :>> is an ordinary keyword."
20:27casion`I understand what it is doing
20:27gfredericksit probably has the note there because that usage is so weird that nobody would expect it
20:28gfrederickscasion`: do you know what a keyword is?
20:28casion`gfredericks: I thought I did, but I'm doubting that now
20:28gfrederickscasion`: what do you think a keyword is?
20:29casion`a unique identifier for a value
20:29hyPiRiongfredericks: It's kind of interesting though, I don't understand how they figure out that it's the ternary case, and not the binary one.
20:30gfrederickshyPiRion: yeah since :>> is a function presumably it might be the binary case. I assume you just can't ever use :>> as a function; #(:>> %) if you really want to
20:30gfrederickscasion`: what other languages are you familiar with?
20:30Chousukecasion`: keywords are not identifiers in clojure. they are simply things that evaluate to themselves
20:31casion`gfredericks: C/asm (in a few contexts)
20:31Chousukeyou can use keywords as macro syntax for that reason
20:31gfredericksChousuke: no, you could use anything in macro syntax
20:31casion`gfredericks: I've done most entirely embedded development
20:31hyPiRionSo I don't understand which one is used here, for instance: https://www.refheap.com/paste/3863
20:31Chousukegfredericks: well, you could, but keywords are a good choice
20:31casion`clojure is my first functional language, or 'high level language'
20:31Chousukegfredericks: since then you won't be hijacking anything
20:32gfredericksChousuke: symbols are nicer
20:32gfredericksChousuke: you hijack any usage of the keyword as a function, which we discussed a couple minutes ago
20:33gfrederickscasion`: okay, well keywords are similar to strings, but they are used in contexts where the only thing you would care to do with them is compare them to other keywords (for equality); a lot of their uses is similar to enums in static languages
20:33Chousukeenums? hm :/
20:34Chousukethey are good for anything that needs a constant. map keys usually.
20:35casion`hmmm
20:35casion`trying to process this
20:35gfredericksthey are very good as map keys
20:35casion`keywords and guaranteed unique?
20:36casion`are*
20:36gfredericksnot sure what that means
20:36casion`a map
20:36gfredericks:foo and :foo are the same
20:36casion`udh, sorry
20:36casion`yes
20:36casion`my brain is overloading apparently.
20:36augustlstrings require string compare, symbols are memory address compares, so to speak
20:36augustlsince :foo and :foo points to the same memory
20:37gfredericksyes keywords compare in O(1) while strings compare in O(n)
20:37Chousukeyeah you can't have two keywords that are both :foo and not the same object
20:37gfredericks,(identical? :foo (keyword "foo"))
20:37clojurebottrue
20:37Chousukenot without some hideous hackery anyway
20:37hyPiRionwell, you do have ::
20:37hyPiRion,::foo
20:37clojurebot:sandbox/foo
20:37Chousukethat's different
20:38casion`so it's like a const pointer then?
20:38Chousuke:foo/bar is still ::foo/bar
20:38Chousuke:foo/bar :P
20:38Chousukedamn typos
20:38hyPiRion,::foo/bar
20:38clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Invalid token: ::foo/bar>
20:38casion`an identifier that always evaluates to the same address space?
20:38hyPiRionhah.
20:38Chousukecasion`: I'm not sure if it's an identifier. it's just an object
20:38casion`ok
20:38gfrederickscasion`: that's true, but it's an implementation detail; really keywords are like strings
20:39gfredericksthey are used in ways that you would not use strings in a low-level language because it wouldn't be efficient
20:39Chousukecasion`: and the semantics of keywords are such that iff a keyword has the same name as another, they are the same object
20:39casion`gfredericks: ok, that makes sense
20:40casion`you can compare keywords at runtime?
20:40gfredericksyep
20:40hyPiRionyes.
20:40gfredericks,(= :foo :bar)
20:40clojurebotfalse
20:40gfredericks,(= :baz :baz)
20:40clojurebottrue
20:40Chousukeyou can store keywords in data structures. they're just data.
20:41gfredericks,(= [:foo] (list :foo))
20:41clojurebottrue
20:41casion`,(= :right (keyword (str "ri" "ght")))
20:41clojurebottrue
20:41casion`mind bown
20:42Chousuke,(identical? :right (keyword "right"))
20:42clojurebottrue
20:42Chousukethat's the important thing
20:42gfrederickscasion`: those things are all true of strings as well; just not the identical? part
20:42Chousukethey're the same object.
20:42gfrederickseverything that keywords are used for in clojure strings could be used as well, just a little slower
20:42Chousukethey use java interned strings internally :P
20:42casion`that is amazing to me haha
20:44augustlare keywords GC-ed? In Ruby, the equivalent (symbols) aren't.
20:44augustlso if you keywordize strings from user input that's a nice way to run out of memory
20:44casion`so, back to condp, I assume the :>> keyword is just used by the macro?
20:45augustlsymbolize*
20:45gfrederickscasion`: yes it's a special case in the macro
20:45casion`is there a way to see how condp expands?
20:45gfredericks,(source condp)
20:45clojurebotSource not found
20:45gfrederickscasion`: yeah you can use macroexpand-1
20:45gfredericks&(source condp)
20:45lazybotjava.lang.RuntimeException: Unable to resolve symbol: source in this context
20:54hyPiRionMeh, condp is ambigous.
20:57casion`I can't find the source for it
20:58gfredericks&(clojure.repl/source condp)
20:58lazybot⇒ Source not found nil
20:58gfredericksbaaaah
20:59hyPiRion&(macroexpand-1 '(condp = foo baz bar spam egg))
20:59lazybot⇒ (clojure.core/let [pred__15215 = expr__15216 foo] (if (pred__15215 baz expr__15216) bar (if (pred__15215 spam expr__15216) egg (throw (java.lang.IllegalArgumentException. (clojure.core/str "No matching clause: " expr__15216))))))
20:59hyPiRion&(macroexpand-1 '(condp = foo baz :>> bar spam :>> egg))
20:59lazybot⇒ (clojure.core/let [pred__15225 = expr__15226 foo] (clojure.core/if-let [p__4925__auto__ (pred__15225 baz expr__15226)] (bar p__4925__auto__) (clojure.core/if-let [p__4925__auto__ (pred__15225 spam expr__15226)] (egg p__4925__auto__) (throw (java.lang.IllegalArgu... https://www.refheap.com/paste/3865
21:00hyPiRionThat's basically how it works.
21:00gfrederickshttp://clojuredocs.org/clojure_core/clojure.core/condp#source
21:02hyPiRionhm, so it's just :>> that's affected.
21:03gfredericksof course
21:03casion`hum
21:03hyPiRionI was thrown off by the "Note :>> is an ordinary keyword.
21:03casion`I get it now
21:03casion`awesome
21:03casion`you guys are awesome
21:04gfrederickshyPiRion: hah; yeah the whole thing is a mess
21:04gfredericks(inc you-guys)
21:04lazybot⇒ 1
21:05hyPiRionI find defn- and dec' messy as well. I mean, the heck.
21:05hyPiRion&(doc dec')
21:05lazybot⇒ "([x]); Returns a number one less than num. Supports arbitrary precision. See also: dec"
21:05ToxicFrog,(doc dec)
21:05clojurebot"([x]); Returns a number one less than num. Does not auto-promote longs, will throw on overflow. See also: dec'"
21:05ToxicFrogAah.
21:05gfrederickshyPiRion: eh; that's just performance stuff
21:05gfredericksdec' at least; not defn-
21:06hyPiRiongfredericks: it's the single quote in the name I'm a bit frightened at.
21:06gfredericksoh you don't like that being syntactically legal?
21:06hyPiRionWell, yeah.
21:07mattmossIt's just a name.
21:07mattmossMakes me think of calculus, where f was a function and "f-prime" or f' was the first derivative.
21:07ToxicFroghyPiRion: you don't like being able to write foo-prime as a name?
21:07_atocldwalker:
21:08gfredericksI use it all the time
21:08ToxicFrogmattmoss: pretty sure that is exactly how it is being used here
21:08mattmossGotcha.
21:08ToxicFrog' is a reasonable ascii approximation of the unicode prime symbol.
21:08hyPiRionWell.
21:08gfredericksToxicFrog: wat; you're saying dec' is the first derivative of dec?
21:08craigbroin H.S. only tho
21:08ToxicFroggfredericks: no; foo' has more applications that just derivatives
21:08hyPiRion&[(dec '1.0) (dec' 1.0)]
21:08lazybot⇒ [0.0 0.0]
21:09mattmossI've refrained from actually using myself, since I didn't see it mentioned in clojure book or other docs as being valid syntax... but maybe I didn't look hard enough.
21:09ToxicFroggenerally A' is just "sometime derived from or closely related to A"
21:09ToxicFrogIn calculus, by convention, this is a derivative.
21:09mattmossWhat ToxicFrog said.
21:09gfredericksToxicFrog: yes I read too much into your "that is exactly how it is being used here"
21:09_atocldwalker: yes just a using a plain XML parser is what I'd do. It's simple enough calling a dedicated maven parser would be overkill. I'm sure there's a class in Aether (which Clojars depends on) which does it, but it'd probably be more work trouble to figure out how to use it than just doing it yourself.
21:09ToxicFroggfredericks: yeah, sorry, that was ambiguous - I meant "it's being used as a prime symbol", not "it's being used as a derivative"
21:10ToxicFrogHmm
21:11ToxicFrogYeah, actually, according to the manual, dec' is not legal
21:11gfredericksthe manual?
21:11ToxicFrogWell, the reader reference on the website, http://clojure.org/reader
21:11ToxicFrog"Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, and ? (other characters will be allowed eventually, but not all macro characters have been determined)."
21:11mattmossToxicFrog: Yeah that.
21:12gfredericksit's old then
21:12mattmossUsing ' as part of identifier seems to work, but I've refrained from doing so because I hadn't found any reference that supported it.
21:12ToxicFrog,(defn f' [x] x) (f' 1)
21:12clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
21:12ToxicFrog&(defn f' [x] x) (f' 1)
21:12lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
21:12gfredericksmattmoss: rich hickey supports it
21:12ToxicFrogeat me lazybot
21:12hyPiRion&(let [f' (fn [x] x)] (f' 1))
21:12lazybot⇒ 1
21:12ToxicFrogThank you.
21:13mattmossgfredericks: That's good enough for me... just finding it in any doc/reference is lacking.
21:13ToxicFroggfredericks: yeah, but if it's not documented...
21:13gfredericksToxicFrog: it was documented verbally at the first clojure conj :)
21:13gfrederickshe said "Now you can put primes on your symbols"
21:13mattmossAh.
21:13ToxicFroggfredericks: word-of-mouth doesn't count as documentation :P
21:13hyPiRion&(let [!' (fn [x] x)] (!' 1))
21:13lazybot⇒ 1
21:14hyPiRion&(let ['! (fn [x] x)] ('! 1))
21:14lazybotjava.lang.Exception: Unsupported binding form: (quote !)
21:14hyPiRionSo the quote is a special case: Cannot occur at start of name.
21:14gfredericksToxicFrog: my point was it's not an accident
21:14hyPiRion/s/name/symbol
21:14ToxicFroggfredericks: yeah, I didn't expect it was, I'm just saying the docs need to be updated
21:14gfrederickshyPiRion: yes it has a different meaning at the start
21:15gfredericksclojure.org doesn't get a lot of compliments
21:15hyPiRion&(let [?'! (fn [x] x)] (?'! 1))
21:15lazybot⇒ 1
21:15hyPiRionWell, that's creative at least.
21:16gfredericks,'%foo
21:16clojurebot%foo
21:16gfredericks% is a fun one; can only be initial
21:16hyPiRionwhat.
21:16hyPiRion,'%%
21:16clojurebot%
21:17gfredericks,'[%%]
21:17clojurebot[% %]
21:17gfredericks%% just makes two of them
21:17hyPiRionWoah.
21:17hyPiRion,'[%''%]
21:17clojurebot[%'' %]
21:18gfredericksthe worst thing in the current reader that I know of is clojure.core//
21:18hyPiRionI don't like that one either, heh.
21:18gfredericks,(read-string "clojure.core//")
21:18clojurebotclojure.core//
21:18gfredericks,(read-string "something.else//")
21:18clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: something.else//>
21:19ToxicFrogwhat
21:19hyPiRionheh. It's the special case of the specials.
21:19mattmossObfucscated clojure?
21:19hyPiRionBut actually...
21:19hyPiRion&(let [/ *] (/ 2 3))
21:19lazybot⇒ 6
21:20hyPiRionAnd you can defn it too.
21:53howard_Hello Clojurians!
21:54howard_I have a question regarding using = to compare lists. Why does (def a 1) (= '(a) '(1)) return false?
21:55howard_however, (= [1] [a]) is true
21:55howard_:-(
21:56gert'(a) is a list with the symbol a
21:56gertthat's not equal to a list with the number 1
21:56howard_ok thanks
21:56howard_so does that mean a is not a symbol in [a]?
21:57gertthe difference is in using the quote ' character
21:57mattmoss,(= (list a) '(1))
21:57clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0)>
21:57mattmosssilly me
21:57gert(def a 1) (= (list a) (list 1))
21:57howard_aha!
21:57gertthat will work
21:57howard_thank you Matt and Gert
21:58gertno worries
21:58mattmoss,(let [a 1] '(a))
21:58clojurebot(a)
21:58howard_Now I will be more careful when using quote :D
21:58mattmoss,(let [a 1] [a])
21:58clojurebot[1]
21:59gert,(let [a 1] (list a))
21:59clojurebot(1)
21:59gertvoila :)
22:00gerthoward_: you could also say (def a 1) (= `(~a) `(1))
22:01gertif you really don't like to use "list"
22:01howard_i love everything Clojure
22:01howard_hehe..
22:06gfredericks,(let [a 1] `(~a))
22:06clojurebot(1)
22:08howard_let me try and see if this works..
22:08howard_,(slurp "/etc/hostname")
22:08clojurebot#<SecurityException java.lang.SecurityException: denied>
22:08howard_nope :D
22:09howard_,(print "ha")
22:09clojurebotha
22:10howard_,(loop [] (recur))
22:10howard_,(print "hehe")
22:10clojurebothehe
22:10hyPiRiontimeout.
22:10clojurebotExecution Timed Out
22:10howard_clever
22:13hyPiRion,set!
22:13clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: set! in this context, compiling:(NO_SOURCE_PATH:0)>
22:15gfredericks,(doc set!)
22:15clojurebotExcuse me?
22:18hyPiRionGurr. I want an immutable map to contain itself. Is there some trick to that?
22:19howard_,(do (declare b) (def b (atom {:b b})))
22:19clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
22:20howard_eh, it worked for me
22:21hyPiRiondeclare and def are scary.
22:21howard_:D
22:21gertit won't happen howard_. a service evaluating clojure forms, on the public internet, is really not going to be *that* insecure
22:22howard_also it is powered by Clojure
22:22hyPiRionHowever, it's not working properly. b doesn't contain itself.
22:22howard_i just realized that..
22:22gertat the time you're defining your atom, b is nil. So your atom holds {:b nil}
22:23gfrederickswhatever you guys do will end up being essentially not an immutable map anymore
22:23hyPiRiongert: b is unbound, actually.
22:23gertah yes, true
22:23howard_yeah... it's always unbound
22:23howard_let me try other ways
22:23hyPiRiongfredericks: That's sad, because there's nothing "illegal" pointing to itself. :(
22:24hyPiRionYou're not mutable if you do that.
22:24gfredericksit's not a finite value though
22:24hyPiRionNo, but neither is an infinite list.
22:24hyPiRionBoth are immutable.
22:27howard_,(do (declare a) (def a {:self (atom a) :data 7}) (:data (ref (:self a)))
22:27clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
22:27howard_,(do (declare a) (def a {:self (atom a) :data 7}) (:data (ref (:self a))))
22:27clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
22:28howard_the bot doesn't take atoms?
22:28hyPiRionYou can't def anything.
22:29howard_well i just found a way...
22:29howard_probably isn't exactly what you want
22:29hyPiRion,(condp #(get %2 %1) {:>> {:>> :>>}} :>> :>> :>>)
22:29clojurebot:>>
22:30howard_,(let [m (:self (fn [] m))] ((:self m)))
22:30clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: m in this context, compiling:(NO_SOURCE_PATH:0)>
22:30howard_eh..
22:30hyPiRionheh, you need to declare it, which is rather hard in a sandbox
22:30howard_put m into def
22:30howard_and it worked for me
22:30howard_you have a self included map by using function
22:32howard_(def m {:self (fn[] m) :data 7})
22:32howard_(:data ((:self m)))
22:32howard_that works
22:33howard_test color code
22:34hyPiRionCreative. I'll try and look for some core-hacky way of making it contain itself.
22:34howard_:D
22:34howard_good luck
22:35hyPiRionAs of right now, I'm only able to get something like ##(let [a (transient {})] (assoc! a :a a) (persistent! a)) , which is almost there.
22:35lazybot⇒ {:a #<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@15947ca>}
22:35gfrederickshyPiRion: what do you need this for?
22:35hyPiRiongfredericks: Intellectual stimulation.
22:35howard_slow clap
22:36hyPiRionIt's only an interesting problem, nothing more than that. :)
22:40gfredericks,(let [m' (promise), m {:self m'}] (deliver m' m) m)
22:40clojurebot{:self #<core$promise$reify__3678@340d5852: {:self #<core$promise$reify__3678@340d5852: {:self #<core$promise$reify__3678@340d5852: {:self #<core$promise$reify__3678@340d5852: {:self #<core$promise$reify__3678@340d5852: #>}>}>}>}>}
22:41muhoowat?
22:41clojurebotFor Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888
22:42gfredericksI think beyond that you'd have to look into hacking the private fields on the map classes
22:45hyPiRiongfredericks: heh.
22:47hyPiRionOh well, I'll look at it tomorrow.
22:48howard_what is the difference between a Cons and a list?
22:49howard_i'm wondering why i cannot use peek in Cons
22:49howard_.(peek '(1 2))
22:49howard_,(peek (cons 1 '(2 3))
22:49clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
22:49howard_,(peek (cons 1 '(2 3)))
22:49clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IPersistentStack>
22:49howard_:-(
22:49howard_,(first (cons 1 '(2 3)))
22:49clojurebot1
22:49howard_oh, first works..
22:49hyPiRion,(doc peek)
22:49clojurebot"([coll]); For a list or queue, same as first, for a vector, same as, but much more efficient than, last. If the collection is empty, returns nil."
22:50hyPiRionSo it's undefined for Conses.
22:50howard_,(doc first)
22:50clojurebot"([coll]); Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil."
22:50alandiperthoward_: cons returns a seq (not a concrete data structure), not a list
22:50howard_i see..
22:51howard_thank you
22:51howard_is there a way to pop more than one item from a stack (list)?
22:51howard_,(doc pop)
22:51clojurebot"([coll]); For a list or queue, returns a new list/queue without the first item, for a vector, returns a new vector without the last item. If the collection is empty, throws an exception. Note - not the same as next/butlast."
22:52howard_,(pop (pop (pop '(1 2 3 4))))
22:52clojurebot(4)
22:52howard_meh... that solves the problem but i wanna pop 100 from stack
22:53gfredericks(apply comp (repeat 100 pop))
22:53howard_so it makes a copy of the stack each time an element is popped?
22:53hyPiRionNo.
22:53howard_ok great!
22:54alandipert,(drop 3 '(1 2 3 4)) ; if you can deal in seqs
22:54howard_thanks guys!
22:54clojurebot(4)
22:54hyPiRion(reduce (fn [a _] (pop a)) [1 2 3 4 5 6] (repeat 3 nil))
22:55hyPiRion,(reduce (fn [a _] (pop a)) [1 2 3 4 5 6] (repeat 3 nil))
22:55clojurebot[1 2 3]
22:56alandipert,(nthrest '(1 2 3 4) 3)
22:56clojurebot(4)
22:57alandiperti think that lil guy stays a list
22:59gfredericks,(-> '(1 2 3 4) (nthrest 3) type)
22:59clojurebotclojure.lang.PersistentList
23:37muhoowhat's the most current hello-world for cljs? is it cljs-template?
23:50nsxtnoob question - if i've a string, say, foo.bar, and i want 'bar', i can do "ListTables"
23:50nsxtuser=>
23:50nsxtwrong paste...
23:51nsxti can do (second (clojure.string/split "foo.bar" #"\."))
23:51nsxtbut that feels... unnatural?
23:52nsxtis there a more idiomatic way of getting "bar"?
23:52howard_i did it in that way too...
23:53nsxtalright, i'll run with it for now.
23:53howard_:)
23:53howard_by the way..
23:53howard_are you trying to get file extension name?
23:53howard_if so, use last rather than second
23:53nsxtno... it will always be string.string
23:53howard_ok
23:53nsxtbut yes, i agree last is better
23:54nsxt(if there were multiple elements)
23:54howard_and if it is performance critical
23:54howard_use peek rather than second
23:54nsxtthanks, howard_
23:54howard_,(peek (clojure.string.split "foo.bar" #"\.")))
23:54clojurebot#<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.string.split, compiling:(NO_SOURCE_PATH:0)>
23:54howard_oops
23:54howard_,(peek (clojure.string/split "foo.bar" #"\.")))
23:54clojurebot"bar"
23:54howard_today i learned that peek is much faster than last :D
23:55muhooalso, noir-cljs or lein-cljsbuild?
23:55nsxtyeah, just checked clojuredocs and there's a benchmark, good to know