#clojure logs

2016-03-09

00:27TEttingerTimMc: you have no idea how often I use toBinaryString and toHexString, haha
00:27TEttingerI use a lazybot as a calculator and any binary stuff needs that
00:58ilevdHi, I find strings like "{{#list}}" "{{#render}}" in Java project html files, what's that framework or lib?
01:08rhg135Mustache
01:12ilevdThanks a lot!
01:36AndreasO(run :dispose), what does it do?
01:40ilevdIt depends on library, where is this used?
01:47AndreasOIn a seesaw example.
01:52TEttingerAndreasO: depends on what run is
01:54TEttingerin all the examples I see that's commented out, AndreasO
01:55TEttingerit looks like defexample defines the run fn https://github.com/daveray/seesaw/blob/master/test/seesaw/test/examples/example.clj
01:58AndreasOTEttinger: strange, I found an example here it wasn't commented out
01:59TEttingerit looks like (run :dispose) will run the example, and when the example is closed it calls whatever fn is assigned to :dispose in the defexample
02:00TEttingerthat's only in the examples
02:13AndreasOhttps://github.com/juliangamble/clj-seesaw-examples/blob/master/src/seesaw/test/examples/clock.clj
02:13AndreasOThere it is, not commented out.
02:56ilevdAre you happy with Clojure?
02:58opqdonutit's nice enough
02:58ridcully_for the larger part
03:00TEttingeryes
04:15prohoboclojure is hard yo
05:04prohoboanyone know how to dynamically add a field to the frame using seesaw?
05:18prohobohello?
05:18clojurebotBUENOS DING DONG DIDDLY DIOS, fRaUline prohobo
05:21prohobogod damn you clojurebot
05:21saureblol
05:24krlis there any way to see where clojure looks for java .class files to import? I'm getting class not found, even though the .class i'm including seems to be in the right place, (pointed to by :java-source-paths)
05:25krl(in lein)
05:30Empperiit uses the classpath declaration
05:30Empperiwhich is passed for java on startup
05:32krlcan you dump it somehow from the repl?
05:34Empperi(System/getProperty "java.class.path")
06:45amoe_anyone know how to move files using raynes.fs library? It seems to have support for moving things, but I don't know how to get access to the 'move' function that is used by these tests. https://github.com/Raynes/fs/blob/master/test/me/raynes/core_test.clj#L425
06:58jonathanjamoe_: according to the source, that function is only available if you're running java 7+
07:04amoe_jonathanj: I am indeed running java 7
07:08jonathanjamoe_: Looks like that function isn't in 1.4.6, which is the latest stable release: https://github.com/Raynes/fs/blob/1.4.6/src/me/raynes/fs.clj
07:09jonathanjrather, it's the version the README says to use
07:09jonathanjlooks like it was added quite a long time ago: https://github.com/Raynes/fs/commit/fdab09a711f6fd457bcdf13d213c6dea79c31241
07:10amoe_oh, that makes sense, thanks! I will find a workaround.
07:11jonathanjmaybe file an issue about releasing a new version?
07:11amoe_jonathanj: yup, I will do so.
07:12amoe_oh, actually one already exists https://github.com/Raynes/fs/issues/102
07:13amoe_it's funny, since starting to work with clojure half the issues I hit are open and resolved in the last ~2 months or so... seems the ecosystem is buzzing
07:32prohobo_im not getting any closure on my seesaw issue
07:33prohobo_i am emotionally exhausted
07:41amoe_prohobo_: maybe paste the code?
07:42prohobo_nah, its okay
07:42prohobo_im too tired to deal with it today
08:21amoe_I wonder is there any way to use the arrow syntax to immediately create a binding with the result, I want to write something like (-> (large-operation) (bind var (do-something var) (do-something-else var)))
08:21amoe_I know that's basically a function but I'd like to avoid making another function as it's in a test
08:23KneivaThere is nothing wrong in making a function just for a test.
08:24amoe_Kneiva: just my taste but I prefer to keep test code as flat as possible
08:43TMAamoe_: you can use unnamed functions: ((fn [var] (do-something var) (do-something-else var)) (large-operation)) or a (let [var ...] ...)
09:00Malnormaluloamoe_: If you reeeeeally want to avoid non-test namespace-accessible artifacts, you could always just make liberal use of `letfn`
09:01Malnormalulowhich can, itself, contain test defs, so that your tests become closures
09:06TimMcamoe_: Is the issue that your tests :use the ns under test, and you don't want to risk testing a test fn of the same name as a var from the original ns?
09:15zenolil.*
09:15zenoliWhoops, sorry.
09:56RedNifreClojure newbie here. So someone mentioned this nice pattern matching library yesterday. I guess I can figure out how to use it in a leiningen project but how can I test it in the REPL? https://clojars.org/defun/defun
09:57egliRedNifre: maybe with lein-try
09:57egli
09:58eglihttps://github.com/rkneufeld/lein-try
10:05RedNifreThanks, but that link gives me other ideas. It mentions a project.clj in ~/lein that I don't have... I guess I'll learn more about lein before customizing it further.
10:05RedNifreBookmarked for later, thanks egli.
10:08RedNifreI think it was justin_smith who mentioned a mutable map that maps symbols to values or functions (or macros even?), e.g. using (def pi 3) writes to one such map. Are these maps the namespaces? Or are there differences?
10:24sdegutisYou ever have a day or week where you're like insanely productive compared to every other day?
10:25RedNifresdegutis. Rarely. It's usually the opposite where one problem leads to the next and everything that should be simple is complicated.
10:25sdegutis:D
10:27RedNifreSo what are you being productive about today? :)
10:27Malnormalulo"My first build failed this morning so I've just been staring at the stack trace until noon" --me, most days
10:27sdegutisRedNifre: using Clojure at work
10:27Malnormalulowait stack trace in a build that doesn't even make sense
10:27sdegutisMalnormalulo: haha yes I know that feeling
10:36RedNifreHm, do the dots in namespaces mean anything?
10:40MalnormaluloI think, under the covers, in the bytecode, they're the same as dots in Java packages. If that means anything to you
10:41Malnormalulo(And if you're using the JVM implementation of Clojure)
10:42RedNifreAh, so I could :require many things at once by doing (:require [clojure.*]) ?
10:45MalnormaluloThat...sounds plausible. I've never tried it.
10:46prohobo_damn, clojure. you scary
10:49mavbozoRedNifre, you require many things at once by doing (:require [foo.bar :refer [fun1 fun1 fun3 var1 var2]])
10:49RedNifreu-huh... So the dots in the namespace name are less important in clojure, they are more informal?
10:50mavbozothe dots in the namespace are important to separate namespace segment
10:52lumaif you want to require multiple namespaces with the same prefix, you can do (:require (foo.bar baz bloo)), which would require both foo.bar.baz and foo.bar.bloo
10:52RedNifreAh, I see.
10:53lumaand the usual tricks work there as well: (:require (foo.bar [baz :refer [fn1 fn2]] bloo))
11:01RedNifreHm, the JoC book just warned me about java boolean objects i.e. (Boolean. "false"). It says the safe way is (Boolean/valueOf "false"). How exactly does that work? Is Clojure's false a java Boolean object? Or the primitive? Or is there autoboxing?
11:02mavbozo,(type false)
11:02clojurebotjava.lang.Boolean
11:02RedNifre,(type nil)
11:02clojurebotnil
11:02winkRedNifre: https://clojurebridge.github.io/community-docs/docs/clojure/truthiness/
11:03RedNifreThanks wink. I'm currently reading about truthiness.
11:03mavbozo,(class false)
11:03clojurebotjava.lang.Boolean
11:04RedNifreSo the only falsey things are nil and false, where nil is Java's null and false is Java's Boolean object for false. Do the primitive java booleans show up in Clojure as well or do they always get autoboxed to Boolean objects before showing up in Clojure?
11:12RedNifreNow JoC says that my functions should expect to be called with nil if they expect collections and that I should use seq to be sure. That advice seems strange to me, I would have thought that treating nils as empty collections (instead of as bugs) would obfuscate bugs elsewhere in the code. Why is that a good idea?
11:22bermrajgood morning, is there a dirrerence in using (Integer.) compare to (new Integer)?
11:23RedNifreYes, the JVM caches the first 255 Integers. I guess it doesn't do that when calling the constructor.
11:23RedNifreWait, what does (new Integer) mean in Clojure?
11:24RedNifre(Newbie here. I just learned that (Integer.) calls the constructor so I wonder what (new Integer) means)
11:32rcassidy,(new Integer)
11:32clojurebot#error {\n :cause "No matching ctor found for class java.lang.Integer"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Integer, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.IllegalArgumentException\n :message "No matching ct...
11:34narwhal01hi guys
11:34mavbozo,(new Integer 1)
11:34clojurebot1
11:34mavbozo,(class (new Integer 1))
11:34clojurebotjava.lang.Integer
11:34RedNifre,(= 1 (new Integer 1))
11:34clojurebottrue
11:34narwhal01,(clojure.string/join " " ["I" "'m" "sorry"])
11:34clojurebot"I 'm sorry"
11:35RedNifreheya
11:35narwhal01how can i join with condition if the word "'m" don't join with space else join with space
11:36rcassidy,(Integer. 3)
11:36clojurebot3
11:36RedNifrenarwhal01 funny idea: join with space and then replace " '" with "'"?
11:37RedNifremore serious idea: something something foldr / reduce ?
11:37narwhal01RedNifre, is the better idea?
11:37narwhal01RedNifre, reduce ?
11:38RedNifreyeah, reduce with a string builder I think.
11:38narwhal01ah ok
11:50mavbozoRedNifre, in what chapter in JoC book there is a advice that "my function should expect to be called with nil if the function expect collections"?
11:53RedNifremavbozo hang on, let me go back...
11:54RedNifremavbozo It's in 3.2
11:55RedNifrehang on
11:55RedNifreI think I might have missread that.
11:56RedNifreOh right, it says "you shouldn't assume seq has been called on your collection arguments, but instead call seq in the function itself." So it means I'll receive empty collections and shouldn't check them for truthiness without calling seq.
11:57RedNifrethanks mavbozo
11:59rcassidy,(seq nil)
11:59clojurebotnil
12:00mavbozo,(seq '())
12:00clojurebotnil
12:00RedNifre,(seq ())
12:00clojurebotnil
12:01MJB47does anyone know why people dont use empty?
12:01MJB47other than its 3 chars longer
12:01RedNifreThe books says it's because you would have to type "(when-not (empty?" instead of "(when (seq".
12:02mavbozothat's 7 chars longer
12:03RedNifre,(vec [])
12:03clojurebot[]
12:03RedNifreHm, so no nil here...
12:04RedNifre,(vec (seq []))
12:04clojurebot[]
12:08mavbozothe comprehensive explanations on sequence is in chapter 5.1 in JoC book
12:10RedNifreI'll get there eventually.
12:56cortexman__oooo\\\\\/
12:57RedNifreHm, JoC says that "underflow" means a floating point becoming zero. I thought it meant substracting from a negative int and getting a positive one as a result.
12:57RedNifreIs Integer.MIN_INT -1 also called an "overflow"?
12:59justin_smithRedNifre: maybe underflow, but I think it throws OverflowError
12:59justin_smith,(dec Integer/MIN_VALUE)
12:59clojurebot-2147483649
12:59justin_smitherr
12:59justin_smith,(dec Long/MIN_VALUE)
12:59clojurebot#error {\n :cause "integer overflow"\n :via\n [{:type java.lang.ArithmeticException\n :message "integer overflow"\n :at [clojure.lang.Numbers throwIntOverflow "Numbers.java" 1501]}]\n :trace\n [[clojure.lang.Numbers throwIntOverflow "Numbers.java" 1501]\n [clojure.lang.Numbers dec "Numbers.java" 1851]\n [sandbox$eval49 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval49 invoke "NO_SOURCE_FIL...
12:59justin_smithyeah, it calls it an overflow though it's an underflow technically
13:00justin_smithhttps://en.wikipedia.org/wiki/Arithmetic_underflow
13:00RedNifreCan you divide the double that is closest to zero by two for me?
13:00justin_smithRedNifre: oooh
13:00justin_smithone moment
13:01justin_smith,(/ (Math/ulp 0.0) 2)
13:01clojurebot0.0
13:01RedNifreokay, the wikipedia article calls both the integer thing and the float becomes zero thing an "underflow" where the JoC book claims that only dividing a float and getting zero is called an underflow.
13:01RedNifreHm.
13:01RedNifreSo no underflow exception there...
13:01justin_smithRedNifre: Math/ulp gives the closest non-equal value to a given double
13:01justin_smithRedNifre: that's not an underflow
13:02justin_smithit's a precision failure, but IEEE floats don't throw on precision errors
13:02RedNifre,(Math/ulp 0.0)
13:02clojurebot4.9E-324
13:02RedNifreRight, I was surprised as well, but both JoC and the Wikipedia article call those underflows.
13:02justin_smithRedNifre: oh wait I'm wrong
13:02justin_smithunderflow is about small numbers, not low negative numbers
13:02justin_smithd'oh
13:03justin_smithRedNifre: yeah, JoC is right, not me
13:03RedNifreNow you're agreeing with the book, but the wikipedia article says that low negative numbers also underflow.
13:03justin_smithnow I am double confused, time for my morning coffee
13:03justin_smithhaha
13:04justin_smithRedNifre: reading more closely, the wikipedia article is talking about negative digits on the exponent, not about negative numbers of high magnitude per-se
13:05RedNifreOh right.
13:05RedNifreI guess an Integer can overflow at both ends then, but never underflow.
13:06justin_smithyeah, that sounds right
13:07justin_smithRedNifre: I don't know if anyone else replied about namespaces with mutable maps but the namespace owns a mutable map of symbols to vars (and each var is a mutable container holding a single value), but the namespace also has a map of referred bindings belonging to other namespaces, and probably some other junk too
13:08justin_smitheg. the stuff that makes require and use and import work
13:08RedNifreAh, so a namespace is a bundle of several maps where each map has a different purpose?
13:10justin_smithyeah - it would probably be informative to check out the java code for this
13:11RedNifreI hope I'll understand Clojure as deeply as I understand Io (A dead language, the Lisp of the OOP world).
13:11justin_smithI remember Io, I never played with it though
13:11justin_smithwhat about smalltalk, that isn't the Lisp of OOP?
13:12faxmodemfor all I know Io is a moon
13:12RedNifreIn Io, everything is an object, the commands you type in the REPL are method calls on the REPL object, Objects are basically maps from Strings to other objects, when you do obj.bla = 5 you are really doing obj.setSlot("bla", 5) etc.
13:13justin_smithRedNifre: aha in smalltalk the equivalent of obj.bla = 5 sends a message of [set blah 5] to obj (everything is a message)
13:14justin_smithbut for some reason at some point in programming history people decided OO was more about inheritence than it was about messages
13:15RedNifreYeah, but in Io, when a method gets called instead of receiving its parameters in can choose to receive a call object instead.
13:15RedNifreIt's also homoiconic, so the call object will contain the AST of what was passed as parameters.
13:15RedNifreThis is basically as powerful as macros.
13:15justin_smithcool
13:16RedNifreAnd there's an operator table that you can inspect and modify.
13:16RedNifreIt's both simple and brilliant. Unfortunately it's a dead language and I prefer FP over OOP these days so I'm looking at Clojure now.
13:17alisdairIo was great, it's a shame it never took off
13:20RedNifreYeah. You can even turn Clojure syntax into valid Io syntax by defining a method with an empty name that transforms the passed AST before executing. You know, like this: https://gist.github.com/RedNifre/50a98c5ab07b526ca891
13:20mmasticWhat's the idiomatic way to create getters for maps? I'm finding myself making lots of stuff like `(def x (partial :x))'. I thought about a macro but I figured that if this was the way for such a common thing then it would surely be part of the core library.
13:20justin_smithmmastic: the idiomatic thing is to not use getters for things that are immutable
13:21RedNifrewhy not just :x?
13:21justin_smithexactly, what RedNifre said
13:21justin_smithwith mutable things, that layer of information hiding can be very important, with immutable ones, it's much less useful
13:22mmasticI don't want plain keyword because it bit me in the ass earlier x_x it makes it impossible to change the map without breaking something.
13:22amalloymmastic: def the keywords you want to use
13:23amalloy(def size :size) ... (size the-map)
13:23amalloythen if you change the name of the key, the compiler will know when you forget to update a use
13:23RedNifreAh.
13:24RedNifreMaybe using records instead of maps would provide that type of security?
13:24mmasticIt's very repetitive and boilerplate-y though, don't you think? and usually changing the name of the key isn't the issue, it's different structuring and such.
13:25justin_smithmmastic: my solution to that is typically to use prismatic/schema at system boundaries
13:25mmasticYeah I thought about records, but I want to be able to extend on the fly.
13:25justin_smithmmastic: you can add any key to a record
13:25RedNifrethat sounds like contradicting requirements.
13:26mmasticPrismatic/schema? what do you mean?
13:26RedNifre"prismatic" sounds like lenses and prisms...?
13:26RedNifre,(:not-there {})
13:26mmasticOh, it does RedNifre :P what I mean is that I'm still molding my structure but I want to keep the solid part solid.
13:26clojurebotnil
13:27justin_smithmmastic: RedNifre: prismatic (which changed names recently) has a library called schema
13:27justin_smithit allows checking arbitrary facts about the shape of data, as a kind of dynamic type checking
13:28mmasticAh libraries, okay. Hmm tbh that sounds like a bit of an overkill. Perhaps I should resort to macros anyway :P?
13:31RedNifreI would use maps as long as you can remember the keywords and switch to a record (or type?) when you get bitten :)
13:31RedNifre(Disclaimer: I have never used maps, types, records so far, I'm just starting out. Don't believe anything I say!)
13:33mmasticHehe fair enough :P thank you. I might do that when I get more far ahead in the evolution of the data.
13:33mmasticThank you everybody ^^ much appreciated.
13:34RedNifreHang on.. Ruby has something called an ostruct.
13:34RedNifreThat sounds like what you want.
13:34RedNifreYou can add arbitrary keys to it, but when you try to retrieve an undefined one you get an error (I think).
13:34RedNifreMaybe something like that exists for Clojure?
13:35justin_smithRedNifre: this is what records do
13:35justin_smithexcept for the error part
13:35justin_smith,(defstruct Foo [a])
13:35clojurebot#error {\n :cause "Unable to resolve symbol: a in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: a in this context"\n ...
13:36justin_smith,(defrecord Foo [a])
13:36clojurebot#error {\n :cause "clojure.lang.Var cannot be cast to java.lang.Class"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Var cannot be cast to java.lang.Class"\n :at [clojure.lang.Namespace referenceClass "Namespace.java" 129]}]\n :trace\n [[clojure.lang.Namespace referenceClass "Namespace.java" 129]\n [clojure.lang.Namespace importClass "Namespace.java" 158]\n [clojure....
13:36RedNifrehuh?
13:36justin_smiththat error is weird...
13:36justin_smithRedNifre: huh? about which part?
13:37RedNifreAlso, I take back what I said about ostruct, it just returns nil when you query something that's not inside.
13:37justin_smith,(defrecord Bar [a])
13:37clojurebotsandbox.Bar
13:37justin_smith,(assoc (Bar. 0) :b 1)
13:37clojurebot#sandbox.Bar{:a 0, :b 1}
13:37justin_smiththat's it, that's what records do
13:38RedNifre,(:a (Bar. 0))
13:38clojurebot0
13:38RedNifre,(:c (Bar. 0))
13:38clojurebotnil
13:38mmasticOkay so I'll just use defs for now and worst case scenario I'll write a macro. Thanks again ^^
13:39justin_smith,(:c (assoc (Bar. 0) :c 2))
13:39clojurebot2
13:39RedNifreyeah, but mmastic's problem is that she/he wants a compiler check to catch that.
13:39justin_smith,(:c (map->Bar {:a 0 :c 2}))
13:39clojurebot2
13:39RedNifre,(:i-cantt-type (assoc (Bar. 0) :i-cant-type "huh"))
13:39clojurebotnil
13:40justin_smithright
13:40justin_smiththat's why I was saying prismatic/schema, it's the right thing in the clojure world for checking those sorts of things
13:41justin_smiththat or core.typed, but core.typed is a little trickier to integrate with
13:42mmasticOh I don't care for a compiler check. I just want getters without boilerplate ^^ I basically want something to write the getter functions for me.
13:42RedNifreAre keywords getter function or is there some hidden macro that turns (:bla someMap) into (get someMap :bla)?
13:42RedNifremmastic but why do you need a getter function if not for compiler checks?
13:43mmasticYeah, they are.
13:43mmasticAnd an associative (such as a map) is also a function that takes a key and does the same thing.
13:43RedNifreAre keywords variadric functions that when called without arguments return themselves, otherwise call (get param self) ?
13:44justin_smithyeah, keywords are getters, and schema allows making assertions about which keywords are present (and the type / shape of the values under those keywords)
13:44justin_smithRedNifre: they have no way of returning themselves, though in the reader they are self-evaluating (but that is not the same as returning self when called)
13:45hiredmanno
13:45justin_smiththey do have an optional not-found argument when invoked though (the same not-found that get allows)
13:45hiredman,(:foo)
13:45clojurebot#error {\n :cause "Wrong number of args passed to keyword: :foo"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Wrong number of args passed to keyword: :foo"\n :at [clojure.lang.Keyword throwArity "Keyword.java" 97]}]\n :trace\n [[clojure.lang.Keyword throwArity "Keyword.java" 97]\n [clojure.lang.Keyword invoke "Keyword.java" 110]\n [sandbox$eval208 invokeStatic "NO_SOURCE_F...
13:48mmasticHmm perhaps I'll explain what actually happened to me. I'm writing a graphical framework. An object in this system is a map, and it has a map assoced with :position which is a map with :x and :y. Then I introduced a physics engine, and the (-> object :position :x) turned into (-> object :physics :position :x). A caller that relied on the initial version broke, as you can imagine. So I thought to make getters. But now getters are boil
13:50TimMcmmastic: Cut off at "boil"
13:51TimMc(IRC has message length limits)
13:53RedNifre,::sandbox
13:53clojurebot:sandbox/sandbox
13:54RedNifreJust to be sure, that's a totally normal keyword named "sandbox/sandbox", right? The part that looks like a namespace is only informal to help programmers, it has no function whatsoever, right?
13:54justin_smithmmastic_: have you considered a protocol with a get-x method? that way you can extend the protocol for any object that should have an x coordinate, and the lookup of the actual property is defined in one place per Class
13:55justin_smithRedNifre: yeah, the namespace part is useful (eg. helps track who would be interested in that part of the data) but doesn't effect much - the namespace of the keyword doesn't even need to exist
13:55justin_smith,:akldjfalkdsjflakdsjfladskjflkadsjf/foo
13:55clojurebot:akldjfalkdsjflakdsjfladskjflkadsjf/foo
13:56RedNifreYeah, so in the technical sense it's a regular keyword that just happens to have a slash in the middle.
13:56mmastic_Yeah I did but I'm not sure how would that be implemented. Would I reify instances or just extend maps? Hmm I actually just considered reifying which didn't sound good, but extending maps should work, I suppose, right? or am I missing something?
13:56justin_smith,(namespace :akldjfalkdsjflakdsjfladskjflkadsjf/foo)
13:56clojurebot"akldjfalkdsjflakdsjfladskjflkadsjf"
13:57justin_smithmmastic_: you would use a record, which is just a map that allows arbitrary protocols / interfaces to be implemented
13:57RedNifreso... what would I do with the namespace of a symbol?
13:57justin_smith,(namespace 'foo/bar)
13:57clojurebot"foo"
13:58RedNifreI meant keyword.
13:58mmastic_But I can't arbitrarily assoc new keys without going back and forth, right? that's a concern for me.
13:58justin_smithRedNifre: I just did that above
13:58RedNifreYeah, I was asking what I can do with that.
13:58justin_smithmmastic_: false, you can associate any keys you want to a record
13:58justin_smithmmastic_: I already demonstrated that above
13:59justin_smithRedNifre: ahh, sorry, misunderstood
13:59justin_smithRedNifre: you might want to go through a map or set and collect keys matching a certain namespace
13:59mmastic_Oh really? damn, I got records wrong all along then :P I'll revisit them. So semantically they're just maps where some keys are specialized?
13:59justin_smithor remove them, or update them, etc.
14:00justin_smithmmastic_: plus the ability to implement interfaces and protocols, yes
14:00justin_smiththey are very useful
14:00TimMcA word of warning, they can interfere with interactive development.
14:01mmastic_Omg that sounds amazing. Home come they can interfere?
14:01justin_smith(not= (defrecord Foo [a]) (defrecord Foo [a])) - they have the same name and slots, but are different classes
14:02TimMcIf you make an instance, reload your code, then ask "is this object an instance of this record?" it will say "no", but it will still be of a class with the same name.
14:02TimMcand of course if you implement protocols everything goes haywire with code reloading, but you already get that with protocols
14:02TimMc(who makes wire out of hay anyhow)
14:02justin_smithmy common approach to this is to put the record and protocol definitions in tiny namespaces that contain no logic that I never reload
14:03justin_smithbut yes, these things are annoying to be sure
14:03RedNifre,(def a-symbol 'some-symbol)
14:03clojurebot#'sandbox/a-symbol
14:03RedNifre,a-symbol
14:03clojurebotsome-symbol
14:03mmastic_Oh I see. I'll revisit records right now. Thank you!
14:03RedNifre,(resolve a-symbol)
14:03clojurebotnil
14:04RedNifre,(resolve 'a-symbol)
14:04clojurebot#'sandbox/a-symbol
14:04RedNifreWhat exactly does the "#'" at the start mean?
14:04justin_smith,(def some-symbol "found it")
14:04clojurebot#'sandbox/some-symbol
14:04justin_smith,@(resolve 'a-symbol)
14:04clojurebotsome-symbol
14:04justin_smith,@(resolve 'some-symbol)
14:04clojurebot"found it"
14:05justin_smith,@(resolve @(resolve 'some-symbol))
14:05clojurebot#error {\n :cause "java.lang.String cannot be cast to clojure.lang.Symbol"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.Symbol"\n :at [clojure.core$ns_resolve invokeStatic "core.clj" 4239]}]\n :trace\n [[clojure.core$ns_resolve invokeStatic "core.clj" 4239]\n [clojure.core$ns_resolve invokeStatic "core.clj" 4229]\n [clojure.core$re...
14:05justin_smithergh
14:05justin_smith,@(resolve @(resolve 'a-symbol))
14:05clojurebot"found it"
14:05justin_smithhaha
14:05RedNifreWhat's with the @ again? And what's with the # in the output?
14:05justin_smithRedNifre: watch
14:05justin_smith,#'foo
14:05clojurebot#error {\n :cause "Unable to resolve var: foo in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve var: foo in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve var: foo in this context"\n ...
14:05justin_smithoops
14:06justin_smith,'#'foo ; I meant this
14:06clojurebot(var foo)
14:06RedNifreOh, is that the lambda again?
14:06justin_smith,'@#'foo ; I meant this
14:06clojurebot(clojure.core/deref (var foo))
14:06justin_smithnope, anything starting with # is a reader-macro, and you can see the expansion by using '
14:06justin_smithso the above expansions via ' help?
14:07RedNifreehm
14:07justin_smithRedNifre: #'foo is a shortcut for (var foo)
14:07justin_smith@foo is a shortcut for (deref foo)
14:08RedNifre,(resolve 'a-symbol)
14:08clojurebot#'sandbox/a-symbol
14:09RedNifreOkay, so clojurebot means (var sandbox/a-symbol) ?
14:09justin_smithright
14:10RedNifrehang on
14:10RedNifreI had to look up var :)
14:11matt______hey, all. i've used clojure for some time now, and i've always known that vectors are not seqs, but i've never understood why. when you call first on a vector, it calls RT's first, which turns it into a seq and then calls seq's first. can anyone explain or point me to an explanation?
14:11TimMc~colls and seqs
14:11clojurebotCool story bro.
14:11TimMchmm
14:11RedNifreWell, (def x 42) creates a var... but I don't understand that. Hm.
14:11TimMc~seqs and colls
14:11clojurebotseqs and colls is http://www.brainonfire.net/files/seqs-and-colls/main.html
14:11TimMcmatt______: ^ I wrote this up a while back
14:12matt______TimMc: nice, thanks. checking it out now.
14:12justin_smithRedNifre: namespaces contain a hash-map from symbols to vars, each var is a mutable container holding a single value (with optional metadata)
14:12TimMcSummary: Seqs are views into collections.
14:12RedNifreI thought that (def x 42) adds an "x" entry to the namespace's map that points to 42. Where does (var 42) come in?
14:12RedNifreah. why is that extra indirection needed?
14:12justin_smithRedNifre: because we want to hold onto the var and see the new value later
14:13justin_smithwithout looking it up in the namespace map every time
14:13justin_smithit's a thing that makes interactive development work as expected
14:13matt______TimMc: quick other question: ISeq also has a more function that no one seems to talk about. any reasoning behind that? deprecation via ignoring?
14:14hiredmaninlining through a hashmap lookup is complicated, inlining a var deref is simpler
14:14RedNifreOh, you mean if I do (def a "a") (def b a) (def a "not-a"), then b will return "not-a"?
14:14hiredmanno
14:14justin_smithno, but inside a function that uses a, it would see the new a
14:14hiredmana is derefed and the value is stored in b
14:14justin_smithso (def b [] a) would work as you described
14:14justin_smitherr, (defn b [] a)
14:15RedNifreYou mean (def b a) checks the namespace map for a and finds a variable, takes the string out ouf that variable, creates a new variable and puts the string in it and then puts that newly created variable in the namespace map under b?
14:16hiredmanyou are mingling what happens at compile time, and what happens at runtime
14:17RedNifreI'm trying to understand what (var "bla") is. I don't understand why (def a "a") doesn't just put the string in the namespace map.
14:17hiredmanwhat I said re: inlining
14:18RedNifreI don't understand the point about inlining.
14:18hiredmanwith a var, the lookup only needs to happen once, to get the mutable var cell, with a direct map lookup, you would need to do a map lookup for ever function call
14:19hiredmanRedNifre: just imagine the var is a inline cache for the map value you would lookup (it isn't, but whatever)
14:19RedNifreHm. I guess def replaces not the content of the var but the var itself?
14:19hiredmanno
14:20hiredmanvars are interned, and def will intern a new one if it does exist, but it reuses an existing one if it already does
14:21RedNifreIf I do (def a "a") (def b a), what exactly is in b? The way I understand it a and b would point to the same var. But if I do (def a "x") a will point to a newly created var containing "x" where b will still point to the old var containing "a"?
14:21hiredmanno
14:22RedNifreWhat exactly happens in this code then? (def a "a") (def b a) (def a "x") b ?
14:22hiredman(def b a) in that scenario, creates a new var b, then derefs the var a, and puts that value in b
14:22hiredmanb will be "a" in that scenario
14:24RedNifreOkay, so every def creates a new var, but the (def a "x") would change the content of the already existing var that is pointed to by a from "a" to "x"?
14:24RedNifreI meant every def that introduces a new ... symbol ... name ...thingy.
14:24TimMcmatt______: Oh, I don't know about the more method, lemme see...
14:24hiredmana simplified version of the semantics for symbol evalution for clojure is something like: to evaluate the symbol a, if a names a local, it evalautes to the value of that local, if a names a var, deref the var
14:25hiredmanRedNifre: no, def produces a var
14:25justin_smithTimMc: matt______: .more is what rest calls
14:25RedNifrehiredman in my example, what exactly does (def a "x") do?
14:25hiredmanRedNifre: vars generally are named by symbols (not always, but you'll likely never run in to an anonymous var)
14:26TimMcah yeah, here's LazySeq's impl: https://github.com/clojure/clojure/blob/3748127f440a39d6003e94733da70c2704e385f2/src/jvm/clojure/lang/LazySeq.java#L84
14:26RedNifreDoes (def a "a") (def a "x") change the content of the var or does it create a new var and puts it in the namespace map?
14:26hiredmanRedNifre: it looks for a var in the namespace bound to *in-ns* named a, creates it if it doesn't exist, and sets its value to "x"
14:26hiredmanRedNifre: it changes the value of the var
14:27RedNifreOkay. Let's see if I understand inlining then...
14:27hiredmanRedNifre: vars are global references by the way, local bindings of names to values (via let, or function application) are locals not vars
14:27RedNifreIf I do [a a a a], does it fetch the var from the namespace map and then kinda replaces the code with [$var $var $var $var] before continuing?
14:28hiredmanno
14:28RedNifreCan you give me an example for inlining?
14:28matt______hm, well more doesn't call rest there. it's the same except it returns an empty list when empty.
14:28hiredmanthe compiler finds the var in the namespace map, and emits code that says "construct such and such a var
14:28hiredmanwhoops
14:29matt______next in RT doesn't call more, either. next calls next, more calls more.
14:29hiredmangenerate java byte code effectively has a reference to the var
14:29hiredmanso when the function is running, it never does a map lookup
14:29hiredmanit can find all the values it needs just by dereferencing the vars
14:30hiredmanderefencing the vars is a simpler operation than a map lookup, so the jvm's jit is better able to optimize it
14:30hiredman(where it gets inlined away or not is sort of complicated)
14:31RedNifreHm... I don't know much about bytecode, I guess that the Clojure code [a a a a] kinda turns into bytecode that says new Vector(Namespace.a, Namespace.a, Namespace.a, Namespace.a);?
14:31hiredmanno
14:31RedNifredammit
14:32hiredman(let [x (resolve 'a)] (Vector. @x @x @x))
14:32justin_smithmatt______: no, I said rest calls .more
14:32hiredmanreally it is more like
14:32hiredman(let [x (resolve 'a)] (fn [] (Vector. @x @x @x)))
14:33hiredmanlike, if you had a function like (defn f [] (inc a))
14:33justin_smithmatt______: next calls .next, more and next are alternatives to one another
14:33justin_smith*rest and next that is
14:33hiredman(let [x (resolve 'a)] (def f (fn [] (inc @x))))
14:33RedNifreHmm, I think it's getting clearer.
14:34hiredmanso you see, the resolution of 'a happens once, and then ever after whenever you call the function f, it just reads the value from the resolved var
14:36matt______justin_smith: thanks. seems a bit confusing, but i see it fitting together now.
14:36RedNifreSo if I write the pseudo bytecode as java code it might compile to something like Var<Integer> x = fetchFromTheNamespaceMap("a"); Integer f() { return inc(x.get()); } ?
14:37hiredmansort of
14:37hiredmanif you know java, the var resolution happens as a static init and the var is held in a static field
14:37RedNifreOkay, that's how I imagined it.
14:38matt______smells like rest, next, and more will behave the same except for the empty case, and that rest is roughly an alias for more in the empty case.
14:38RedNifreDoes the content of a var ever change?
14:38justin_smithmatt______: rest is .more (but might change in the future)
14:38justin_smithmatt______: next is .next
14:38hiredmansure
14:39RedNifrehow? when?
14:39justin_smithmatt______: this is much clearer if you look at (source next) and (source rest)
14:39hiredmanif you define a function g that invokes function f, but at some point in the repl decided to define a new f
14:39hiredmang will when executed use the new f
14:39matt______justin_smith: i'm looking at it right now at the top of core.clj before defn is available.
14:41justin_smithmatt______: no, I mean the source actually available at runtime
14:41justin_smithlike literally what (source rest) and (source next) return in the repl
14:41RedNifreoh god...
14:42hiredmanthat is also what I think of as "standard var linkage mechanics", there are varations for dynamic binding (slight), direct linking (this is new in 1.8, and basically eliminates the var at compile time), and static linking (this is a defunct, sort of a precursor to direct linking, the compiler support for it is deleted or commented out)
14:42matt______justin_smith: that returns the exact same thing as shown in core.clj... ?
14:42matt______https://github.com/clojure/clojure/blob/010864f8ed828f8d261807b7345f1a539c5b20df/src/clj/clojure/core.clj#L57
14:42RedNifreI haven't thought this through but it sounds like it works differently for def and defn.
14:42hiredmanno
14:43hiredmandefn is more or less def
14:43matt______the calls to (source rest) or (source next) that is.
14:43hiredman(the def part is, the fn part is fn of course)
14:43justin_smithmatt______: oh, right
14:43RedNifreah, never mind. I thought the wrong way...
14:44hiredmanRedNifre: (def b a) from your ealier example comes out as (let [x (resolve 'a)] (def b @x))
14:44hiredmanit is fairly common for people to be confused about the behavior of top level defs liek that
14:44matt______justin_smith: just making sure. thanks for the info.
14:45justin_smithRedNifre: and people that know they are confused are a step up on those that simply assume wrongly
14:46RedNifreOkay, so (def a "a") (def b a) is two separate vars containing the same string. But the function (defn bla [] a) ... fetches the var when it gets created... so when I later do (def a "x"), the CONTENT of the var changes from "a" to "x" which means that calling the bla function will now return "x" but the b value will still return "a"?
14:47hiredmanyes
14:47RedNifrePhew!
14:48RedNifreI think I get it now. Thanks for your patience :)
14:52hiredmanI have this essay I keep meaning to write entitled "Vars, what the hell?"
14:52RedNifreWhen I do (defn bla [] a), the namespace map gets a new entry called bla that points to a newly created var containing (fn [] the-var-that-was-in-a-when-this-function-got-created), right?
14:53hiredmanmore or less, but you don't really talke about the var being in a, a is the name of the var
14:54hiredmana doesn't have a place to store things, it is a name
14:54justin_smithRedNifre: that's right, and also if you deleted a with ns-unmap and made a new a, bla would never see the value of the new a
14:54RedNifreWell, no, if I do (def a "x") later then the function will still use the now nameless var that can no longer be found in the namespace map?
14:55hiredmanno
14:55RedNifreoh right
14:55RedNifredammit
14:55justin_smithRedNifre: you have crossed signals with hiredman because hiredman has had me on his ignore list for years
14:56justin_smithRedNifre: you are correct, if you ns-unmap a, then make a new a, bla never sees the new a
14:56hiredman(as an aside you can actually create nameless vars, but that is a feature that isn't used ever, outside of the compiler)
14:56RedNifreaw, now you two are being intentionally confusing. How am I supposed to chat with people that have each other on their ignore list? :)
14:57justin_smithRedNifre: I don't ignore him, it's one way, just telling you he didn't understand what you were saying because he didn't see what I said
14:57ridcullybut you could tell the one, what the other siad
14:57RedNifreNah, telling one what the other said would be disrespecting the ignore list ;)
14:59RedNifreIs this var business only for the REPL? I mean, I wouldn't redefine things in regular code, right?
14:59justin_smithRedNifre: there is no such thing as "only for the repl" in clojure
14:59justin_smithRedNifre: there's just one compiler
15:00RedNifreBut (def a "a") (def a "b") would seem weird to me in regular code.
15:00RedNifrewhat did you do to get on the ignore list? :)
15:00justin_smithpragmatically, I would call that bad code. But it's legal. There are no special repl-only features or rules in the clojure compiler.
15:00justin_smithRedNifre: I think I was playing with clojurebot and being a dumbass, not sure
15:01justin_smith"dumbass" probably works as a description, whatever it was
15:01RedNifreYeah, I didn't mean that it would be illegal code outside the REPL, just weird.
15:02TimMcjustin_smith: Wait, you're on his ignore list too?
15:02justin_smithTimMc: yup, it's quite a club we've got isn't it
15:03TEttingerthe ignoramancer ignores most of the channel apparently
15:04TimMcI at least do people the favor of clearing my ignore list periodically...
15:04RedNifreAnother thing, JoC mentions using keywords like an enum, e.g. :north :west :south :east. That seems strange to me I like the concept of an enum being a finite set of well known values. Am I being oldfashioned? Are there regular enums?
15:05justin_smithJava has enums, I think you can create them via interop
15:05TEttingeryeah, not sure how you'd make one in Clojure
15:05justin_smithbut usually we use keywords as if they were enums if we need something like that
15:06RedNifreIt's all so dynamic... how do you refactor that?
15:07justin_smithRedNifre: a lot of clojure idioms are very dynamic, borrowed from the lisp world where compile-time checking isn't really a done thing
15:07justin_smithyou refactor it by changing things until it doesn't look broken any more (which is the downside of the lisp approach of course)
15:07matt______i was linked and read "seqs and colls", and perhaps i'm dense, but i still don't understand why vectors don't implement the seq abstraction.
15:07matt______you can call first, next, cons on a vector, but it goes through conversions and/or an if-else-if ladder of instanceof calls in RT to get there versus just having a method on the class
15:08matt______anyone know the rationale?
15:08justin_smithmatt______: cons doesn't return a vector because vectors have no built in prepend - you need to convert to another type and then back again
15:09matt______justin_smith: the same is true for first and rest, right?
15:09justin_smithafaik, yes
15:10matt______yet all of those will take a vector and take a slower route than just having vectors be seqs an implement the required methods.
15:10justin_smithmatt______: clojure will kind of steer toward things that are natively apropriate for data types, even at the price of some inconveniences, I think vectors not being a seq is part of this
15:10justin_smithlike, vector not being a seq reflects the fact that you need to do a type conversion before you can do seq things to it
15:11justin_smith(even if that conversion is implicit in most idiomatic code)
15:11RedNifreHm, now JoC explained metadata to me but without examples... when would I use metadata as opposed to putting things into an object? Or is that for annotating data I get from other libraries?
15:12justin_smithRedNifre: vars are a greate example here
15:12justin_smith,(meta #'+)
15:12clojurebot{:added "1.2", :ns #object[clojure.lang.Namespace 0x7da402f4 "clojure.core"], :name +, :file "clojure/core.clj", :inline-arities #object[clojure.core$_GT_1_QMARK_ 0x2d5dbd31 "clojure.core$_GT_1_QMARK_@2d5dbd31"], ...}
15:12matt______justin_smith: ok. yeah, it seems like performance is the reason for not doing it. efficiently adding at the front is not doable, and even rest is... well, i'm not sure of the efficiency of subvec, but will look into it.
15:13RedNifre,(-> (meta #'+) :name type)
15:13clojurebotclojure.lang.Symbol
15:14RedNifre,(identical? + (-> #'+ meta :name))
15:14clojurebotfalse
15:14RedNifre,(identical? '+ (-> #'+ meta :name))
15:14clojurebotfalse
15:14RedNifre,(= '+ (-> #'+ meta :name))
15:14clojurebottrue
15:14RedNifrephew
15:14TimMcmatt______: subvec creates a window
15:15TimMc,(class (subvec [1 2 3 4 5] 1 2))
15:15clojurebotclojure.lang.APersistentVector$SubVector
15:15matt______TimMc: i haven't looked at the source yet, but if that's what I think it means, it's quite efficient by saying "just look between index i and j"
15:16RedNifreHow exactly is metadata connected to things?
15:16justin_smithRedNifre: it's a method in IMeta, implemented using a mutable slot in the Object usually
15:16RedNifreDoes the namespace contain a separate metadata map that has vars as keys that point to vars that point to metadata maps?
15:16amalloyjustin_smith: no way
15:16justin_smithamalloy: no?
15:17amalloythere's no mutation for metadata
15:17justin_smithoh, OK, right that makes sense, my bad
15:17amalloyIObj/withMeta returns a new version of the object with the specified metadata
15:17TimMcmatt______: Yeah, exactly. But it also holds onto the original, GC-wise, just like substring.
15:17justin_smithRedNifre: anyway, a Var implements IMeta and knows how to return its metadata
15:18justin_smithRedNifre: the namespace also holds metadata, but only about itself
15:18justin_smith,(meta *ns*)
15:18clojurebotnil
15:18RedNifrewait, does the metadata sit in the var or in the thing the var points to?
15:18TimMchttps://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/APersistentVector.java#L528
15:18justin_smithor it can, doesn't always have any
15:18amalloysorry justin_smith, 0-2 today
15:18justin_smithamalloy: oh, man
15:18amalloy,(instance? clojure.lang.IMeta #'inc)
15:18clojurebottrue
15:18amalloyer
15:18amalloywell
15:19justin_smithamalloy: Vars hold their metadata, not their namespaces, I know that much!
15:19amalloyi guess it does implement IMeta but not IObj
15:19TimMcaha
15:19amalloyso there's no with-meta for vars
15:19justin_smithgot it, I wasn't going that far
15:20RedNifre,(def pi (with-meta 2 {:description "Important number!"}))
15:20clojurebot#error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IObj"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IObj, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3657]}\n {:type java.lang.ClassCastException\n :message "java.lang.Long cannot...
15:20matt______TimMc: yeah, that makes sense. to me (which doesn't mean much), cons seems like the main hangup for vectors not being seqs.
15:20justin_smithRedNifre: 2 is not an IMeta
15:20amalloyyeah, i was confused since you were talking abotu IMeta and mutation earlier
15:20justin_smithor an IObj for that matter
15:20RedNifreWhat's IMeta and IObj?
15:21justin_smithRedNifre: the interfaces you must implement to use metadata in the normal ways
15:21justin_smithRedNifre: you might find it informative to look at (source meta) in your repl
15:23TimMcRedNifre: Metadata is stored on the object itself, it just isn't used for equality checks.
15:23backnforthCan someone else with out with my code.. I have a very basic clojure program thats giving me a, "Exception in thread "main" java.lang.RuntimeException: Map literal must contain an even number of forms". core.clj: http://pastebin.com/AGdXVGxM
15:24TimMcRedNifre: Vars are objects in their own right, and store metadata... but they also *point* oto other objects, which may or may not support metadata themselves.
15:24RedNifreOkay, so it's not truly that "meta", huh?
15:24justin_smithTimMc: just to be a donkey I could define a type right now that uses some external location to store its metadata :)
15:24backnforthWhen the remove the "listRead" function and just keep foo, the "lein run" works fine.
15:24ridcully,{:a :b :c} ; backnforth
15:24clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
15:25justin_smithbacknforth: what do you think {} does?
15:25justin_smithbacknforth: based on your indentation, I think you assume it works the way {} does in C/java/javascript
15:25backnforthSame as what imperative programs do.
15:25justin_smithin clojure it's only used for creating hash-maps
15:26backnforthYes, justin_smith
15:26justin_smith,{:a 0}
15:26clojurebot{:a 0}
15:26justin_smithbacknforth: our closest analog to {} in java is (do) but usually you don't even need to explicitly use do
15:27backnforthI love Clojure, but damn can you be complicated sometimes.
15:27RedNifreI forgot, why do I have to do (meta #'+) instead of (meta +) again? Was it because (meta +) looks for metadata in a newly created + symbol whereas (meta #'+) looks in the content of the var of the namespace?
15:27justin_smithbacknforth: this isn't complicated, it's actually simpler than the rules for other languages, just different
15:28backnforthjustin_smith: I understand
15:28justin_smithRedNifre: because somebody attached metadata to the var, but nobody attached metadata to the function, hypothetically either or neither could have metadata
15:29ridcullybacknforth: you want to find all x in inputList? then maybe filter is what you want here?
15:29justin_smith,(meta (with-meta #() {:has-meta true})) ; RedNifre
15:29clojurebot{:has-meta true}
15:29backnforthridcully: What is filter?
15:29RedNifreWhat's #() again?
15:29ridcully,(doc filter)
15:29clojurebot"([pred] [pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects. Returns a transducer when no collection is provided."
15:29justin_smith,'#()
15:29clojurebot(fn* [] ())
15:29justin_smithRedNifre: ^
15:30RedNifregaah
15:30RedNifreWhat's fn* then?
15:30justin_smithRedNifre: an implementation detail of fn
15:30RedNifreI think my head is getting full.
15:30justin_smithfair enough - pretend it is fn, it might as well be in this case
15:30justin_smithRedNifre: kudos on the curiosity, btw
15:31backnforthridcully: I'm looking to return the indexs, not the items
15:31RedNifreI'm not quite sure about the relation of # and lambdas. I mean #(println "hey") is kinda a lambda. And if #() returns () I would guess that #'+ returns '+ ? Or is that a different # ?
15:32TimMcRedNifre: #( is a single piece of syntax
15:32TimMcCheck out http://clojure.org/reader, it's called a reader macro. (No, you can't really define your own.)
15:33TimMc,'#(println "thing:" %) ; RedNifre: See how it just expands to a fn
15:33clojurebot(fn* [p1__143#] (println "thing:" p1__143#))
15:33TimMcI quoted it so you could see the expansion.
15:34RedNifre,'#()
15:34clojurebot(fn* [] ())
15:34RedNifreOkay, that one makes sense.
15:34RedNifre,#'+
15:34clojurebot#'clojure.core/+
15:34RedNifreThat # is completely unrelated to #( right?
15:35TimMcwho reads the reader
15:36TimMcRedNifre: # is a dispatch character; the next character after it determines what piece of syntax you're using.
15:38RedNifreAh. I thought that #'+ means something like # '+ i.e. there's a quoted + in there, but it's actually #' +
15:39RedNifre,(meta (var +))
15:39clojurebot{:added "1.2", :ns #object[clojure.lang.Namespace 0x7b99e11e "clojure.core"], :name +, :file "clojure/core.clj", :inline-arities #object[clojure.core$_GT_1_QMARK_ 0x3286c02d "clojure.core$_GT_1_QMARK_@3286c02d"], ...}
15:40RedNifreI think I get it now.
15:40amalloyRedNifre: right. i wouldn't be surirised to learn that the #' dispatch was chosen because it looks a bit like a different kind of quote
15:41amalloy,(:added (meta #'+)) ;; lies
15:41clojurebot"1.2"
15:41RedNifreThe ":name +" part in (var +)'s metadata implies to me that two separate keys in the namespace map will never ever point to the same var. Is that correct?
15:44RedNifreIt's all getting clearer... how do I print the current namespace's symbol-var-map ?
15:45amalloy,(take 5 (shuffle (ns-publics (the-ns 'clojure.core))))
15:45clojurebot#error {\n :cause "clojure.lang.PersistentHashMap cannot be cast to java.util.Collection"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentHashMap cannot be cast to java.util.Collection"\n :at [clojure.core$shuffle invokeStatic "core.clj" 6988]}]\n :trace\n [[clojure.core$shuffle invokeStatic "core.clj" 6988]\n [clojure.core$shuffle invoke "core.clj" 6988]\n [...
15:45amalloyso much for shuffle
15:45amalloy,(take 5 (ns-publics (the-ns 'clojure.core)))
15:45clojurebot([primitives-classnames #'clojure.core/primitives-classnames] [+' #'clojure.core/+'] [decimal? #'clojure.core/decimal?] [restart-agent #'clojure.core/restart-agent] [sort-by #'clojure.core/sort-by])
15:46RedNifre,(ns-publics *ns*)
15:46clojurebot{}
15:47RedNifre,(def content "have to be quick")
15:47clojurebot#'sandbox/content
15:47RedNifre,(ns-publics *ns*)
15:47clojurebot{content #'sandbox/content}
15:48RedNifreNow it's getting really interesting :)
15:49RedNifreHang on, if the namespace is already called "sandbox" why does it say #'sandbox/content? Isn't that kinda redundant?
15:49RedNifre(sandbox/content)
15:49RedNifre,(sandbox/content)
15:49clojurebot#error {\n :cause "java.lang.String cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval215 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval215 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval215 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java...
15:49RedNifre,sandbox/content
15:49clojurebot"have to be quick"
15:49RedNifre,content
15:49clojurebot"have to be quick"
15:50RedNifreOr is that just a feature of the ns-publics function?
15:51RedNifre,(ns-publics *ns*)
15:51clojurebot{}
15:54RedNifreAre Vars objects? If so, how can I inspect member variables and methods?
15:55TEttinger,(.hashCode +)
15:55clojurebot459507496
15:56RedNifreIs that the hashCode of the function or of the var?
15:57RedNifre,(.hashCode (var +))
15:57clojurebot1638383430
15:57RedNifreaha
15:58TEttinger,(.hashCode #'+)
15:58clojurebot1638383430
15:58TEttinger,(class #'+)
15:58clojurebotclojure.lang.Var
15:59TEttinger,(class +)
15:59clojurebotclojure.core$_PLUS_
15:59TEttingergah this is a headache
15:59RedNifreIs $_PLUS_ a fake class symbolizing the native operator?
16:00RedNifreAnyway, how to list the public member variables and methods of objects, e.g. vars?
16:01RedNifreCan I look into the + Var and see a member variable pointing to the _PLUS_ function and another member variable containing a map of the metadata?
16:05matt______RedNifre: If you eye up https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/Var.java ...
16:05sdegutisHow do you match an alphabetic character of any case using Clojure regex?
16:05sdegutisI currently have this monstrosity: #"[a-zA-Z]" but I think that's not ideal.
16:06matt______You'll see it has root, sym, and ns fields
16:06RedNifresdegutis #"(?i)[a-z]" ?
16:06sdegutisHmm but isn't there something like \w ?
16:06matt______,(.-ns #'+)
16:06clojurebot#object[clojure.lang.Namespace 0xf093f2 "clojure.core"]
16:07matt______Or to get what it points to, (.get #'+)
16:07RedNifreyeah, that's even better
16:07sdegutisNo watch, \w matches numbers too.
16:07sdegutisOh well I guess that's fine.
16:07RedNifrematt I meant from within clojure.
16:08ystaelsdegutis: #"\p{L}" matches anything with the Unicode property Letter, I think
16:08sdegutisCool, thanks.
16:08sdegutisGood day everyone.
16:08sdegutisGood day.
16:08matt______That (.get #'+) call is within clojure. perhaps i'm misunderstanding.
16:08RedNifreI meant getting a list of all public variables and methods.
16:09RedNifreA bit like when you inspect the current namespace
16:09RedNifre,(ns-public *ns*)
16:09clojurebot#error {\n :cause "Unable to resolve symbol: ns-public in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: ns-public in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: ns-pu...
16:09RedNifre,(ns-publics *ns*)
16:09clojurebot{}
16:09RedNifre,(def resetting "all the time")
16:09clojurebot#'sandbox/resetting
16:09RedNifre,(ns-publics *ns*)
16:09clojurebot{resetting #'sandbox/resetting}
16:09matt______ok, i see. i know what i'd try wouldn't work.
16:10matt______,(.getMethods (class (var x)))
16:10clojurebot#error {\n :cause "Unable to resolve var: x in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve var: x in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve var: x in this context"\n :at ...
16:10matt______Whoops
16:10matt______,(.getMethods (class (var +)))
16:10clojurebot#object["[Ljava.lang.reflect.Method;" 0x30bb067 "[Ljava.lang.reflect.Method;@30bb067"]
16:10RedNifreYeah, but that's the java way. Is there an idiomatic clojure way?
16:11matt______not that i'm aware of, but that doesn't mean there isn't.
16:12amalloysee the clojure.reflect namespace
16:12amalloyof course be aware that using reflection to peek inside of objects is taking you well outside documented APIs
16:14RedNifreWhen examining my REPL's namespace I found a clojure_two.core.proxy$java.lang.Object$SignalHandler$d8c00ec7, what's that?
16:14RedNifretype gives java.lang.Class, how can I poke it some more?
16:15RedNifre"clojure_two" is the lein project's name in which's folder I started the REPL.
16:18matt______amalloy: nice.
16:19matt______RedNifre: that's something repl-related to handling interrupts.
16:19sdegutisThe past 20 minutes have been wasted trying to parse minified CSS via regular expressions. Let that be a lesson to you.
16:20RedNifre"Never touch anything related to CSS or HTML, ever", got it.
16:22sdegutisRedNifre: On the contrary, I wrote in about 80 lines a Clojure version of SASS or Less.
16:22sdegutisRedNifre: and it's been a huge productivity boost.
16:22sdegutisRedNifre: it's the opposite thing that's proving to be a challenge: parsing minified CSS to turn it into Clojure forms.
16:22RedNifre"Become a web developer today", got it.
16:22sdegutisRedNifre: i like ur style
16:23RedNifreSo you can now write CSS in edn?
16:23sdegutisMe? Sure.
16:23sdegutisYou? No. Unless you write the same 80 lines I wrote.
16:24sdegutisAnd I get to use everything in clojure.core, too. Yay!
16:25RedNifreUh, why do you turn minified CSS into Clojure?
16:26sdegutisRedNifre: Because we didn't always start with Clojurified CSS. In the old days, I actually had to write plain literal CSS by hand.
16:26RedNifreSure, but why is it minified?
16:26sdegutisRedNifre: Now I want to convert some of that to my Clojure-CSS data structures, so that I can work more quickly with it.
16:27sdegutisRedNifre: because it was minified.
16:27RedNifre"Minifying CSS is a destructive process", got it :P
16:27sdegutisOh good point though, maybe I can find my before-minifying version of it in the git history.
16:27RedNifre:)
16:27sdegutisBut that assumes I haven't altered the minified version since minifying it.
16:27sdegutisWhich I vaguely remember maybe doing possibly.
16:28RedNifreAh, gotta go, my head is full for today.
16:29sdegutis:)
16:29RedNifreSee you guys tomorrow!
16:30sdegutisWe'll see.
17:05justin_smithamalloy: I think you were wrong and the metadata on vars is actually mutable. If I use def to define something, and then cache the var with another def, then define again and add metadata, the old var still equals the var, but the var now has different metadata, and the cached var has the metadata applied now, which makes me think mutation must have happened
17:06amalloyoh on vars it is
17:06amalloyand other refs
17:06justin_smithamalloy: yeah, maybe I was overgeneralizing before, because I was really thinking about the var case
17:06justin_smithbecause meta on def would be weird otherwise
17:07amalloywould it? def could just replace the var wholesale
17:07amalloybut i guess that would break other code that depends on this namespace
17:07amalloywho are hanging onto Var objects
17:07justin_smithit could at least, yeah
17:08justin_smitheg. running a def again would not change behavior of functions in other namespaces (unlike now), but only when you apply new metadata (which could be a line number change)
18:06matt______i'm trying to extend a protocol to hit arrays of any type. the primitives work, but Object[] is not catching things that derive from it. any insights?
18:10matt______to clarify, I can extend [Ljava.lang.Object, which works fine on (make-array java.lang.Object n), but doesn't work on (make-array java.lang.String n)
18:19justin_smithmatt______: yeah, I don't think [Ljava.lang.String; extends [Ljava.lang.Object; so the extension won't be inherited
18:20matt______But it does. https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
18:20justin_smithmatt______: what about extending java.util.List instead, and doing the extra steps to get an ArrayList or whatever?
18:21justin_smithmatt______: String does inherit Object, [Ljava.lang.String; does not extend [Ljava.lang.Object; - arrays are barely if at all OO
18:22matt______justin_smith: ah, i see what you're saying about the [L-prefixes now, ok.
18:22justin_smithmatt______: it's not even a prefix, it's part of the name of a completely different type (that isn't even a class iirc, arrays are not like other things)
18:22justin_smithor maybe it is a Class, I forget the details
18:24matt______justin_smith: i will probably end up using some sort of j.u.Collection, but was hoping for the extra performance if it wasn't too difficult.
18:27justin_smithmatt______: maybe check out Arrays/asList which returns a fixed size List that uses the array for the actual data - it's just a thin wrapper, but gives you a List which you can trivially extend with your protocol
18:27justin_smithmatt______: or just make sure all the arrays are arrays of Object I guess :)
18:27justin_smith,(into-array Object ["a" "b" "c"])
18:27clojurebot#object["[Ljava.lang.Object;" 0x449e153b "[Ljava.lang.Object;@449e153b"]
18:29justin_smithgiven this is clojure, you don't lose much by casting to Object anyway, it's not like we are being careful about our types in general.
18:30matt______justin_smith: i think you've solved it.
18:30justin_smithwhich, the asList?
18:30matt______well, i will look at it, but an array of Object
18:31justin_smithahh, yeah, if you control the creation step of the array, that might just be your guy
18:32matt______just trying to make a toy data structure that mocks how clojure's work, but based on protocols and deftypes
18:32matt______seeing as clojure uses Object[], that seems like the way to go
18:34justin_smithcool project, any plans to make a blog post or tutorial out of it?
18:35matt______umm, maybe. i wrote up a bit about protocols mostly for my friends the other day, so this will probably grow into that eventually.
18:37matt______it started as "all these interfaces have 1-3 methods. how hard could it be to write something like clojure's vector in terms of protocols/deftypes?" famous last words.
18:38justin_smithhaha, nice
18:54amalloywell, that's what cljs did already, right?
19:16matt______amalloy: yeah, except those aren't toys. :)
19:17matt______and a bit different, too. js arrays are a bit more flexible that java arrays, but they lose a lot to JS' typing.
19:36ddellacostaamalloy: is lazybot down for the count?
19:37ddellacosta>
20:11TimMcyep
20:15rhg135dead. deeeeeeeeeeeeeeeead
20:35madmax88So has anyone has problems where a jar made with `lein uberjar` isn't writing a file, but when you use `lein run`, the program will?
20:37madmax88My program also writes to a file with `lein trampoline run`. But, when running a jar with `lein uberjar`, the file gets created, but remains blank
20:49madmax88found the problem: I needed to call `(shutdown-agents)`
21:07TimMcyuuup
21:07TimMcalthough... no, I don't understand why it would have that effect
21:10matt______interesting: though small, the clj and cljs ISeq interface/protocol differ quite greatly! first, next, more, and cons in clojure compared to just first and rest in cljs.
21:15amalloywell in clojure, ISeq inherits methods from parent interfaces
21:15amalloyin cljs the protocols are a la mode
21:15amalloya la carte
21:15amalloynot covered with ice cream or modern
21:18matt______amalloy: sure, but it still adds two methods that need to be implemented and (roughly) renames another compared to the cljs version.
21:19amalloynot really. more and next are the same thing, and cons is part of another protocol that every implementation of ISeq will also implement
21:19matt______and if you look at the history, cljs did have both next and rest for a hot minute, but never had the oft-forgotten more.
21:20matt______amalloy: more and next are the same except when they're not. :)
21:20amalloywell yes
21:20matt______(not= (more (seq [])) (next (seq [])))
21:21matt______(that was news to me. maybe you even told me. :)
21:21amalloyright, more is rest, and next is next
21:21amalloyas i recall
21:23matt______still interesting to see the differences.