#clojure logs

2016-01-21

00:00luxbockfelixn_: I don't know Python that well but I think the big difference between transducers and generators is that transducers are source agnostic
00:00luxbocki.e. you can re-use the same code with sequences and channels
00:01luxbockand any other source that might come up in the future
00:02baritonehandsso defprotocol for CRUD by id semantics, where one implementation is in memory ref, future implementation is some DB?
00:02justin_smithright
00:02justin_smithand then you could even have general game-logic code that calls the methods of that protocol
00:03justin_smithand if you do it right, that game-logic code can be completely stateless / functional
00:03felixn_luxbock: if python had channels, I imagine it could work with that. generators seem to support the same API as transducers, so my thinking is just that they're built with HoF... which makes me "get it", unless what I'm saying is wrong, than I still don't get it XD
00:03justin_smitha bunch of functions that take a game, and return the next round of the game
00:04baritonehandsjustin_smith: not too much game logic, just state transitions mostly, and validation
00:04baritonehandswaiting -> playing -> done
00:04justin_smithfelixn_: for all X in clojure, X is higher order functions
00:04justin_smithbaritonehands: your state transitions are what I called logic
00:07baritonehandsjustin_smith: so for actual file organization, what would you recommend?
00:07baritonehandswhere would by protocol and its implementations go, etc.
00:08justin_smithstate management protocol gets its own namespace, each implementation of that protocol gets its own namespace, all validation and transition functions use the protocol methods but the protocol is the only code shared between any of these
00:09justin_smithso validate.clj requires state.clj and calls its methods, sql.clj requires state.clj and implements its methods, ref.clj requires state.clj and implements its methods, state.clj is very small, just defines the protocol. Then a namespace that brings the pieces together and starts all the code.
00:10baritonehandsjustin_smith: does my RESTful api fit into all of this?
00:11justin_smithit would be an implementation detail of that last namespace that it serves an API
00:11felixn_baritonehands: if you're building an API, is there a need to build turtles all the way down? you could just keep the API code flat and straight forward
00:12baritonehandsfelixn_: The api code is also very generic. If I could reuse CRUD semantics there as well it would help
00:13baritonehandsfelixn_: Current api - https://github.com/baritonehands/avalon/blob/master/src/clj/avalon/api/games.clj
00:13felixn_baritonehands: seems like a function that just builds endpoints would be sufficient
00:13felixn_you'll drastically cut down on lines of code
00:14baritonehandsfelixn_: defresource is a macro, so I think it would have to use a macro to generate
00:16justin_smithbaritonehands: my one bit of feedback on that api namespace is that there is code in that namespace that relies of the fact that the game state is in a ref
00:16justin_smithotherwise it's an api :)
00:17baritonehandsjustin_smith: I don't think it relies on games being a ref. I only ever call functions in the games namespace. Never reference games ref directly.
00:18justin_smithbaritonehands: dosync
00:18baritonehandsah, yeah, games and people need to be updated in the same transaction
00:18justin_smithfor sql this would be some transaction holding function instead
00:18justin_smithpoint is, it's a leaked detail
00:19baritonehandsjustin_smith: Yeah, hmm
00:20justin_smithif you want the implementation to be abstracted, and for it to handle state with methods owned by the data state, then I'd do the protocol as I mentioned before, and let the protocol methods handle the transaction logic as needed
00:21baritonehandsjustin_smith: so that means the protocol needs a method to create and relate two different references/db entities
00:21justin_smithprobably, yes
00:28justin_smithin fact you could simply not expose the data objects themselves, and just expose unique ids, then you don't need to expose any transaction function at all, the implementation could use transactions as apropriate, implicitly
00:35neoncontrailsIs there a better way to do this?
00:36neoncontrails,(read-string ((comp str str/lower-case) (reduce into #{} '[(:FOO :BAR :BAZ)])))
00:36clojurebot#error {\n :cause "No such namespace: str"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such namespace: str, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "No such namespace: str"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n ...
00:36neoncontrails,(read-string ((comp clojure.string clojure.string/lower-case) (reduce into #{} '[(:FOO :BAR :BAZ)])))
00:36clojurebot#error {\n :cause "clojure.string"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: clojure.string, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.ClassNotFoundException\n :message "clojure.string"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\...
00:38neoncontrailsHmmm. Not sure how to fix without importing clojure.string. But the expected output is #{:baz :bar :foo}
00:51baritonehandsjustin_smith: How do I reference the memdb implementation where I need it, but only reference the crud protocol?
00:52baritonehands(defprotocol CRUD
00:52baritonehands (create [entity])
00:52baritonehands (get [id])
00:53baritonehands (save [id updates])
00:53baritonehands (delete [id]))
00:53baritonehands,(defn create-db []
00:53baritonehands (let [db (ref {})]
00:53clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
00:53baritonehands (reify CRUD
00:53baritonehands (create [entity]
00:53baritonehands (let [id (str (java.util.UUID/randomUUID))]
00:53baritonehands (dosync (alter db assoc id (assoc entity :id id)))
00:54baritonehands entity))
00:54baritonehands (get [id]
00:54baritonehands (@db id))
00:54baritonehands (save [id updates]
00:54baritonehands (dosync (alter db update-in [id] merge updates)))
00:54baritonehands (delete [id]
00:54baritonehands (dosync (dissoc db id))))))
00:54amalloybaritonehands: long pastes to a pastebin, please, such as gist.github.com
00:56baritonehandsjustin_smith: https://gist.github.com/baritonehands/b75dc69242948308ff3d
01:02nys-where does the nrepl-port file go
02:55autogen_hey guys
03:02alex``hey there
03:43devangshahalexyakushev: i have completed the incremental build project and have it approved...
03:44devangshahhttps://github.com/celeritas9/lein-droid/tree/inc-build
03:44devangshahshall i create the PR?
03:45devangshahwhat would you suggest…? I want to have it merged.. :-)
03:59jonathanjwhat's the quickest dirtiest way to get the current system timestamp as a string?
03:59jonathanjapparently System/currentTimeMillis doesn't exist, despite javadocs telling me it does, am I missing something?
04:00jonathanjjava.lang.RuntimeException: Unable to find static field: currentTimeMillis in class java.lang.System
04:04ridcully_,(System/currentTimeMillis)
04:04clojurebot1453367011585
04:09TEttingerjonathanj: were you doing:
04:09TEttinger,System/currentTimeMillis
04:09clojurebot#error {\n :cause "Unable to find static field: currentTimeMillis in class java.lang.System"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to find static field: currentTimeMillis in class java.lang.System, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n ...
04:09TEttingerit is a static method
04:10TEttingerI can see it could have been either way though,
04:10TEttingerit makes sense as a field and method
04:29Wojciech_KWhy unquote and syntax-quote are in diffrent namespaces?
04:50neoncontrailsWojciech_K: hehehe. They're very different in scope. If you're not sure which one you want, use quote
04:51Wojciech_Kneoncontrails, I use syntax-quote with conjuction with unquote, the stange thing is
04:51Wojciech_Kunquote and quote are in clojure.core
04:52Wojciech_Kwhile syntax-quote is in clojure.tools.reader
04:52Wojciech_Ksyntax-quote and quote are more similar to each other than to unquote
04:58neoncontrailssyntax-quote resolves symbols to their values in the namespace it gets called by. Between consenting adults, it's fine, but it's possible to do horrible things to other namespaces if used wrong
05:00Wojciech_Kright, thanks
05:07jonathanjTEttinger: oh, you're probably right, I forgot to call it
05:07jonathanjhow can i create a List from Clojure?
05:07jonathanja List<String> to be precise
05:07neoncontrails,'()
05:07clojurebot()
05:07jonathanjneoncontrails: not a list, a java.util.List
05:09jonathanji have a function whose signature is List<String> can i just pass ["" ...] to that?
05:09noncomclojure seqs implement List ? i dont' remember for sure
05:10TEttinger,(java.util.ArrayList. [1 2 3])
05:10clojurebot[1 2 3]
05:10TEttinger,(java.util.ArrayList. '(1 2 3))
05:10clojurebot[1 2 3]
05:10noncomlooks like they do
05:11TEttingernot sure if vector or seq implement List. ArrayList takes a Collection IIRC, so more general
05:11TEttinger,(java.util.ArrayList. #{1 2 3})
05:11clojurebot[1 3 2]
05:11noncom,(instance? java.util.List [])
05:11clojurebottrue
05:11noncom,(instance? java.util.List '())
05:11clojurebottrue
05:11TEttingerah good then
05:12TEttinger,(instance? java.util.List [1])
05:12clojurebottrue
05:12TEttinger,(instance? java.util.List (range))
05:12clojurebottrue
05:12TEttingerwhaaaaat
05:12noncomcool. lists are rather widespread!
05:12noncomwell, can't a lazy seq implement a list ? :)
05:12TEttinger,(class (range))
05:12clojurebotclojure.lang.Iterate
05:13noncom(.add (range) 1)
05:13noncom,(.add (range) 1)
05:13clojurebot#error {\n :cause nil\n :via\n [{:type java.lang.UnsupportedOperationException\n :message nil\n :at [clojure.lang.ASeq add "ASeq.java" 151]}]\n :trace\n [[clojure.lang.ASeq add "ASeq.java" 151]\n [sun.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAccessorImpl.java" -2]\n [sun.reflect.NativeMethodAccessorImpl invoke "NativeMethodAccessorImpl.java" 57]\n [sun.reflect.DelegatingMethodA...
05:13noncomhehe
05:13jonathanjwhat is a java.util.List<String> vs a java.util.List?
05:13noncomunsup op, what i expected
05:13noncomjonathanj: same
05:13jonathanjeh?
05:13TEttingerjonathanj: generics like <String> only apply in java source, they're erased in bytecode
05:13jonathanjwhat is a java.util.List<String> vs a java.util.List<Turnip> then?
05:13noncomsame
05:13jonathanjoh okay
05:14jonathanjsorry, i don't JVM
05:14TEttingerit's weird in any language, the generic erasure
05:14noncomjonathanj: so just be aware that something may brake in runtime if the types are not friends
05:14TEttingerthere's a reason for it, I assume, but it's still weird
05:14noncomthe reason is always performance
05:16TEttingerhence why java.util.Random is at least 5x slower than a non-thread-safe linear congruential pseudo-random generator?
05:16TEttingerthe reason there is thread safety
05:17noncomhmm
05:17TEttingerLCGs are supposed to be among the fastest RNG types, which sorta helps make up for their lousy quality
05:17noncomoh maybe, i don't know this matter for sure
05:18TEttingerI've been in RNG land recently. I had a dream last night about an RNG truncating instead of casting to int, so all the numbers it made were usually "about a billion"
05:19noncom:D
05:19TEttingerthe number it returned was that text
05:19TEttingergood ol' dream code
05:19noncomomg lol :D
07:26neoncontrailsAre tail calls acceptable if the stack depth is bounded? Say, if the function is guaranteed to terminate in 3 recursions or less
07:29gfredericksneoncontrails: you're wondering about the function calling itself by name instead of using recur?
07:31neoncontrailsgfredericks: yup. Discouraged or actually risky?
07:35neoncontrailsMy recursive case-analysis works great for almost all inputs... but with an interesting exception. It fails whenever a string contains a single quotation mark , e.g. "didn't"
07:37neoncontrailsI wonder if it might be related. The individual functions I'm passing the inputs to all work, so I wonder if it's the tail call...
08:01oracle123what's CLOJURE_HOME ? I am using CLOJURE_HOME ,and let set it? but in the document for socket REPL, it gives some code to run under CLOJURE_HOME, but how to set it?
08:19ridcully_oracle123: CLOJURE_HOME is most likely an environment variable? could you please post the link, what "document" is meant?
08:20neoncontrailsFigured out the issue I was having earlier. Strings with single quotes (e.g. "didn't") break the SQL query, which makes sense. Is there a clever way to transliterate the single quote so I can recover the original string pretty easily when I need the literal value?
08:24ToxicFrogneoncontrails: use stored procedures instead, stop caring about escaping your inputs to be to SQL-safe?
08:28neoncontrailsToxicFrog: I think I'm on the right track then. The ` character doesn't appear to break SQL, is it safe to translate ' -> `?
08:28ToxicFrogneoncontrails: what? That's the complete opposite of what I suggested.
08:28neoncontrailsI know ` is special in Clojure, but I don't think that should matter in the string
08:29neoncontrailsToxicFrog: sorry could you clarify what you meant then? "Stored procedures" could mean almost anything
08:29ToxicFrogAlso, how will you handle strings that naturally include ` in them?
08:29ToxicFrogSQL stored procedures.
08:30neoncontrailsOoh I see. This is my first db app, I didn't know SQL had such things
08:30ToxicFrogAka prepared statements or parameterized queries.
08:30ToxicFrogYou write the query in SQL as a function, then call it from clojure passing in the parameters needed.
08:31ToxicFrogNo escaping is needed, the parameters are treated as raw data even if they contain characters that would normally be special to SQL.
08:33ToxicFrogIt requires a bit more setup up front, but it protects against SQL injection attacks, frees you from worrying about correctly escaping your stuff even if injection isn't a concern, and if you're worried about qps, it's also faster than assembling the query ex nihilo each time.
08:33neoncontrailsOh cool that sounds a lot more sane than what I'm currently doing. Thanks for the suggestion
08:36ToxicFrogOk, it's been a while; parameterized queries and stored procedures are related but are not the same thing.
08:36ToxicFrogStored procedures are written up front and stored in the DB.
08:36ToxicFrogParameterized queries can be created on the fly, and might look something like this (details depend on implementation):
08:37ToxicFrog(sql-query-with-params "SELECT ? FROM users WHERE name == ?" field-name user-name)
08:37ToxicFrogfield-name and user-name shouldn't be escaped and are correctly spliced into the command where the ?s appear.
08:37ToxicFrogneoncontrails: ^
08:38ToxicFrogneoncontrails: if you're using JDBC, it looks something like this: http://rosettacode.org/wiki/Parametrized_SQL_statement#Clojure
08:40neoncontrailsToxicFrog: awesome, I was just about to ask about jdbc. Thanks for the examples, this is really helpful
08:48neoncontrailsToxicFrog: Success!
08:48neoncontrailsThanks again, I had no idea this was a thing.
08:51jsabeaudryWhat's the status with incanter?
08:52oracle123about the clojure home, sorry it's not mean CLOJURE_HOME, but just clojure home, the doc says
08:52oracle123The simplest way to launch a Clojure repl is to use the following command line from within Clojure’s home directory:
08:52oracle123
08:52oracle123java -cp clojure.jar clojure.main
08:53oracle123the doc is here http://clojure.org/reference/repl_and_main#_launching_a_socket_server
08:53oracle123but I am using lein, so where should I run the java -cp clojure.jar clojure.main?
09:04jsabeaudryoracle123, if you use lein you dont need to run that
09:10oracle123I want to start up a socket REPL in clojure 1.8, there is no doc about how to start it in lein. only show how to start it up in java.
09:11winkthat's because 1.8 is like 2 days old
09:12winkI'm still trying to find out what this new socket REPL's benefits are
09:14oracle123I could telnet and send command to it. Maybe we could also do the same in Nrepl.
09:15oracle123if I start an clojure app which tightly loop doing something, if I connect to it using repl, how will it repsonse? since it's busy working in a tight loop, will it kicks off a service thread accept request and reply?
09:16ToxicFrogneoncontrails: you're welcome!
09:16pbxis there a 'lein version' equivalent that tells me the installed clojure version?
09:17oracle123lein version won't tell the version of clojure, and in the project.clj, we could define different version of clojure
09:18oracle123so it's depends on the proejct.clj, it can't give a fixed version.
09:19hyPiRionpbx: `clojure -e '(clojure-version)'` or `lein run -m clojure.main -e '(clojure-version)'`
09:19wink`lein version` would also be ambigous depends on whether it is called inside a project dir or not
09:19winki.e. would you want your project clojure version, or the one lein uses?
09:25hyPiRionoracle123: You can change the lein repl version to 1.8.0 via https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#replacing-default-repl-dependencies and then run something like `JVM_OPTS='-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}' lein repl`
09:25hyPiRionThis should start a socket which you can connect over via `telnet 127.0.0.1 5555`
09:28neoncontrailsToxicFrog: I think this should be possible, but just to make sure... any reason I couldn't just use the (sql/execute! ... ) method to insert the name, and use update! to populate the fields?
09:32ToxicFrogneoncontrails: I'm not sure what you mean by "use sql/execute! to insert the name
09:33ToxicFrogneoncontrails: that said, I have a suspicion that the example in (doc sql/update!) or https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L1042 will answer your question
09:37oracle123hi hyPiRion, what I am trying to do is, run a clojure app using lein run with remote repl enabled at home, then I could control its run time behaviou from outside, such as define as var using "def", and connect from another computer, modify the var value to change how the app runs.
09:37oracle123but using your approach, it starts a lein repl, it doesn't run my code.
09:38oracle123normally I am running using "lein run"
09:40beakyhello
09:40neoncontrailsToxicFrog: I'm wondering if I can compose those calls to avoid restructuring my map as an ordered seq. This works just fine: "(sql/execute! spec ["UPDATE mydb SET name = ?" "it's"]) Can I then populate it with (sql/update! spec :mydb {:name "it's"} ["fieldA = ?" 0]), or do the fields need to be declared in execute?
09:40beakyis clojure enterprise ready
09:41ToxicFrogneoncontrails: yes, and that's pretty much exactly the example given in (doc sql/update!)
09:42ToxicFrogIn fact, that update! call of yours basically turns into: (sql/execute! spec ["UPDATE mydb SET name = ? WHERE fieldA = ?" "it's" 0])
09:42poweredJVM is good enough for enterprises, and clojure uses JVM so I'd say yes beaky
09:57pseudonymousSo I'm trying to retrofit my project with tests. Is there any way to mock/monkeypatch calls ? I'd like not to actively call the database. I looked into bindings but those only apply to vars (not imports?) which must be declared dynamic beforehand
09:58tdammersmocking databases is hilariously cumbersome
09:58tdammersif you want simulation tests, I suggest just running them against a real database (but not one that you care about); clear it out and fill it with whatever fixture you want before running the test, and then just point your application to it
09:58tdammersfor unit tests, things are trickier
09:59pseudonymoustdammers: would not be surprised. I've given up testing many times because pretty much all my projects use databases heavily...
10:00tdammersI think a reasonable way to go about it is to wrap your database in a low-level-ish data access layer, and mock *that*
10:00tdammersand then use simulation tests against a test database to cover you bases
10:01tdammersthen the only problem you might have is that your data access layer might break in ways that you cannot easily detect using your unit tests
10:01tdammersso the trick is to keep that layer small and simple
10:16alex``guys, what's the proper way of evaluating a vector passed to a macro? i'm getting the annoying "can't create ISeq from symbol" error while trying to map through the vector
10:17justin_smithalex``: macros can only use data that is present at compile time
10:18justin_smithyou have to write the macro such that the data is only mapped over by the resulting code, and not accessed by the code generation
10:20justin_smithsimple example (defmacro m [f coll] (map f coll)) won't work because coll is accessed by map at compile time, (defmacro m [f coll] (list 'map f coll)) will work, because map is not called on coll until runtime, and coll is not accessed by the macro itself
10:21alex``understand
10:21alex``but i need to map the data to generate code
10:21justin_smithalex``: then the data needs to be present at compile time
10:22alex``if i write (defmacro [& args]) it works, but saying (defmacro [args]) doesn't
10:22jonathanj java.lang.IllegalArgumentException: No matching method: asList
10:22jonathanjtrying to do (java.util.Arrays/asList ...)
10:22jonathanjit would be useful if this error told me what it tried to match
10:23justin_smith,(java.util.Arrays/asList (into-array [1 2 3]))
10:23clojurebot[1 2 3]
10:23justin_smith,(type (java.util.Arrays/asList (into-array [1 2 3])))
10:23clojurebotjava.util.Arrays$ArrayList
10:23jonathanjoh, is there something i should know about Java varargs functions?
10:24justin_smithjonathanj: varargs methods really take all the extra args as an array
10:24jonathanjokay, good to know
10:24justin_smithbeing picky about method / function here because they are different things in this world
10:24jonathanjexcept that didn't help me debug this stupid problem *cry*
10:25jonathanj(clojure.java.io/copy) doesn't do any encoding translation, does it? it's just straight bytes from a to b?
10:25justin_smithyou can give an :encoding arg if you want it to convert
10:26justin_smithit depends on if you are going byte->byte byte->char, char->byte, char->char, iirc only the middle two need the encoding
10:26jonathanji'm trying to figure out why trying to mimic <https://github.com/apache/pdfbox/blob/2.0.0-RC2/tools/src/main/java/org/apache/pdfbox/tools/ExtractImages.java#L301&gt; is filling my file with weird junk that definitely isn't image data
10:26jonathanjjustin_smith: it's a copy from InputStream to File
10:26justin_smithbut it defaults to utf-8 which should usually be correct on sane systems
10:26jonathanjit's binary data, i definitely don't want any decoding/encoding to happen
10:26justin_smithjonathanj: inputstream to file is byte->byte so you are fine
10:27justin_smithright, you don't have chars on either side, so no worries
10:27jonathanji was hoping to hear "you're a moron, you are supposed to do X" and then i'd be done debugging this
10:27justin_smithcopy just hase the :encoding option because it can handle chars too
10:27justin_smithhaha
10:28justin_smithjonathanj: I'll look out for reasons to call you a moron then
10:28jonathanjthanks, you're a true friend
10:28jonathanjdump-1: DOS executable (device driver)
10:28jonathanj*argh*
10:29jonathanji've been fighting with pdfbox and java for a whole day trying to debug this nonsense
10:29justin_smithso the headers aren't coming out right?
10:29justin_smithhave you tried checking cmp to see where the first differing byte is?
10:29jonathanjthe data seems to be complete garbage
10:30jonathanjit seems like 99% of the file is \377
10:30jonathanjwhatever that is, probably 0xff?
10:31justin_smithoh, weird
10:31jonathanjjustin_smith: i'm trying to extract the images from a PDF, i'm just basing my code on that pdfbox code but i'm not getting anything even remotely correct
10:31ToxicFrog\377 is 0xFF in octal, yeah
10:31humanbsdSorry for the off-topic: Anyone of you people are playing sauerbraten?
10:31ToxicFrogNot-entirely-joking suggestion: shell out to pdfimages(1)
10:32justin_smithjonathanj: so I assume you have a setup where you have a pdf generated with a known image etc.
10:33jonathanjjustin_smith: it's such a long sad story, i'm trying to recompress the image in the PDF but i want the original image data so i can do something like estimate the JPEG quality (based on the qtables)
10:33jonathanjif i didn't need the original stream, i'd just use the method that gives me a BufferedImage
10:34justin_smithjonathanj: right, I was just thinking if I were trying to do this, I would start with a known image, and a pdf I made with that image in it, so I could look at differences between what is extracted and the original
10:34jonathanji think at this point, it's probably as much work to calculate the quality than to just always resave the image and throw it away if it's bigger
10:35jonathanjjustin_smith: that might help if the data resembled something other than garbage
10:35justin_smithjonathanj: well, when you have something correct to compare it too, that can only add information right?
10:35jonathanjjustin_smith: i dunno, something weird is happening, guess i'll bash my head against it
10:35jonathanjjustin_smith: i dunno, can it?
10:36jonathanjjustin_smith: for some reason this data is all exactly the same size (for all different images) but `pdfimages -list` shows them as definitely not the same size
10:36justin_smithjonathanj: the extra 0xff makes me think that somewhere something is taking bytes and making them 16 bit characters (what the vm uses internally) and then you are outputting bytes derived from those, so it would be twice as much output, and every other byte would be 0xff
10:36justin_smiththat's just a wild guess though
10:37jonathanji thought that might be the case too but then i wouldn't expect the files to all be the same size
10:37justin_smithwell, every other byte would be 0xff or 0x00 (sign extension...)
10:37justin_smithjonathanj: could be more than one thing is wrong here :)
10:38jonathanjjustin_smith: yes, i think that may well be a possibility
10:39justin_smithjonathanj: how about, for debugging purposes, make an "image" that's just 0xdeadbeef over and over, and another that is just 0xfeedcafe over and over, then try extracting the two - if the output has any relation to the input at least those would be recognizable even mangled
10:39justin_smithwell, packing them into a pdf, and then extracting them, of course
10:52jonathanjoh well i fixed it
10:52justin_smith"oh well" haha
10:53jonathanjapparently PDXObject.createInputStream creates an input stream containing the data for the entire XObject as it appears in the PDF
10:53jonathanjwhereas PDFObject.getStream.createInputStream creates an input stream for only the embedded object data
10:53justin_smithoh, nice
10:53justin_smithand also weird
10:54jonathanjyeah, i didn't even expect that to work and the docs don't really seem to explain this
10:54jonathanjthanks, justin_smith
11:00tos9is there some atriviality to apply'ing interop-ed things
11:00tos9e.g. (apply (.log js/console) whatever) or (apply .someJavaThing ...
11:04justin_smithtos9: methods are not functions, apply is for applying function args
11:05tos9justin_smith: Hm, OK -- is there another thing that means that?
11:05justin_smithamong other issues, apply takes a collection as argument, and the argument count and types will indicate different methods (unlike a function call where you might get a different arity but it is still the same function)
11:05justin_smithtos9: no
11:06tos9oh, right, multimethods... that's annoying.
11:06beakyhello
11:06beakyhow do i dockerize a clojure app
11:06justin_smithwell, multimethods are something different - but method overloading is the issue here, yes
11:06tos9justin_smith: So given some arguments, there's no generic way to call an interop callable thing with them?
11:07justin_smithbeaky: make a docker image that has a jvm in it and a script that starts up your jar?
11:07justin_smithnot that I know of
11:07ystaelbeaky: well, the simplest thing you can do is "java -jar uberjar.jar" as your CMD
11:07ystaelthere is a "clojure:1.8" image in hub
11:07justin_smithright, you hardly even need docker for that
11:08tos9justin_smith: Interesting. Thank you.
11:08justin_smithtos9: wait, you mentioned js/console above - I have been talking about jvm clojure
11:08tos9justin_smith: Yeah -- which doesn't ahve overloading, so this should be simpler there?
11:08justin_smithtos9: with js clojure, there are js methods that call a js function with a coll as args
11:08tos9justin_smith: (But I somewhat intentionally asked it generically)
11:08justin_smithforget how it works, but it is a thing
11:08justin_smithright, not generically a thing, won't work on the jvm, but js has a way to do it
11:08tos9Yeah I can probably use like .apply from JS land
11:09tos9OK, cool
11:13beakyah
11:16tos9How to I tell lein to put ~/.lein someplace else
11:16tos9man lein is not a thing :/
11:17justin_smithtos9: lein help
11:18tos9justin_smith: it just prints usage info, and lein readme just prints.. the readme. I don't see anything explaining any environment variables lein respects, or config info, etc. etc.
11:21justin_smithtos9: config info is partially in lein help profiles, but what you want is in the sample project.clj (and yes it should also be in regular docs) https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L489
11:21tos9Ah, awesome.
11:21tos9justin_smith: Thank you!
11:22justin_smithtos9: see also "lein help sample | grep HOME"
11:24justin_smith"lein help sample" is full of amazing info (though it might be more convenient to just go to that github page)
11:25tos9yeah I read it a few times yesterday but was too overwhelmed at the time by all the settings to play with :)
11:25tos9I'll have to read it again when I shed some noobiness.
11:25justin_smithheh, and of course the env vars are at the bottom
11:25justin_smithtos9: it's a reference document, I've never read it start to finish
11:25justin_smithjust like most man pages in fact
11:28jonathanji really wish i could map (.foo) without a lambda/anonymous function
11:29justin_smithjonathanj: blame java for methods not being first class data, and needing some Object to carry them
11:30justin_smithon a bytecode level a method isn't something you can pass as an arg
11:32justin_smithjonathanj: the obvious rejoinder there is that clojure could wrap it for convenience reasons, but in general clj likes to stay "close to the metal" in terms of how it uses the vm, and not use implicit abstractions for interop
11:34jonathanjactually, now that you say that, istr some kind of function to turn a method into a clojure function, but i can't remember the name (or exactly what it does)
11:34beakyi love the cloud
11:34gfredericks#method .foo
11:34beakyoops wrong channel
11:34gfredericks,(doc memfn)
11:34clojurebot"([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn. name may be type-hinted with the method receiver's type in order to avoid reflective calls."
11:34jonathanjthat's the one
11:34justin_smithmemfn is depricated though
11:34justin_smithit's better to just use #(.foo %)
11:35gfredericksbecause of default-reflection?
11:35gfrederickswell that's no different from #(.foo %) I guess
11:35gfredericksI'd never heard that it was deprecated
11:35justin_smithsomehow #(.foo %) can be optimized where memfn isn't, I forget the details it's been ages since I learned about this...
11:36gfrederickssurely you could implement memfn with #()
11:36justin_smithgfredericks: now I'm wondering if it was "deprecated" or just "there's no case where using it is better than just using a lambda"
11:37gfredericksthat sounds a lot more likely
11:37gfredericksit makes you feel clever
12:51cap10morgan_Is clojurebot's source code on GitHub somewhere?
12:51justin_smithyes
12:51justin_smithhttps://github.com/hiredman/clojurebot
12:51cap10morganjustin_smith: cool, was just going to ask if that was the one. thanks!
14:14elvis4526Is there an alternative to this: (alter-var-root #'get-all-users (fn [of] (fn [request] "poo")))
14:14elvis4526
14:14elvis4526Im the repl and i want to redefine a var assigned to a function inside a namespace
14:15elvis4526(or perhaps its the function that is assigned to the var)
14:16justin_smithelvis4526: (intern 'some-ns 'some-symbol value)
14:17justin_smithand you can also do (in-ns 'random-ns) (def ...) (in-ns 'other-ns)
14:18justin_smith,(intern 'some-ns 'some-var 42)
14:18clojurebot#error {\n :cause "No namespace: some-ns found"\n :via\n [{:type java.lang.Exception\n :message "No namespace: some-ns found"\n :at [clojure.core$the_ns invokeStatic "core.clj" 4032]}]\n :trace\n [[clojure.core$the_ns invokeStatic "core.clj" 4032]\n [clojure.core$intern invokeStatic "core.clj" 6071]\n [clojure.core$intern invoke "core.clj" 6071]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FIL...
14:18justin_smithoops!
14:18justin_smith,(create-ns 'some-ns)
14:18clojurebot#object[clojure.lang.Namespace 0x1b74fd63 "some-ns"]
14:18justin_smith,(intern 'some-ns 'some-var 42)
14:18clojurebot#'some-ns/some-var
14:19justin_smith,some-ns/some-var
14:19clojurebot42
14:34elvis4526Ha I didn't know changing it with def was allowed when you were in the same namespace
14:35elvis4526its working perfectly thanks
14:35justin_smithcool
14:35justin_smithelvis4526: yeah, that's why the repl is so useful, being able to redefine in a running system just by running the new code
14:54justin_smithplaying with this new socket server thing in 1.8, it's pretty cool, especially being able to run a repl just based on a command line arg with no code added to the codebase
15:00wht_rbtprobably a newb question here -- does clojure have a way to prompt a user for a password on the console, so that the user's input does not echo?
15:03Shayanjmwht_rbt: not sure about Clojure specifically, but Java has java.io.Console.readPassword
15:03domokatoline-seq makes a lazy sequence - does that mean it reads from a file when the elements are gotten from the resulting seq?
15:04amalloydomokato: yes
15:04domokatoamalloy: th
15:04domokatoamalloy: thx
15:08wht_rbtChayanjm: thnx - I went down that rabbit hole, but ended up getting strange results
15:08wht_rbtsimilar to this: https://groups.google.com/forum/#!topic/clojure/hlv2m00hhgU
15:08wht_rbtSystem.console was coming back null for me
15:24tos9I have 4 channels which contain 1 value each. I want to join the 4 values -- what's the easiest way to do that?
15:24tos9I see async/merge for one way?
15:24tos9join the 4 values as 1 str
15:33optikalmousedoes clojure have the same Environment stuff as Common Lisp? like trace/untrace, dribble, etc.?
15:33elvis4526tos9: i'd use async/merge yes
15:33optikalmouseor actually man I would love to have APROPOS
15:34jonathanj,(doc apropos)
15:34clojurebot"([str-or-pattern]); Given a regular expression or stringable thing, return a seq of all public definitions in all currently-loaded namespaces that match the str-or-pattern."
15:34tos9elvis4526: I must be doing that wrong I think, because (go (let [strs (<! (async/map str (async/merge comments)))] (println strs))) gives me Error: [object Object] is not ISeqable
15:35elvis4526tos9: is comments a list of channels ?
15:36tos9elvis4526: yes (although let me print it to be sure)
15:37tos9it's: (#object[cljs.core.async.impl.channels.ManyToManyChannel] #object[cljs.core.async.impl.channels.ManyToManyChannel])
15:37jonathanjmerge returns one channel
15:37jonathanjmap expects a seq
15:37tos9a ha
15:37elvis4526thats what i was about to say
15:37elvis4526Usage: (map f chs)
15:37elvis4526
15:39tos9does that mean that I want (reduce str "" (async/merge comments)) then? Or does it mean I'm highly confused (Which I probably am).
15:39jonathanjso comments is a bunch of channels that each return one comment? more than one comment?
15:39tos9jonathanj: they're a bunch of channels, each has 1 comment in it, yeah.
15:39jonathanjtos9: merge returns a channel, clojure.core/reduce doesn't know how to reduce a channel, does it?
15:40tos9jonathanj: no, but along with like a <!
15:40tos9oh hm no
15:40tos9yeah that doesn't work.
15:40jonathanjso what are you trying to do?
15:40tos9jonathanj: I have those 4 channels which contain 1 comment each which are strs. I want 1 str which is the concat of those 4 strs.
15:40tos9(I'll want to interleave some other HTML, but first I want to see ^)
15:41jonathanji think a transducer might make building that processing chain easier
15:41tos9Yeah so it seeeems likely that that's true, and also it seems like cljs-http can *take* a channel rather than returning one, in which case I could probably get it to put my responses all on the same channel
15:41beakyhelllo
15:41beakyis om production ready
15:42elvis4526tos9: You could loop over the output channel with go-loop, collect each string and concat them for each iterations
15:42tos9But I'm trying not to change my approach in a way that complicates it, I'm only like 3 hours into clojure programming :P
15:42jonathanjtos9: sorry i barely know anything about core.async so i can't really suggest a concrete solution
15:42domokatomap-indexed should perform better than dotimes + nth, right?
15:42tos9elvis4526: The merged one? Cool that sounds like a thing I might be able to do. Will give it a shot.
15:42tos9jonathanj: Have you seen the evil thing I'm working on?
15:42elvis4526tos9: yes the merged one
15:43jonathanjtos9: no, sorry i just started reading IRC
15:43tos9jonathanj: Well you will soon, it's complete techcrap :)
15:54mistnimhi, what is clojure commonly used for? web development? anything else?
15:55tos9what's wrong with my syntax here: https://github.com/Julian/sphinxcontrib-githubcomments/blob/master/src-cljs/githubcomments/core.cljs#L10-L14
15:55tos9clojure is telling me I'm not allowed to recur there
15:56optikalmousejonathanj: thx!
15:58jonathanjtos9: i don't think you (recur) in a (go-loop)
15:58hiredmanof course you can
15:59tos9jonathanj: I'm copying the example at https://clojuredocs.org/clojure.core.async/go-loop
15:59tos9or at least I think I am
15:59jonathanjoh you do, sorry, the docs are just really sparse
16:00hiredmantos9: replace go-loop with (go (loop [ ...] ...)) and then ask yourself what is wrong
16:00tos9hiredman: I did, and then got "wrong number of arguments to recur
16:00hiredmantos9: do you know how loop/recur works?
16:00tos9hiredman: I do not!
16:00tos9I'm reading the docs on loop now
16:00hiredmantos9: good
16:01tos9Oh I see.
16:01tos9I need to pass the 2 new values.
16:06elvis4526tos9: there is probably a better way to do it, but this is what I had in mind https://gist.github.com/j-allard/1efb23c2e13af35ed490
16:09justin_smithjonathanj: regarding "map expects a seq" - the two argument version of map doesn't need a seq, and can be applied as a transducer on a channel
16:15justin_smith,(sequence (map inc) (range 10))
16:15clojurebot(1 2 3 4 5 ...)
16:15justin_smithand can also use a seq
16:16jonathanjjustin_smith: i meant (clojure.core.async/map) which was the function in question, i was just lazy
16:16justin_smithjonathanj: clojure.core.async/map is depricated
16:16justin_smithit's just map now
16:16jonathanjmmm, the docs don't say it's deprecated
16:16jonathanjso how do you apply a transducer to a channel?
16:17justin_smithjonathanj: sorry, it's map> and map< that are depricated, map is still legit
16:18justin_smithjonathanj: you can provide a transducer as an optional arg to a channel
16:18jonathanjhmm, that seems kind of inconvenient, like if you merge, how do you apply a transducer to a channel you didn't create?
16:20justin_smithjonathanj: by piping onto a channel you did create, which has the transforms you want
16:20justin_smithor using pipeline
16:21justin_smiththis is how we replace all the "Depricated - this function will be removed. Use transducer instead" functions
16:27amalloyjustin_smith: replace them with "Deprecated"?
16:46rcassidybeen using vim&fireplace with clojure and it's been awesome, but i'm missing one feature
16:49rcassidyjumping to definition of a symbol is easy -- any way to find usage of a symbol across files? something like ctags does in vim for :ts ?
16:55justin_smithrcassidy: sad but true, I usually just reply on grep -Rn ...
16:56justin_smith*rely
16:56justin_smithemacs has a mode where it lists the hits and there's a keyboard shortcut to visit the next hit etc.
16:56justin_smithI'm sure vim has some sort of grep / silver searcher plugin
16:57rcassidyjustin_smith: thanks, that's what I'm doing too re: grep
16:57rcassidyctags was nice for c++ in vim, can easily find all occurrences of a symbol and hop around based on the tag... sad there's not a similar thing that fits into fireplace
17:01justin_smithrcassidy: I've never seen tags for lisps like for algol family languages, I don't know if that's coincidence or some property of lispy languages that makes tags less useful or what
17:02rcassidyi saw some ctags syntax regexes to add support for tags, but doing c-style tags on top of fireplace just for one feature feels like overkill
17:02rcassidyand I don't feel like setting up my tagfile right now at work :p
17:02rcassidys/support for tags/support for clojure tags/
17:04justin_smithrcassidy: oh look, you can generate a tags file for clojure with etags http://stackoverflow.com/questions/1481842/clojure-emacs-etags
17:05justin_smithrcassidy: more relevant https://gist.github.com/vladh/1e1e7bc5eb274235e0b9
17:05rcassidyfound those :)
17:05rcassidylike I said, I could just straight use ctags, but that's a lot of cruft just to avoid grepping
17:06rcassidymaybe i'll give in eventually
17:06justin_smithtrue that
17:06justin_smitheventually CPU / disk speed improvement beats the old clever caching maybe
17:13tos9elvis4526: Sorry - I jumped into a meeting -- thanks I think that's really helpful
17:14tos9I still can't get go-loop to work, and probably I don't understand scoping 100% yet
17:14tos9But I've just tried https://github.com/Julian/sphinxcontrib-githubcomments/blob/master/src-cljs/githubcomments/core.cljs#L10-L14 which appears to do *something*, although it also pegs a CPU, so maybe my channels aren't closing after the value pops out
17:15justin_smithtos9: why do you have an infinite loop inside your set! call?
17:16justin_smiththe loop never returns, so set! never gets called
17:16tos9a ha -- OK, so I guess I need to figure out how <! tells me that there's nothing left to read then?
17:16justin_smithit will return nil if the channel is closed
17:17tos9Ah cool! OK, /me tries.
17:17justin_smiththen you can conditionally recur only if hte channel is open
17:17justin_smithand then close the channel on the writing end
17:19tos9I wish I knew the paredit things already, it'd make editing not be completely tedious :P
17:22tos9! Amazing :) it works.
17:22justin_smithnice
17:26tos9justin_smith: http://platform-guild.readthedocs.org/en/latest/code-review.html
17:27tos9the result of my evil handiwork (so far, still needs lots of work)
17:27tos9but that bottom text box (the gray one) is what I just spent 2 evil days on -- bringing github comments onto a source doc at the client side, so thanks, appreciated
17:27justin_smithvery cool
17:27tos9Now I just need to work on styling and some other nonsense.
17:28tos9And also on figuring out why apparently these AJAX requests aren't automatically cached by browsers :/
17:29tos9Are there any general tips for making https://github.com/Julian/sphinxcontrib-githubcomments/blob/master/src-cljs/githubcomments/core.cljs look more idiomatic overall?
17:32justin_smithtos9: why are you calling apply on line 31 instead of just calling the function?
17:33tos9because it started off as dorun and as a thing with side effects (to print), fixing now :)
18:30justin_smithtos9: I think your loop could be (reduce str "" comments)
18:30justin_smithasync/reduce that is
18:34justin_smithtos9: https://gist.github.com/noisesmith/4fb0b6fec934128d89e1
18:35justin_smithtotally works as a async/reduce call, which is cool
18:35justin_smithreduce doesn't even need to be in a go block, which makes sense
18:57nuttynutnuthi
18:59nuttynutnutis there a simple way to find the longest end subsequence of a number? like for 32541 it would be 541
18:59nuttynutnutfor 1428531 it would be 8531, for 61256 it would just be 6
18:59nuttynutnuti came up with one solution but i was wondering if there was a better way.. one sec lemme code it up
19:06tos9justin_smith: Ah awesome! That does work -- I tried it before but I didn't realize async/reduce returns a channel
19:08tos9justin_smith: it doesn't look like cljs.core.async has <!! so I think I do need to keep the go blcok though?
19:09justin_smithtos9: oh, I only used <!! and >!! so that I could use the repl interactively
19:09justin_smithtos9: in the real code do all the puts and takes in go blocks
19:10tos9justin_smith: Ah, OK, good.
19:13nuttynutnutok back
19:13nuttynutnutthat took longer than expected
19:13nuttynutnutso i came up with something like this but there must be a more elegant way, right? (distinct (flatten (take-while (fn [[l r]] (> (int r) (int l))) (partition 2 1 (reverse (str 32541))))))
19:15justin_smithI think you'd want something like (map first ...) or (map second ...) rather than (distinct (flatten ...))
19:15nuttynutnutthat doesnt work
19:16nuttynutnutit only gives 14 and not 145
19:16nuttynutnutoh and yeah it needs to be 541 so then i need to reverse
19:17nuttynutnutso it'd be .. (reverse (distinct (flatten (take-while (fn [[l r]] (> (int r) (int l))) (partition 2 1 (reverse (str 32541)))))))
19:17nuttynutnutgross
19:17justin_smithand that's still giving chars and not numbers
19:18nuttynutnutyeah
19:19justin_smith,(defn rev-digits [n] (->> n (iterate #(quot % 10)) (take-while (complement zero?)) (map #(rem % 10))))
19:19clojurebot#'sandbox/rev-digits
19:19justin_smith,(let [digits (rev-digits 52741)] (reduce (fn [digs d] (if (< d (first digs)) digs (conj digs d))) (take 1 digits) (rest digits)))
19:19clojurebot(7 4 1)
19:20justin_smithoops!
19:20justin_smith,(let [digits (rev-digits 52741)] (reduce (fn [digs d] (if (<= d (first digs)) (reduced digs) (conj digs d))) (take 1 digits) (rest digits)))
19:20clojurebot(7 4 1)
19:21justin_smithbonus: real math instead of string hacks
19:22justin_smithnuttynutnut: also, that version finds the sequence starting at the end, which is guaranteed to do the minimum amount of checks
19:23nuttynutnutyeah pretty cool
19:23nuttynutnutclojure is missing a function
19:23nuttynutnutthere should be something in the core that lets you compare two elements at a time
19:23nuttynutnutthere's so many times in a lot of these 4clojure problems that i have to compare the current item and the next item
19:24nuttynutnuthave to end up doing some weird partition hack and then extracting the result from the vector later
19:24justin_smithor a reduce
19:24nuttynutnutyeah but that's ugly too
19:24ystaelnuttynutnut: reduce is love, reduce is life
19:24nuttynutnutanything can be done with reduce
19:24nuttynutnutreduce is just like doing a for loop in imperative
19:24justin_smith(inc ystael)
19:24nuttynutnuthigher abstractions are better
19:25justin_smithnuttynutnut: it's like a list comprehension that iterates over elements of one sequence and can optionally exit early
19:25justin_smithit's no for loop
19:25justin_smithor even clojure's for for that matter
19:26nuttynutnutit's just a loop with an accumulator
19:26justin_smithno it's not, because it is guaranteed to only run as many cycles as the number of elements in your input
19:26justin_smithit's not an arbitrary loop
19:26justin_smithwe have "loop" for that
19:27ystaelnuttynutnut: possibly not coincidentally, a computer is a loop (device for performing repetitive computation) with an accumulator (memory)
19:27nuttynutnutlike.. something like this would be cool (taking-peak #(< %1 %2) [1 2 5 4 3])
19:27nuttynutnutactually even better
19:27nuttynutnutan overload for take, filter, etc. that take 2 parameters instead of one
19:27justin_smithnuttynutnut: (reduce max 1 2 3 4 5)
19:27nuttynutnutso you could optionally look at the next item
19:28nuttynutnut?
19:28nuttynutnutthat doesnt run
19:28justin_smithnuttynutnut: (reduce max [1 2 3 4 5])
19:28justin_smithwhich is the same as apply max, of course
19:28justin_smithunless that's not what you mean by "taking-peak"
19:28nuttynutnuttaking-peak is just like take-while
19:29justin_smithoh, yeah mean peek
19:29nuttynutnutis it possible to add an overload to functions like take-while so their function takes 2 arguments instead of one?
19:29nuttynutnutso you could optionally use the take-while that just looks at the current value
19:29nuttynutnutor the one that looks at both
19:30nuttynutnuti think that'd be pretty cool
19:30nuttynutnutso often with these functions i need to look at the next or previous items in the sequence as well
19:30nuttynutnutand you can't so you have to use some hacky reduce
19:30nuttynutnutcould be added to filter, reduce, map, etc.
19:30TEttingeror defined in a lib
19:30ystaelnuttynutnut: it would be more coherent to mimic the behavior of map, which treats all its arguments after the function as successive arguments to the function
19:31TEttinger,(map + [1 2 3] [20 40 60])
19:31clojurebot(21 42 63)
19:31nuttynutnutyeah that could be a problem
19:31TEttingerone way you could do it is with...
19:32TEttinger,(defn map-ahead [f coll] (map f coll (rest coll)))
19:32clojurebot#'sandbox/map-ahead
19:32amalloynuttynutnut: don't do it with special overloads to all sequence functions, just use partitino
19:32TEttingerwhere the second argument to f is the next element in the collection, and the last element isn't used
19:32amalloy,(partition 2 1 (range 5))
19:32nuttynutnutit's messy though
19:33clojurebot((0 1) (1 2) (2 3) (3 4))
19:33nuttynutnutbecause you have to extract the values later
19:34justin_smithsounds like a job for a monad
19:34nuttynutnuti showed the code above that was required to get 541 from 32541
19:34nuttynutnut(reverse (distinct (flatten (take-while (fn [[l r]] (> (int r) (int l))) (partition 2 1 (reverse (str 32541)))))))
19:34nuttynutnutwith this it could instead be something like..
19:34TEttinger,(defn map-ahead [f coll] (map f coll (rest (cycle coll))))
19:34clojurebot#'sandbox/map-ahead
19:34justin_smithnuttynutnut: flatten is 100x as hacky as the worst reduce
19:34nuttynutnut(take-while #(< %1 %2) (reverse (str 32541)))
19:34nuttynutnutor something like that
19:35nuttynutnutwell yeah flatten is bad too
19:35nuttynutnutim saying there's no good solution
19:35nuttynutnutthat's concise
19:35amalloyjustin_smith: probably a comonad actually, right? like that's what zippers are for
19:35nuttynutnutor if there is i'd like to be made aware of it
19:35justin_smithamalloy: that's over my head still, but sure, sounds legit
19:35amalloyhaha
19:36TEttingerwhat does that function even do, nuttynutnut? finds an increasing section of a sequence starting from the back?
19:36nuttynutnutyeah
19:36nuttynutnutthe reason im trying to make it:
19:36amalloywell mine too, mostly. but as i understand zippers, a zipper on a list is a "pointer" to one specific element in the overall list, with a (get) function to read the current element, and functions (left) and (right) to give you a new zipper with a new focus
19:36justin_smithTEttinger: digits of a number actually
19:37nuttynutnuthttp://stackoverflow.com/questions/352203/generating-permutations-lazily control+f for "Find the longest "tail" that is ordered in decreasing order. (The "541" part.)"
19:37justin_smithamalloy: oh yeah, nuttynutnut could totally be using a zipper
19:37nuttynutnuttrying to code that first step concisely
19:37nuttynutnutzippers huh?
19:37nuttynutnutive heard of them but no idea what they do
19:37nuttynutnutis that a good solution to this?
19:37justin_smithnuttynutnut: yeah, check the api - from a given position you can look at the values to the left and right etc.
19:37nuttynutnuto
19:37nuttynutnutthats perfect
19:38justin_smithor even up and down in a tree
19:38nuttynutnutok ill look in to those
19:39TEttinger,(reductions #(or (< %1 %2) (reduced %1)) (reverse "32541"))
19:39clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number>
19:40justin_smithI was just playing with the new clojure 1.8 socket repl, accidentally printed an infinite lazy seq, and Control-C just locked up the terminal until I shut down the socket server
19:40TEttinger,(reductions #(or (< %1 %2) (reduced %1)) (map int (reverse "32541")))
19:40clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number>
19:40TEttingergah
19:40TEttinger,(reductions #(if (< %1 %2) %1 (reduced %1)) (map int (reverse "32541")))
19:40clojurebot(49 49 49 49 49)
19:40TEttingerright.
19:40irctcIs there a function like map, but where I can discard some elements? A kind of combined remove+map where I would remove elements I don't need, and transform the ones I do at the same time?
19:40nuttynutnutyeah that was messing with me earlier too
19:40nuttynutnutlol
19:40nuttynutnutfilter?
19:40clojurebotfilter is not map
19:40justin_smithirctc: mapcat
19:41justin_smithirctc: or keep
19:41justin_smith(doc keep)
19:41irctchum, I'll have a look at all of these
19:41clojurebot"([f] [f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects. Returns a transducer when no collection is provided."
19:41justin_smithkeep if you never want a nil element
19:42justin_smithmapcat is more general and allows nil elements and also removing elements
19:42justin_smith(but it's a little clumsier)
19:42irctcKeep is exactly what I want thanks
19:43justin_smith,(mapcat #(cond (even? %) [%] (> 10 %) [nil] :true nil) [2 3 4 12 13 14])
19:43clojurebot(2 nil 4 12 14)
19:44justin_smithkeep couldn't do that because it eats all nils (but clearly keep works for your case)
19:44didibusYa, I won't have nils
19:44didibusBut it's good to know mapcat is there if I ever need it
19:45justin_smithusually people only think of mapcat as combining multiple results per item, but really it's the options for "0 or more results per item"
19:48didibusYa, I'm still slowly learning about all the core functions, there's just so many awesome jewel
19:52TEttinger,(reduce #(if (< (or (first %1) -1) %2) (apply vector %2 %1) (reduced %1)) [] (map #(Character/digit % 10) (reverse "32541")))
19:52TEttingerseems too long
19:52clojurebot[5 4 1]
19:54nuttynutnutyeah still pretty long
20:02amalloymapcat is a primitive operation powerful enough to implement map, filter, keep, and a whole bunch of other stuff in terms of
20:02justin_smithyupyup
20:12neoncontrailsSpeaking of core functions. I'm working on something that requires taking a lot of set intersections, lots of set membership queries. I need persistent collections, rather than the lazy ones I keep creating with map
20:13justin_smith,(into #{} (map #(* % %)) [1 2 3 4]) ; like this?
20:13clojurebot#{1 4 9 16}
20:13neoncontrailsIs there an eager alternative? A better core function to use when you generally need to build the structure in memory?
20:14justin_smithneoncontrails: that's what the map transducer used with into is for, yes
20:14justin_smiththe above builds a set with the help of the transducing function generated by the single arity version of map
20:14justin_smith*single arg arity of map
20:15neoncontrailsjustin_smith: interesting. I didn't know into had that property, that's useful
20:16justin_smithneoncontrails: yeah, the idea with the whole transducers thing is not needing to generate a lazy seq if you know you already need a different data structure, and into is one of the most straightforward ways to use a transducer
20:18neoncontrailsMaybe today is the day I'll learn what transducers are. I read up on them a few months ago, and there was lots of head whooshing
20:27justin_smithneoncontrails: it should be straightforward to parse out what into does with a single transducer arg (like (map f) or (filter f)) with trial and error
20:28justin_smithafter that comes composing transducers, etc.
20:37neoncontrailsIt is with consistent practice, yeah. There's an interesting variety of types in Clojure that makes the patterns a little harder to see than in Scheme
20:38neoncontrailsBut it's a nice variety. I dig it
22:36rhg135any idea why a put! to a manifold stream would immediatly return false if it's not closed
23:26bjaany idea why the .setBounds in this snippet seems to be underestimating the height of my images consistently? https://gist.github.com/555c96a26dab2483c671
23:26bjathis is probably just a swing 101 question, not precisely a clojure question, although it is in clojure
23:38John[Lisbeth]where is the bin for ghci located in ubuntu?
23:39John[Lisbeth]oops
23:51rhg135https://www.refheap.com/113945 this is really perplexing, it was working before and I don't recall changing the relevant code