#clojure logs

2014-10-21

00:31eggheadis there a good lib for wrapping up apis as cli apps in clj?
00:34justin_smithyou should be able to do most of it with cheshire, clj-http, and tools.cli
00:35justin_smithmaybe grenchman if the load-up time of an uberjar is still too long
00:40trx|2egghead: I use swig for accessing shared libraries (.dll,.so) from clojure. Swig is a command line tool but it wouldn't be difficult to create a custom leiningen plugin to run swig scripts from the command line.
00:41rritochegghead: the problem I run into is with clojure class loaders so you need to register the generated .so or .dll from a static initializer
00:42rritocheggghead: because of that you typically need to adjust the .java files generated by swig before you compile them
00:43justin_smithrritoch: oh, you think he means library apis, I thought he meant http apis
00:44rritochjusting_smith: now that you mention it, he didn't specify
00:44egghead:)
00:45eggheadas pitiful as the jvm is for cli apps, tools.cli is closest to what I was looking for with my vague question, just was wondering if there was anything ~fancier~
00:47justin_smithfancier means - integration with other tools? cursor control? colorful output?
00:49eggheadi dunno what I was thinking justin_smith, I guess *in* and clojure.tools.cli are all I need
00:50justin_smithegghead: you'll likely find *out* and *err* pretty handy too
00:50egghead:p
00:51justin_smithplus stuff from clojure.string if you are taking input from stdin that comes from other tools, likely
00:56rritochDoes anyone have any suggestions for AOT compiled scripts? I'm developing a clojure web application framework and it seems I made a major performance mistake in the dispatcher. To mimic the behavior of other script languages like PHP I made a (script ...) macro which runs during compilation IF a dispatch variable is set as true.
00:56arrdemtbaldridge: watching the commit stream for pixie is an inordinate amount of fun :D
00:57arrdemrritoch: example use case?
00:58arrdemrritoch: my gut is that you're doing it wrong, but I'd like to quantify that
00:58rritochHere is a condensed version of the macro (defmacro script [docstr & body] `(if *dispatch* ~(conj body 'do)))
00:59rritochUsage could be ... (script "HelloWorld" (println "hello world!"))
01:00rritochIn the actual macro there is also some logging which dumps something like "running script: " docstr...
01:00justin_smithand the "script" would be something that optionally occurs as a stateful action during application template rendering while creating a project?
01:01rritochThe script is launched with either load-file or load-reader depending on if it is a local resource or a remote (URL)
01:01justin_smithin what context? when is the script run?
01:02rritochThe script is run from the servlet, this particular servlet sends all requests through the doPost method of the servlet.
01:02justin_smithOK that's a really bad idea
01:03rritochYep, I wanted to mimic the behavior of PHP before I realized how slow it would be
01:03justin_smiththere is a lot of overhead on eval
01:03justin_smithyeah, eval is slow
01:03rritochNow I want to undo that decision, preferably by just changing the macro and possibly the deployment method
01:03justin_smithwhat you want is one server process that stays running for months (maybe even years) at a time, that has a function that gets called for each request
01:04justin_smithinstead of loading a script, call a function in a handler namespace
01:04justin_smithso convert the load-script logic to an invoke-function logic
01:05justin_smiththis will involve defining the namespaces (of course), requiring them from your main servelet definition, and then invoking their functions - instead of having a file that imperatively does a sequence of steps, have a file that defines a function which another namespace can invoke
01:05rritochHere is the complexity. Say there are more than one scripts in a single CLJ, this creates an issue since it would need to have multiple functions
01:05justin_smithrritoch: ok, that is the normal way to do clojure
01:06justin_smithI have namespaces with hundreds of functions in them
01:06justin_smithwell, at least two
01:06rritochWell, the point of this is to smooth the transition for developers coming from other script languages, such as PHP, CGI (Perl), etc.
01:07justin_smiththat's kind of odd
01:07rritochI was thinking that maybe I could define an atom holding an array, and put the randomly generated function names in that array, and have a single initializer
01:07justin_smithwhy would you randomly generate function names?
01:08justin_smithand why would putting the functions in an array be in any way useful?
01:08rritochThe problem is the macro expansion would happen for each script in the file so I'm not sure if it's possible to have a different expansion for the first (and/or last) expansion in a given file.
01:08rritochIt is useful because it simulates running a Perl or PHP script
01:10arrdemOkay so lemme get this straight
01:10arrdemyou have this (script) thing, that runs... when... at load time? at -main invocation time? at AOT time?
01:10rritochSo the purpose of using randomly generated function names is to avoid collisions between scripts, than there would be a single function like __run_scripts whic would run all of the scripts
01:10rritochBut defining __run_scripts should only happen in one of the macro expansions
01:10arrdemthat's a terrible reason. we have gensym. function name collisions are literally impossible.
01:11justin_smithrritoch: if they are in an array, they don't need any names at all
01:11rritocharrdem: Yeah, I'm aware of gensym, it is what I plan on using
01:11arrdemrritoch: so... why do you have worries about name collision?
01:12justin_smith,((juxt #(+ % 8) #(* % 3) #(mod % 2)) 12) ; rritoch - none of these have names, nor do they need them. They are all functions.
01:12rritochBut I would need to collect the list of functions which need to be run from the single script execution function (__run_sccripts)
01:12clojurebot[20 36 0]
01:13arrdemWhy? a "script" is really just a function that sequentially calls a bunch of other anonymous functions in a straight line block..
01:13justin_smithrritoch: you can have a list of functions without any names
01:14rritochOk. so say I have some index.clj script setup which has 3 scripts in it, an init script, a form validation script and an output generation script as would be typical for a single page web application
01:15justin_smithwhat differentiates a script from a function?
01:15rritochThese need to be run in order, but the dispatcher has no idea about what index.clj is going to contain, or what functions it will contain
01:15arrdemthis (if *script ... ) macro thing apparently
01:15rritocharrdem: yes, basically
01:15arrdemrritoch: so... you have three functions in a file... go on...
01:16rritochBut the macro expansion just surrounds the code in an (if *dispatch* (do ...code...)
01:16rritochSo as of now it runs at load time
01:16rritochBut I want to AOT and simulate this same behavior
01:16rritochAssuming it's possible
01:16justin_smithrritoch: is the condition in the macro, or in the output of the macro?
01:17rritochIn the output of the macro
01:17justin_smithif the condition is in the output of the macro, and it checks *dispatch* at runtime, you are fine
01:17justin_smithjust make sure *dispatch* is not resolved during compile time
01:17rritochYeah, that is how it currently works, but it is slow
01:18justin_smithit's slow because you are calling load
01:18rritochI'd like to AOT compile this instead
01:18justin_smithyou don't need to call load
01:18justin_smithjust require the namespace, and call the function
01:18justin_smithwrap the whole "script" in one function you can call
01:18rritochThe dispatcher isn't going to know the names of the functions
01:18rritochThe web designer is going to build index.clj
01:19rritochWith whatever scripts they need to run to produce the web page
01:19justin_smithOK, then pass those function names in as an argument
01:19justin_smiththis is all logic you can do at runtime, without needing to use the compiler to load new code
01:20rritochThe dispatcher won't know what the function names are, at least not on an initial HTTP GET request, I can see function names being passed in POST requests, or part of URL's but not for a home page
01:20rritochBut you did give me an idea
01:21rritochCan the macro define the gensym function with metadata? So at runtime a (run-script) function could extract the list of functions which need to run?
01:22rritochex. (run-script "index.clj")
01:22justin_smithrritoch: in order to know what to run, there needs to be shared information between the one deciding what runs and the one doing the running. In your case it was a file name.
01:22justin_smithrritoch: you can literally take every file name, and make it a function name, that the contents of each file you would load, and put it in a function body.
01:23justin_smiththere is no extra information needed that was not needed in the original unperformant design
01:23justin_smith*that has the contents of each file
01:23justin_smithyou can have a single namespace, with an "index" function, and a "validate" function, etc. etc.
01:23justin_smithno gensyms are needed
01:23justin_smithno runtime compilation is needed
01:24rritochHmm, it's going to take me a few minutes to process that one
01:24justin_smithrritoch: that's understandable
01:24rritochSo your suggesting I wrap the source code in a function that gets called, and compile that instead so I can just call the function?
01:25justin_smithrritoch: clojure is not a scripting language like php or perl, but I promise that the clojure approach is very useful, and helps make good designs that scale well
01:25arrdem(inc justin_smith)
01:25lazybot⇒ 100
01:25justin_smithrritoch: yes, that sounds about right
01:25rritochTechnically I think that is exactly what I want, but I've never considered that possiblity, nor am I sure where to start, but your right, that would be a fast AOT script
01:25justin_smithrritoch: and you don't need to explicitly compile the function, that should happen (as much as is needed) during generation of the uberjar and startup of the app
01:26justin_smithrritoch: you have a marvelous new world of app design ahead of you if you stick with it :)
01:27rritochLol, I have 30 years programming experience, and 10 years web development experience, I'm not new to LISP, but fairly new to clojure (less than a year)
01:27justin_smithOK
01:27rritochI'm almost literally over-the hill
01:27rritochTo the point where I'm just making code to pass on to the next generation
01:28justin_smithsorry, not meaning to be condescending, just saying, based on your level of (un)familiarity of how things are done here, and my own experience with scripting oriented stuff
01:29rritochNo, I understand your perspective. It is the clojure way of doing things, and the solution you came up with is almost exactly what I'm looking for
01:30rritochIn addition to helping developers familiar with scripting languages, this also simplifies the task of translating existing web applications into clojure.
01:30justin_smithI think you'll find it's the way of doing things you'll find in any language that doesn't run a process that is expected to run for under half a second and then exit
01:30justin_smithrritoch: that is a promising thing, yeah
01:31justin_smithrritoch: maybe you could also blog about the adaptation process also - I bet there would be a lot to learn from that
01:33rritochjusting_smith: It has taken me a very long time to reach the proof of concept phase where clojure web apps could be run from tomcat, and standalone, deploying .jsp templates and using .clj scripts for deployment.
01:33rritochSources can either be in the application, maven or OSGI bundles.
01:34justin_smithrritoch: ring makes things a lot easier
01:34rritochI developed a leiningen plugin which copies all dependencies to the WEB-INF/lib folder
01:34justin_smithit connects regular clojure functions to the servlet api
01:34justin_smithring does that part too
01:34rritochjustin_smith: Ring made things worse, I had to remove it
01:34justin_smithrritoch: I suspect you were not using it the way it was meant to be used - I have used it for years
01:34rritochRing doesn't support JSP
01:34justin_smithOK
01:35rritochThere is a conflict because Ring provides it's own javax/servlet/Servlet.class
01:35justin_smithOK
01:35rritochThat of course conflicts with what tomcat provides
01:36justin_smithwere you using ring uberwar?
01:36rritochIt was a nightmare so I disabled ring support until I can find a solution to it
01:36justin_smithI have a few ring apps running in tomcat instances
01:36justin_smiththey work great - but I am not explicitly using jsp, just the ring apis
01:37rritochTo support CGI this framework depends on tomcat
01:37justin_smithlike I said, I have ring apps running via uberwars inside tomcat
01:37rritochSo it can be run from the command line, and still process .jsp files
01:38rritochring uberwars wouldn't be able to support CGI execution of jsp scripts, simply because of the connnflict with the javax/servlet/Servlet.class
01:38justin_smithOK
01:39justin_smithI don't really know the jsp part, so I can't address that
01:39rritochBut I actually still have ring support in the code, I'm just waiting to find a solution to this conflict issue
01:41rritochIn order to load code from OSGi modules I've needed to wrap tomcat's resources (such as ServletRequest, ServletContext, ServletResponse) in wrappers so I could .forward to code which isn't in the classpath but is in OSGi bundles
01:41rritochNeedless to say this development process was a nightmare because around every corner is a new bug or conflict to deal with
01:42rritochNow that it is working I'm trying to undo some of the horrible design choices that were made just to get the thing functional.
01:42justin_smithrritoch: well, I'll just reiterate what I said above - I put functions into namespaces, compiled at uberjar or application startup time, and use function parameters to vary their behavior, and it works very nicely for me
01:42arrdemrritoch: so... what class conflict are you getting with ring? Because Ring doesn't actually package that class as far as I can tell.
01:43rritocharrdem: I was getting a security violation
01:43rritochaardem: If I recall correctly its because the "signers" don't match between what ring utizes and what the tomcat library provides
01:44arrdemrritoch: what version of the servlet package are you using?
01:45arrdemin production that is, ring has another version and I suspect that's where your issue is coming from.
01:45rritocharrdem: but yes, that class is provided by ring, at least it was, I can give you it in a sec, but first I wanted to share the leiningen dep which is [org.apache.tomcat/tomcat-jasper "7.0.52"] and conflicts with ring
01:45rritochThe tomcat dep is the only place of conflict
01:47rritochI don't know if this is new, but as you can see from the sources, ring won't allow tomcat to be used
01:47rritochhttps://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/uberwar.clj#L26-L33
01:48rritochSimply because tomcat contains javax/servlet/Servlet.class
01:48rritochPreviously I was getting a security conflict, but with the latest version it looks like the tomcat dependency wouldn't even be loaded
01:49rritochI wasn't actually running ring from tomcat with uberwar though, I didn't make it that far
01:49rritochIt was crashing while running it from the command line (CGI mode)
01:50rritochThe conflict I was getting comes from this code... https://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/war.clj#L230-L233
01:51rritochSo, until ring is willing to give up control of what servlet it uses, this application framework can't support ring.
01:52rritochWithout tomcat, there is no easy way to execute .jsp templates
01:52rritochMaking your own .jsp compiler is one option, but it would be an insanely huge project
01:53justin_smithrritoch: add a config to make that one step optional, it should be a trivial patch
01:53justin_smithrritoch: that seems so much easier than the alternatives
01:55rritochRing doesn't provide any configuration setting to bypass that step
01:56rritochYeah, I could create my own "version" of ring which doesn't conflict but that basically eliminates any benefits to using ring in the first place, since I'd have to maintain a custom version
01:57justin_smithrritoch: it's open source, clone it, offer a patch
01:58justin_smiththat process is so much easier than any other alternative I have seen so far
01:58rritochjustin_smith: That isn't a bad idea, but it isn't a priority. Optimization is the current priority but before going onto the next phase I really need to revisit the ring issues
01:59rritochLeaving code in the application that never gets used, while it happens more than anyone likes to admit, I'd prefer not doing it.
01:59justin_smithbut this is the easy way to get things optimized. eval is very expeinsive, you want a long running process serving requests without runtime compilation
02:00rritochWell, this script issue isn't the worse problem I face
02:00rritochI believe you helped me the other day with this fallback URL compiler
02:00rritochBut technically the only reason that is required is the classloader isn't looking in the right places to find the pre-compiled classes on the remote server
02:02justin_smithrritoch: do the names of the namespaces reflect the location of the files relative to the effective classpath?
02:02rritochThis fallback compilation hack to compile the remote sources locally is functional, but I don't want to rely on it as the primary means of utilizing remote code bases.
02:02justin_smithcompiling before deploying is not a hack
02:02justin_smithit is the right way to do it
02:02justin_smithcompiling at runtime is the hack
02:03rritochI agree, and that is what I have in place right now, a runtime compiler hack
02:03rritochBut there are actually some benefits to that since it could respond to code changes in real time without a need to restart the server or servlet container.
02:04arrdemClojure will do that out of the box with a simple defn, no "compile hacks" required.
02:04rritochRegardless of the possible benefits, it is currently on my list of optimization issues to deal with
02:04arrdemThe entire def infrastructure is designed to support dynamic code reloading both in development and production without having to defensively eval or load everything all the time.
02:05rritocharrdem: Compile hacks are absolutely required for this case as source code can exist in the local app, in maven loaded jars, in OSGI bundles, or from remote URL's
02:06rritochThis is an issue that was solved yesterday since load-reader doesn't generate __init.class when *compile-files* is enabled.
02:06justin_smithrritoch: and we have a classpath, so that the function (require) can abstract over all of those, as long as you set the classpath properly
02:07rritochSince the compile function only accepts a local source, the only way around it was to generate a reader from the URL and call the Compiler/compile function directly, manufacturing an appropriate script path to ensure that the __init.class is properly generated.
02:07justin_smithrritoch: every method of loading code compiles it
02:07rritochJustin, these are web applications running from tomcat, adjusting the classpath used by tomcat isn't how I plan on spending the next 3 years of my life
02:08justin_smithdo you explicitly need to create the .class file?
02:08rritochTomcat doesn't simply classpath manipulation in any way
02:09rritochRegardless, what I've done so far is really the only solution until I can get the deployment to properly switch classloaders when controller (MVC) functions get called.
02:10rritochjustin_smith: I'm referring to attaining classes (gen-class) from a source file located on a remote server
02:11rritochAs I said, load-reader doesn't generate the __init.class, which is why the hack is required,
02:11rritochload-reader does a lot of compilation, but the generated class files are unusable since it doesn't include the __init.class
02:12justin_smithrritoch: it's late here, and I need to move on to other things. Good luck. I think there are likely much simpler ways to meet your root requirements than the elaborate things you are describing, but I can't go into it right now, sorry.
02:12rritochThis may be a bug or a feature of clojure, I'm not really sure, but the way around it was to call Compiler/compile directly
02:13rritochjustin_smith: That is not a problem, this hack solution works, and I neeed to deal with the class loader issue anyhow.
02:14rritochI also need/want to implement this function/file solution so the scripts run faster by being AOT compiled
02:15arrdemrritoch: ... having spent the past summer working on the Clojure compiler implementation, I assure you that you are bludgeoning the Clojure runtime into supporting a sequentially executed imperative style based on code loading for the language is not designed.
02:15arrdemrritoch: AOT is not your problem. Your problem is that you are misapplying the language as if it were PHP or Perl when it is not designed to be used as such.
02:16rritocharrdem: That id debatable, since it is exactly how most versions of LISP function
02:16rritocherr, is debatable
02:17arrdemrritoch: Clojure is hardly a "typical" lisp in a number of ways especially with regards to the total lack of an interpreter let alone the datastructure and software engineering philosophies involved.
02:18rritocharrdem: You can't have your cake and eat it too, your explicitly contridicting the reasoning behind not allowing cyclical dependencies
02:19rritochEither clojure is meant to support Streaming source code, or it isn't
02:19arrdemrritoch: cyclical dependencies on what... namespaces? vars? classes?
02:20ddellacostaI guess it's not possible to do destructuring w/Schema in schema.core/defn, huh
02:20rritochIt may take me some time to find the article, but as I said, what your stating is directly contridicting the statements from clojure's developers as to why they won't support cyclical dependencies
02:21rritochIt is right here: https://news.ycombinator.com/item?id=2467809
02:22rritochBy Rich Hickey who supposedly has a big role to play with Clojure
02:22arrdemhow does that have anything to do with the conversation at hand
02:22arrdemby the way we do support circular dependencies on symbols via declare
02:22arrdemwith some restrictions
02:23rritochYou stated I was misapplying the language, but I'm actually directly applying the language per the reasoning by Rich as to why cyclical dependencies aren't being allowed
02:24rritochI may not know all of the clojure politics, but I suspect Rich is higher up in the food chain than anyone in this chatroom.
02:24Raynes☜(⌒▽⌒)☞
02:24rritochSo, either Clojure is meant to be scriptable/streamable, or it isn't
02:24arrdemRaynes: lols
02:24rritochI'm working under the assumption that it is
02:26rritochSince load-reader doesn't create the required __init.class files when *compile-files* is enabled the only way to compile a class from a stream is to pass it to Compiler/compile directly, as I have done.
02:27sveriHi, I have a list of keywords and a map. For each keyword I want to update the map with a given function, how would I do that? I know that I can reduce over the list, but I don't know how to keep a copy of the new map the same time.
02:27rritochIf clojure is planning on moving away from streamability, than remove this cyclical dependency issue because it causes more problems than it solves.
02:30amalloysveri: reduce keeps an accumulator; that's the whole point. here, your accumulator is the new map
02:30rritochBetter yet, just repair load-reader (Compiler/load) so that it generates the __init.class files when *compile-files* is enabled.
02:30amalloy(reduce (fn [m k] (change m somehow with k)) original-map list-of-keywords)
02:30dbasch,(reduce (fn [x y] (assoc x y (rand-int 10))) {} [:a :b :c :d])
02:30clojurebot{:d 6, :c 5, :b 7, :a 0}
02:30dbasch^ sveri
02:31sveriamalloy: dbasch thank you, obv. that's the whole point. My head still does not want to think about it that way, but it's clear if someone states the obvious, jeez
02:32justin_smithrritoch: to step back in for a moment: clojure supports runtime update, and aims to minimize the difference between entering code sequentially in a repl vs. loading from a required file. This is on order to streamtime development, but has nothing to do with hotswapping code in production. Also, this does not mean that streaming code and using eval on arbitrary sources at runtime is a) efficient b) simple or c) a sane way to get any r
02:32justin_smithwork done. I'm not suggesting this is wrong because clojure doesn't or isn't meant to support scripting, but saying that the kind of complexity and brittle behavior you are seeing is symptomatic of using clojure in unusual ways.
02:34justin_smithif I dealt with the kind of complexity and frustration in my clojure development that you are describing, I would have ditched it long ago.
02:34rritochjusting_smith: I've walked away from this project a few dozen times for the exact reasons your stating
02:35rritochjusting_smith: But the goal of this is to reduce the complexity, and learning curve, for developers using this web platform
02:35rritochIf I do the hard work, they don't have to
02:35rritochFor that matter, it also means that I don't ever need to deal with these problems again, once they're solved
02:36justin_smithmy fear is that the design is importing external complexities that don't need to exist, and introducing an extra layer of complexity by trying to make clojure something it simply is not
02:38rritochFlexibility is exactly why I'm utilizing clojure instead of Pike, clojure has far fewer limitations
02:38rritochIn this particular case a real clojure developer can define their functions and have a (script) macro which calls their functions, escaping the scripting structure
02:39rritochBut for programmers familiar with scripting languages, this hybrid functionality makes the transition easier on them
02:40arrdemAt the expense of atrocious performance and shielding them from a language designed to support real software architecture rather than load order based imperative programming
02:41rritocharrdem: That is why I'm now dealing with the performance issue, and I believe justins solution of wraping the file as a function will solve that problem
02:42rritocharrdem: I've never tried it before, and I'm not entirely sure if (ns .... (:import) is going to function properly within a function, but these are issues I'll learn when I try
02:44rritochRegardless, this platform has a long way to go, after the optimization step, I need to revisit the ring issue, and after that I need to establish a modern GUI. I'm considering using libGDX instead of JavaFX, but integrating that into a framework which is already complex is probably going to take years.
02:46rritochSo far all I've solved is creating a MVC framwork that is script driven, which can utilize maven resources, OSGi bundles, and remote codebases (Such as how many .js files are delivered client-side).
02:46rritochI'm currently optimizing what I have so far because repairing these things after adding new layers of complexity will be a nightmare
02:47amalloyrritoch: importing inside of a function doesn't do anything. import doesn't load any classes, just gives the current file a shorthand to refer to them
02:48rritochamalloy: :( that is truly sad then, because these scripts need a way of defining Imports to the scripts can be clean
02:49justin_smithrritoch: but that isn't what :import does
02:50rritochjustin_smith: I believe I know what import does, it likely generates bitecode so the class file contains the imports at a binary level, and it also cleans up the code because you don't have to namespace qualify all of your classes
02:50justin_smithrritoch: nope
02:51rritochjustin_smith: Ok?
02:51justin_smithit's a convenience so you don't have to type out the full package name
02:51arrdemrritoch: there is no JVM bytecode "import" operation.
02:52arrdemrritoch: loading a class loads all of its transitive dependencies recursively. As justin_smith says, import just makes class names nicer to type.
02:52rritocharrdem: If I recall correctly, the class file format includes a section for imports, but I could be wrong, it has been over 10 years since I dealt with class files at a binary level
02:52justin_smithrritoch: http://stackoverflow.com/questions/9680295/import-statement-byte-code-significance
02:53rritochWell, I just rechecked the class file structure, and your right, there is no section for imports
02:53rritochhttp://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
02:54rritochIt's been well over 10 years since I dealt with class files at a binary level
02:54arrdemRight. Classes make fully qualified references to their depended classes, and unresolved dependencies forces classloading.
02:54rritocharrdem: Ok, well using load-reader is allowing me to utilize imports
02:55arrdemwhat does "utilize imports" mean. We just went over the fact that (import) is simply syntactic sugar.
02:57rritocharrdem: Are you trying to be helpful or are you just trolling?
02:57dysfun_is there a clojure library for handling renaming files with a known name into the format file.n.ext where n is an increasing number?
02:58rritochdysfun_: http://clojuredocs.org/clojure.core/format ?
02:58dysfun_hrm, i suppose that works
02:59rritochdysfun_: If you want it more automatic you may be able to find a way of wrapping format to make it automatic
02:59dysfun_that's overkill. it just seems like a common piece of code. i wondered if anyone knew a library that included it
03:00dysfun_it's not terribly difficult to write
03:45rolfburh
03:45rolfboh nice, completely botched the window there
03:45rolfbsorry all
04:43tincho1Hi, I'm having an issue with loading the optimus library as it uses core.memoize which relies on core.cache and that has some issue with it in core.cache/through.
04:44tincho1I've found similar issues online but their solutions don't seem to work for me. I've tried tracking through the dependencies and :excluding core.cache when I can. But no luck.
04:45tincho1If anyone has some advice it would be greatly appreciated
04:56rurumateWhy does tools.analyzer depend on datomic-free?
04:57rurumateIt's surprising to find a part of the compiler need some sort of database
04:57rurumatesee https://github.com/clojure/tools.analyzer/blob/master/project.clj
04:58AeroNotixBronsa^?
05:07borkduderurumate https://github.com/clojure/tools.analyzer/search?utf8=✓&q=datomic
05:08borkduderurumate it has scope provided
05:12rurumateborkdude: yes but still lein pulls all the datomic deps when doing a lein install in tools analyzer. Also, there is no mention of datomic on README.md
05:13borkduderurumate that is normal with scope provided. it won't be packaged with your uberjar
05:14rurumateif it's not packaged with the uberjar, apps may break at runtime. The circumstances for that are not mentioned in the README
05:16rurumatemaybe it makes more sense to put the datomic stuff in a separate project that depends on t.a. ?
05:18cflemingrurumate: Bronsa is a bit too clever for that I think. I haven't looked in detail, but I believe the datomic stuff is experimental, and it looks like it's conditionally compiled out if not present: https://github.com/clojure/tools.analyzer/blob/5a58c3ffd87da05e50924d2931b833544717ee55/src/test/clojure/clojure/tools/analyzer/query_test.clj#L11
05:18cflemingrurumate: Is this actually causing you some problem?
05:20rurumatecfleming: yes, it bothers me
05:22cflemingrurumate: That sounds like a fairly mild sort of a problem :-)
05:23rurumatealso it clogs my hard drive
05:28dysfun_gah, i keep getting "Variable binding depth exceeds max-specdl-size just trying to do (ns foo) and evaluating it under cider-ritz (via nrepl). any ideas?
05:29dysfun_or at the very least what that error even means to give me an idea where to look?
05:30dysfun_oh, seems to be on the emacs side
05:30dysfun_is there a channel for clojure-related emacs stuff?
05:34phillordso this error is normally caused by an illfounded recursion
05:34phillordalthough it can happen as a result of just deep recursion
05:34phillordOne solution is to do (setq max-specpdl-size 4000)
05:35phillordwhich will increase the max allowable level, but if it still happens, then there is a bug somewhere. For which you need to turn debugging on, and get a stack trace
05:35dysfunoh, i think it might be something to do with the 5 nrepl connections i just closed
05:35dysfunbut then i was creating them because i was getting that, and sometimes it would just go away after a while
05:37phillordif it occurs randomly and not predicably, then it's quick likely just that you are hitting a deep recursion
05:37phillordso increasing the max size will work
05:37dysfuni've set it to 10 for now, and it's gone away. i suppose i'll have to either find the bug and fix it or just restart emacs periodically
05:37phillordif not, again, you need to get a stack trace
05:38phillordYou have max-specpdl-size at 10?
05:38dysfunyes
05:38phillordwell, the default on my OS is 1300
05:38dysfunthat's bizarre then
05:38dysfuncause it's working fine now
05:38phillordwhat OS?
05:38dysfunosx
05:38dysfunplain gnu emacs
05:39phillordlaunch with "emacs -Q"
05:39phillordand then tell me the value?
05:40dysfunwill do, once I've reproduced it
05:40dysfun(if i reproduce it)
05:40phillordyou don't need to reproduce anything -- just see whether max-specpdl-value is the same with -Q --
05:40dysfunoh right
05:40rurumateIs it possible to require more than one library at once, in the repl? Like the :require clause in the ns macro
05:41dysfun1300
05:41dysfunrurumate: you can use ns if you want
05:41phillordthis variable controls how many times you can recurse -- because it controls how many times a variable binding can be pushed onto the stack
05:41phillordEmacs cannot know whether something is going to terminate, so it just sets this value
05:41rurumateoh sure, why didn't I do that before
05:42dysfun*nod*, most interpreted languages do that
05:42dysfunso why didn't everything break completely when i set it to 10?
05:42phillordif you have rest it to 5 from the default 1300, then are you going to crashes in perfectly normal code
05:42phillordI don't know
05:42dysfunsoftware :)
05:42phillordwhere did it get set to 10?
05:42dysfunm-x set-variable
05:43phillordyou set it to 10?
05:43dysfunyup
05:43phillordwhy?
05:43clojurebotwhy is startup slow is busy compiling the `for` macroexpansion
05:43phillordset it back to 13000
05:43dysfunfirst stackoverflow i answered
05:43phillordsorry 1300
05:43dysfuner saw
05:43dysfunwell i killed it now
05:43dysfunso it's back to 1300
05:44phillordThis value used to be smaller in the past -- it protects emacs from o-o-memory crashes
05:44dysfuni have 8 gigs on this machine. i'm not concerned about that :)
05:44phillordno
05:44phillordthat's why it's got much bigger than it used to be
05:44dysfuni know it was written for a different day...
05:45dysfunthen again, the default configs for postgres and mysql are very conservative
05:45dysfunthe postgres one in particular is for a Sun IV
05:46phillordwell, emacs is like Shakespeare -- not of a time, but for all time
05:47cflemingIt's also like Shakespeare in that no-one really understands it :-)
05:48dysfunheh. i'm kind of hoping DEUCE will get somewhere, but i'm not interested enough to actually develop it
05:59SagiCZ1how does (swap! foo atom) work with the foo function? when i redefine foo while the application is running, the new behavior isnt reflected.
06:02SagiCZ1i mean the live re-compilation is advertised as a feature of clojure but it seems to me that you have to design carefuly so that you can use it and if you do would that produce idiomatic code?
06:12dysfunthe code that uses it also has to be recompiled
06:13dysfunit gets bound to a compiled function
08:02mearnshdysfun: #clojure-emacs exists
08:14dysfunmearnsh: yeah, i discovered :)
08:16mearnshah yes
08:58justin_smithdysfun: you may want to mention on #clojure-emacs that you are using cider-ritz
08:59dysfunthe issue has gone away
09:44SagiCZ1~lazy-logs
09:44clojurebotlazy-logs is http://logs.lazybot.org/
09:45justin_smithSagiCZ1: the syntax is (swap! atom foo)
09:46justin_smithSagiCZ1: if you need t see a new definition of foo, you need to recompile the function that calls (swap! atom foo) OR you need to call (swap! atom #'foo)
09:46justin_smiththat is guaranteed to always look up the definition (can be a bad idea because of the var lookup overhead)
10:02SagiCZ1thank you justin_smith
10:03justin_smithnp
10:03SagiCZ1is that true for other calls as well? (foo (foo2 coll))
10:04justin_smithyes, if you need to see changes without redefining, then you can change it to (#'foo (#'foo2 @#'coll)) ; assuming all 3 were global defs
10:05justin_smithin practice you should only need explicit var lookup like the above in stateful functions that have internal mutation (like a server process, or if they wrap some long running stateful java thing)
10:06justin_smithwith pure functions, just re-evaluate the definition to capture the new definitions for things it uses
10:06SagiCZ1my case is a long running doseq
10:06SagiCZ1which is consuming a lazy-seq stream
10:06SagiCZ1if i want to recompile it, i would have to stop the consuming and start over
10:06justin_smithyeah, if you need to see new defs while it runs, it makes sense to use var lookup explicitly then
10:07mdrogalisThat sounds like some funky code.
10:08SagiCZ1and now that i mention it, i am not sure i should use lazy-seq to act as a stream... i am streaming some data from the internet and it seems to work fine, but i wonder if there is some better clojure way to do streams.. non mutable..
10:08SagiCZ1mdrogalis: it probably is kinda funky, i would like to improve it
10:08justin_smithSagiCZ1: what about using core.async and putting the data elements on a channel?
10:08mdrogalisSagiCZ1: Can you use a real queue and reload your code in a normal way?
10:09justin_smiththen you can redefine the consumer of the channel
10:09justin_smithor yeah, a queue
10:09mdrogalisAye, both are good solutions.
10:09SagiCZ1what is a normal queue?
10:09SagiCZ1*real
10:09rurumatequeue = channel in core.async lingo
10:09justin_smithSagiCZ1: there are a few options in java.util.concurrent
10:09mdrogalisSagiCZ1: Oh, I mean something like HornetQ or ActiveMQ.
10:10justin_smithmdrogalis: oh, an inter-process queue?
10:10mdrogalisThe reason I say that you might want an inter-process queue is that it will buy you the ability to kill off your old jar and reload a new one from scratch. Avoids redefining vars.
10:11SagiCZ1mdrogalis: yeah i would probably end up with that later, because i might need some automatic back up in case of connection drop, but for now i would like to be able to use just clojure stuff.. of course writing abstract enough code to be able to swap in activeMQ alter
10:12mdrogalisMaybe an interface between your code and a channel would be best. Sounds like you get the idea.
10:12SagiCZ1yeah so i will probably use java's blocking queue or something.. or get familiar with clojure.async
10:13mdrogalis:)
10:13SagiCZ1thank you both for ideas
10:14mdrogalisYep
10:18mmeixtrying to solve 4clojure #58, need a hint
10:18mmeixsee: https://www.refheap.com/92101
10:20clgvmmeix: do not construct lists but call functions in the reduce step
10:21mmeixhm, tried that ... but obviously the wrong way
10:21mmeixok ... more thinking - thanks for the hint
10:21mmeix(but it's not way off, right?)
10:23SagiCZ1if i want to apply a function to each element of a coll but i only care about the side effects, is there a better way than (dorun (map foo coll)) ?
10:23puredangermaybe the new run! in 1.7?
10:24puredangerI guess that does reduce-y things so maybe not
10:24puredangerdorun seems fine
10:27SagiCZ1puredanger: alright, just wondering
10:28zerokarmaleftSagiCZ1: I prefer doseq
10:29SagiCZ1but map can do pmap
10:32puredangerif you're heading in that direction it might be more direct to just make your own ExecutorService
10:33jonathanjhow does one do networking in Clojure?
10:33jonathanji'm hoping for something more high-level than java.net.Socket
10:35clgvok, `run!` just uses the benefits of reducible collections if possible
10:35sam_Hi, When I do (class (clojure.instant/validated [ 1 1 1 1 1 1 1 1 1 1 1 ])) , I get clojure.instant$validated$fn__6196. Could someone explain what this means?
10:36ToxicFrogsam_: does clojure.instant/validated return a function?
10:37Jaoodjonathanj: haven't use it but there's aleph
10:37ToxicFrogBecause that's the type of an anonymous function.
10:37stuartsierrapuredanger: What's the first argument to `run!`
10:38puredangerbased on the source, I'd say it's a 1-arg function to be invoked with an item from coll
10:38SagiCZ1(doc run!)
10:38clojurebot"([proc coll]); Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil"
10:38puredanger,(source run!)
10:38clojurebotSource not found\n
10:38jonathanjJaood: thanks, i actually just stumbled on to aleph and it looks fairly useful at first glance
10:39puredanger,(run! println (range 5))
10:39clojurebot0\n1\n2\n3\n4\n
10:41stuartsierraOK, it's just `(reduce #(proc %2) nil coll))`
10:42stuartsierraLike `(dorun (map …))` but without the intermediate seq.
10:42sam_Oh. I was trying to annotate namespaces.
10:42sam_So, under what type would this come?
10:42sam_And the [ 1 1 1 1 1 1 1 1 1 1] is a persistent vector, right?
10:44stuartsierrasam_: Every Clojure function compiles to its own class with a generated name.
10:45stuartsierra`clojure.instant$validated$fn__6196` is probably the class of an anonymous fn created in the body of a function named `validated` in the namespace `clojure.instant`
11:38numbertenis there a function that lazily concats but with a non-deterministic order?
11:41Bronsanumberten: no but it's trivial to make one
11:41Bronsanumberten: (defn shufcat [& args] (apply concat (shuffle args)))
11:47mdrogalisBronsa: shufcat. I love it.
11:48numbertenBronsa: (shuffle args) would realize the lists in args right?
11:49Bronsanumberten: no
11:49Bronsanumberten: it realizes args, which is not lazy anyway. but the elements in args are still not realized
11:49Bronsa,(defn shufcat [& args] (apply concat (shuffle args)))
11:49clojurebot#'sandbox/shufcat
11:50Bronsa,(first (shufcat (map #(do (println %) %) (range 10)) (range 10 20) (range 20 30)))
11:50clojurebot20
11:51numbertenvery cool
11:52numberteni guess I thought the inner most arguments were evaluated first, so any strict list processing call would realize everything
12:01sveri,(midje)
12:01clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: midje in this context, compiling:(NO_SOURCE_PATH:0:0)>
12:01sveri(midje)
12:01nullptr~midje
12:01clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: :>
12:04EvanRso is there a way to use reflection intentionally without a reflection warning
12:04EvanRwithout disabling the warn option for the whole file
12:04BronsaEvanR: probably only by using clojure.lang.Reflect directly
12:05EvanRthats what im doing, clojure.lang.Reflector/invokeInstanceMember
12:05EvanRand i get reflection warning, clojure.lang.Reflector/invokeInstanceMember cant be resolved
12:06BronsaEvanR: you have a reflection warning on your usage of c.l.R/invokeInstanceMember then, not on the method you're trying to invoke
12:06EvanRconfused
12:06BronsaEvanR: I see the 3-arity takes either an array or an Object
12:06EvanRi have an object
12:08EvanRputting ^Object does not help
12:09sam_Hi!
12:09BronsaEvanR: hint the first arg as ^String
12:09EvanRoh
12:09sam_Are functions/namespaces to work with data structures?
12:10EvanRthe second arg to invokeInstanceMember? it didnt work
12:10BronsaEvanR: I really can't figure out why the compiler thinks there's an ambiguity there, might be a reflector bug
12:10BronsaEvanR: http://sprunge.us/XeeE
12:11EvanRthe first arg
12:11EvanRwhy string?
12:12Bronsabecause that's its signature, the defined arities are (Object,String), (String, Object, Object[]) and (String, Object, Object)
12:12EvanRhttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java (String, Object, Object[]) ?
12:13EvanRoh wrong method
12:13dbaschit could match this method too perhaps: public static Object invokeInstanceMember(String name, Object target, Object... args)
12:14EvanRi had the arguments reversed
12:14Bronsadbasch: no, in my repl (clojure.lang.Reflector/invokeInstanceMember ^String a b c) doesn't cause a reflection warning while (clojure.lang.Reflector/invokeInstanceMember a b c) does
12:14dbaschthat’s not object[], it’s variadic
12:15Bronsadbasch: what? Object.. x compiles to Object[]
12:16EvanRcurrently i have this
12:16EvanR(clojure.lang.Reflector/invokeInstanceMember (str "get" (name k)) t (int i))
12:16dbaschBronsa: what I mean is that when calling the method you don’t call it with an array
12:17EvanR(int i) doesnt look right
12:17Bronsadbasch: from clojure you do
12:19dbaschBronsa: but how would the compiler know whether c is Object or Object[] ?
12:19noncomcan anyone explain, why is it a "while" cycle here instead of a simple "if" that would suffice in my opinion? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Namespace.java#L58
12:20EvanR(clojure.lang.Reflector/invokeInstanceMember ^String (str "get" (name k)) t (int i)) is still giving me a warning
12:21EvanRbut
12:21BronsaEvanR: it's the int the issue there, you need to remove it
12:21EvanR(clojure.lang.Reflector/invokeInstanceMember ^String (str "get" (name k)) ^Object t ^Object (int i)) worked
12:21EvanRremove it?
12:21Bronsadbasch: the java or clojure compiler?
12:21dbaschBronsa: clojure
12:21BronsaEvanR: either remove the (int ) call or box it
12:22EvanRbox it?
12:22Bronsadbasch: it might just default to Object
12:22BronsaEvanR: why do you need that (int) call?
12:22dbaschBronsa: but I can see how both methods could be considered
12:23Bronsadbasch: there are some cases where the compiler just picks one of possible methods, I think this is one of those
12:23EvanRBronsa: it appears to be used as the argument to the dynamically named method?
12:23Bronsadbasch: it probably picks the Object[] arity only if you tag the arg as ^objects
12:23myguidingstarhi all, is it possible to run a lein task from existing nrepl?
12:25joegalloit's all just clojure code, so it is *possible*
12:25technomancymyguidingstar: if you set :eval-in :nrepl, Leiningen will try to connect to an existing nrepl server instead of starting a new jvm
12:25technomancy(it will fall back to starting a new JVM if it can't though)
12:26BronsaEvanR: look, (int x) in that case returns a primimtive int. the invokeInstanceMember method takes an Object. if you pass a primitive to it the compiler will not know how to invoke it, just remove the (int) call
12:26technomancyand you can't initiate it from within the repl (unless you bring in leiningen as a dep)
12:28myguidingstar(inc technomancy)
12:28lazybot⇒ 150
12:29Bronsanoncom: the compareAndSet might fail
12:32noncomBronsa: ah, i see.. :)
12:39numberteni'm looking at the implemention of interleave and it appears to make recursive calls without the use of recur
12:39numbertendoes that mean it uses O(n) stack space?
12:40numbertenit's lazy so I assume it would still be O(1) as long as you don't hold the head?
12:40sam_Are there functions/namespaces to work with data structures?
12:50clgvnumberten: it uses the macro 'lazy-seq` so it does not use any recursiv calls
12:50Bronsasam_: what do you mean?
12:51sam_I mean are there any functions to implement various data structures?
12:51sam_Like tree, heap etc
12:52Bronsasam_: that's such a vague question, it depends on how you want to implement them
12:52sam_Actually.
12:53sam_Tree etc can be a namespace and there can be various functions
12:53sam_For inserting, deleting etc
12:54clgvsam_: there is no clojure.tree namespacen in the clojure jar - if that answers your question ;)
12:55sam_It does answer the question, thank you!
12:55sam_clgv:
12:56sam_Wouldn't it be a good idea to add those?
12:57Bronsasam_: clojure already ships with a number of persistent data structures that are used extensively, and a big amount of functions to manipulate them
12:59hiredmana reasonable argument could be made that clojure is entirely a dsl for manupilating those data structures
13:00clgvsam_: I guess you'll only get such namespaces included if they add important missing features. so what exactly is missing for you?
13:01sam_That's true , but I feel having these basic data structures would be helpful, Bronsa.
13:02benmossdoes anyone know in vim-fireplace if there’s a way to reset the REPL once you’ve accidentally caused an infinite loop?
13:02noonianits pretty easy to construct trees out of clojure's core datastructures if that is how you need to model your data
13:02clgvsam_: you build trees with vectors and maps in various ways
13:03benmossi can <ctrl>-c the command, but subsequent commands never return either after that happens
13:03clgv+can
13:03jro_sam_: https://clojure.github.io/clojure/clojure.walk-api.html operates on tree-like clojure forms
13:04sam_To be completely honest, I dont really find anything missing, clgv. But as I have used C, C++ extensively. I feel implementing these would make it closer to other programming languages. I'm sorry if what I say seem like non-sense to you. I'm a newbie here.
13:04EvanRbenmoss: im using fireplace, im interested in how you caused an infinite loop
13:04mgaaresam_: can you give an example or two of what kind of tree manipulation functions you would think to add?
13:04clgvsam_: oh when you are learning Clojure, you should avoid to make it closer to C/C++ ... just try to learn something entirely new
13:05benmossEvanR: as in evaling `(range)`
13:05EvanR:S
13:05technomancyseems to me that trees aren't as much a data structure as a way of using data structures, just like stacks are just a way of using lists
13:06benmossnot actually doing something *quite* as dumb as that, but a function that recurs infinitely
13:06EvanRah
13:06clgvtechnomancy: yeah, our third semester students usually struggle with trees represented in arrays ;)
13:06sam_I meant the basic functions like insertion, deletion and the BST stuff.
13:06sam_That's it.
13:06benmossvim hangs waiting for a response which will never come, I <ctrl>-c it, but i get the sense I need to reconnect to nrepl or something
13:07technomancysam_: have you used update-in?
13:07EvanRbenmoss: when you close and reopen vim does it work
13:07technomancydeletion is just update-in + dissoc
13:07benmossEvanR: yeah, my two options are restart vim or restart the repl
13:07EvanRbenmoss: does :Connect work
13:07mearnshsam_: see joy of clojure section 6.2
13:07EvanRah no, you said it hangs
13:08benmossEvanR: oh yeah i forgot that is a third option, but it prompts me to enter a host and port and everything, its kinda annoying
13:08EvanReven if you have .nrepl-port ?
13:08benmossEvanR: yeah
13:09EvanRanother good reason to show that your code will not infinite loop before running it
13:09jonasenbbloom: Interesting post on Om! Thanks
13:09benmossEvanR: so just solve the halting problem first?
13:10EvanRof course its a case by case argument ;)
13:10bbloomjonasen: glad you enjoyed it!
13:10benmoss:)
13:10sam_I personally feel having a separate namespace along with the functions would make it simpler and hence user friendly.
13:10sam_Just expressing *MY* opinion!
13:10EvanRbenmoss: its times like these it would be nice to turn off TCO so that you get an error instead of hanging
13:10sam_technomancy, No. I haven't. What does it do?
13:10jonasenbbloom: one question: are cursors important in that context, or is all you need the :descriptor support?
13:11clgvsam_: how far did you get reading the introducotry clojure material of your choice so far?
13:11bbloomjonasen: the technique described in the post is 100% orthogonal to the representation of your app state or references in to that representation
13:11jonasengreat! that's good to hear
13:11clgvsam_: your opinion might change drastically in the learning process...
13:12jonasenbbloom: I tend to use om/value a lot and use more of an FLUX architecture instead of cursors/transact!
13:12bbloomjonasen: see https://news.ycombinator.com/item?id=8487855
13:13sam_I just have a basic idea!
13:13sam_I was planning to implement these data structures to get a better idea and hence the question came up, clgv.
13:14EvanRsam_: have you tried implementing linked lists first
13:14sam_No. I haven't.
13:14EvanRbaby steps
13:15clgvsam_: oh, better start trying to implement small tasks for learning. 4clojure.com offers a lot of those
13:15sam_Ok.
13:15sam_:)
13:15sam_So, you guys are saying that is not neccessary huh?
13:15sam_There must be some reason!
13:15jonasenbbloom: thanks! I'll definitely play with this
13:16technomancysam_: http://clojuredocs.org/clojure.core/update-in
13:17technomancydo we have any bot commands to give clojuredocs links?
13:17clgv$docs update-in
13:18clgv:(
13:18clgv$clojuredocs update-in
13:18lazybotclojure.core/update-in: http://clojuredocs.org/v/5823 clojure.core/update-in: http://clojuredocs.org/v/1692
13:18mdrogalis*Claps* :D
13:18technomancyhuzzah
13:18clgvawesome :)
13:18technomancythough... why two links?
13:18mdrogalisFor *twice* the learning
13:18clgvlazybot: botsnack
13:18lazybotclgv: Thanks! Om nom nom!!
13:21EvanRi seem to be able to redirect pprint to a file using *out*
13:21EvanRso i guess (def *out* to something else), but how to do i undo it
13:21clgvEvanR: use (binding [*out* ...] (pprint ...))
13:22EvanRalternatively i just noticed it takes a writer as a second arg
13:22clgv$(source with-out-str)
13:22clgv$source with-out-str
13:22lazybotwith-out-str is http://is.gd/tw8lMA
13:23clgvEvanR: for an example have a look overthere ^^
13:23clgv,(with-out-str (println (vec (range 3))))
13:23clojurebot"[0 1 2]\n"
13:24EvanRnice...
13:25EvanRdoes clojure have a macro to put my - key back in place?
13:25EvanRits popping off the keyboard
13:26nooniani think theres an emacs command for that: M-x pop-keycap-into-place
13:28sam_Sorry. Did you guys say something? WiFi has issues here.
13:29technomancysam_: http://clojuredocs.org/clojure.core/update-in
13:29travisrodmannoonian: lol
13:29sam_I saw that technomancy :)
13:30sam_For insertion
13:30oskarkvHm, the clojuredocs quickref doesn't have all the functions in it, and it's usually where I go to see if what I need already exists
13:30oskarkvDon't you guys think that it should have every function in there?
13:31technomancysam_: for deletion, use update-in with dissoc
13:32sam_Yes.
13:32technomancyoskarkv: is that the thing designed for being printed out?
13:32technomancykind of defeats the purpose if it doesn't fit on the page
13:32oskarkvtechnomancy no, this http://clojuredocs.org/quickref
13:32oskarkvIs that for printing out? I dunno
13:33sam_I guess the usage of BST in cpp created all the problem. The complexity of the problem is reduced to large extent using it in cpp.
13:33technomancyoh, I'm thinking of the cheat sheet
13:33technomancythat is pretty extensive
13:33sam_I'm sorry if this seems nagging, but could you explain why you feel it is unneccassary?
13:34oskarkvThe quickref is great when looking for something because the functions are grouped
13:34technomancysam_: what is BST?
13:34sam_Binary Search Tree. :)
13:35technomancysam_: and that ... does something that regular clojure maps don't?
13:35mikerodIs there not a named var that can be used to find the current line number value from the compiler?
13:35mikerodI see this in the Compiler: `static final public Var LINE = Var.create(0).setDynamic();`
13:35mikerodSo there is an unnamed var
13:35mikerodthat is public here
13:35mikerodI'd have expected a named var like the *file* var
13:37llasrammikerod: what's the context where you're trying to discover this information?
13:38mikerodllasram: macroexpansion would be fine
13:38technomancysam_: probably the reason no one has advice for you is that you aren't framing your questions in terms of specific functionality
13:38mikerodor a function called by a macro while expanding
13:38llasrammikerod: Within a macro, you should be able to check the `:line` metadata of argument forms
13:38mikerodif I wanted to ask, "what is the line number that is currently being compiled"
13:38mikerod&form?
13:38lazybotjava.lang.RuntimeException: Unable to resolve symbol: form? in this context
13:39mikerodwell, not lazybot, I just meant the special &form binding
13:39Bronsasam_: don't take this the wrong way but from what you've beein saying it looks like you haven't even read about the availbale clojure data structures, it's probably best if you read some introductory material before trying to implement your own data structures
13:40llasrammikerod: That'll work, although I believe :line metadata is applied to any list
13:40sam_I guess that's the reason Bronsa. Thanks technomancy.
13:41Bronsamikerod: yeah (:line (meta &form)) should work
13:43Bronsasam_: I've heard http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome is good, you might want to check that out and ask here if you have any doubts
13:51muraikisam_: I also recommend http://www.braveclojure.com/ as it has a good explanation as to how the built in structures work and why you're able to use the same functions across them all (section: Core Functions in Depth)
13:52SagiCZ1sam_: And I would recommend Programming Clojure if you don't care for lame jokes in brave clojure, also Joy of Clojure which gets recommended very often is too advanced for a beginner.
13:59mikerodllasram: Bronsa hmm thanks that probably works then
13:59mikerodI still wish there was just a dynamic var like *file* for *line*
13:59mikerod:D
14:10muraikisagicz1: yeah, sometimes brave clojure gets a bit too wacky. which is a shame because I think it really has excellent pacing and clear descriptions otherwise.
14:11andyfoskarkv: The Clojure cheatsheet is also grouped by functionality and may include things the quickref page does not have. See clojure.org/cheatsheet or click the "Download other versions with tool tips" link near top of that page
14:18roelofHello, whar is wrong here : (defn divides? [divisor n] (if (=(mod n divisor)0)))
14:19swedishfishroelof: you aren't supplying "if" the right number of args
14:20swedishfishroelof: you are only passing in a predicate
14:20andyfroelof: If is unnecessary there if you want to return Boolean val
14:20amalloyroelof: you just want to remove the if entirely
14:21roelofthanks, that did the trick
14:23roelofanother guestion : Can I say to midje that I only wants to test one function instead of the whole namespace ?
14:30mr-Hey, what's wrong with (filter #( (= 1 (mod % 2)) ) [1 2 3]) ? It says it can't cast Boolean to IFn.
14:31amalloytoo many parens
14:31amalloy#((...)) should just be #(...)
14:32mr-Oh. Those keep tripping me up :-(
14:32mr-Thanks
14:33amalloymr-: remember that () is for calling functions, not for grouping
14:34mr-amalloy: Yeah, I thought the #( ) was special
14:34mr-and if they are special, I thought I had to call =
14:35amalloy#(x y) is short for (fn [] (x y)). the idea is that you can take an expression that does something (such as (= 1 (mod % 2))), and just putting a # in front of it changes that into a function that, when called, does that thing
14:36dbaschone of the first things in any Clojure tutorial for Java/C people should be a section called “parentheses are not curly braces”
14:36roelofanother guestion : Can I say to midje that I only wants to test one function instead of the whole namespace ?
14:37mr-Is the #( ) special syntax the interpreter implements, or is it implemented in clojure?
14:38amalloymr-: there's no such thing as the interpreter. clojure is clojure; it's compiled
14:38mr-amalloy: Sorry, I have only been using the repl so far.
14:40justin_smithmr-: everything you do in the repl is compiled
14:40mr-amalloy: But, for example in Agda, if then else is implemented in Agda's standard library. You could define your own, if you liked.
14:40justin_smithmr-: what distinction are you trying to make?
14:40amalloyi think he's getting at special forms
14:41amalloymr-: you could not implement #() yourself: it is a reader macro
14:41mr-justin_smith: I am wondering if I could implement my own #( ) in clojure
14:42amalloyyou could do something very much like it, but you couldn't use quite the same syntax. it'd have to be like (my-lambda (+ 5 %)) instead of #(+ 5 %). it would have to have a name, and look like any other clojure function call
14:45mr-Great, thanks
14:46EvanRparentheses are not curly braces in C or java either ;)
14:49dbaschEvanR: no, but some people who arrive from those languages think { translates to (
14:49mdrogalispuredanger: What's the Sonatype repository to grab Clojure 1.7.0-master? Can't seem to find it.
14:49EvanRthat seems like an odd conclusion
14:50dbaschEvanR: it’s pretty common, in particular people who are used to throwing extra curly braces around because why not
14:50justin_smithEvanR: dbasch: but you see it all the time, it's not odd at all
14:51mr-I don't know why you'd have to jump to curly braces. In most languages even the normal braces are just grouping devices..
14:51justin_smithprobably the most commonly asked question on clojure SO: clojure said Long cannot be cast to IFn here is my code: (5) what's wrong with it
14:51EvanRwhen would you put {5} ?
14:52justin_smithEvanR: I am simplifying slightly
14:52justin_smithpeople do it all the time
14:52dbaschEvanR: you’d have something that evaluates to 5
14:52EvanR{2 + 3} ?
14:52mdrogalisNevermind puredanger, found it :)
14:52justin_smith{return 2+3;}
14:52mr-return (2+3); is much more common :-P
14:52EvanRo_O
14:52dbaschor (nil) when you just wanted to print something out, for example
14:57justin_smithEvanR: mr-: a more specific example (if (foo) (5) (6)) where foo is a value not a function
14:57noonian,([1 2 3])
14:57clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector>
14:57noonian,(map #([%]) [1 2 3])
14:57clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector>
14:58justin_smithnoonian: yes, slightly more subtle examples
14:59jro_,(map #(-> [%]) [1 2 3])
14:59clojurebot([1] [2] [3])
14:59amalloyEvanR: or (defn foo [x] (\n (+ x 1)))
14:59justin_smith,(map #(do [%]) [1 2 3])
14:59clojurebot([1] [2] [3])
14:59noonian,(map #(do [%]) [1 2 3])
14:59clojurebot([1] [2] [3])
14:59nooniandoh, you beat me to it
15:00amalloywhere they put the first open paren on its own line to be a comfortable grouping mechanism, then another one to call +
15:00dysfuncan clojure be written in funky character sets?
15:00justin_smith,(map #(max [%]) [1 2 3]) ; so many ways to do it
15:00amalloydysfun: any character set can be funky if you have enough confidence in your jive
15:00dysfuni don't want to, i'm just wondering if assuming utf-8 would be bad
15:00clojurebot([1] [2] [3])
15:00noonianjustin_smith is good at that iirc
15:01dysfunparty at justin_smith's!
15:01amalloynoonian: is justin_smith the one who pastes 💩 PILE OF POO whenever someone mentions silly characters?
15:01dbaschhere’s some code by a guy who was having an interesting conversation with arrdem and justin_smith last night https://github.com/rritoch/clj-physics/blob/master/src/Physics/core.clj
15:02pmonksdysfun: seems to work ok: (defn 💩 [] (println "💩") )
15:02noonianamalloy: yes i think so, and he had one super long crazy character symbol a while back
15:02justin_smithamalloy: I have occasionally pasted it, but my goto is ☃
15:02dysfunpmonks: and that's invalid utf-8?
15:02pmonksNo - it’s valid UTF8.
15:02dysfunright. my question is whether i can assume clojure is utf-8
15:02justin_smithdbasch: omfg
15:02amalloydysfun: i think the clojure reader reads utf-8
15:03dysfungood enough for me
15:03pmonksClojure-on-JVM is UTF-16 internally (since that’s what Java is).
15:03justin_smithdbasch: I was really trying to help this guy
15:04amalloypmonks: well, but the files it reads are utf-8
15:04justin_smithdbasch: it appears he really is just trying to do php or perl in clj
15:04pmonksamalloy JVM can read a bunch of encodings, and it’ll convert internally to UTF16
15:04pmonksUTF16 is the canonical JVM representation (for historical reasons).
15:04amalloyi know that. it's not relevant to what dysfun is asking
15:05amalloyeg, clojure.lang.Compiler/loadFile reads files as UTF-8
15:05justin_smithpmonks: sure, but it reads utf8
15:05dbaschperljure
15:05dbaschperljury
15:05arohnerdbasch: are you familiar with swearjure?
15:05EvanRhysterical raisins
15:05dbascharohner: yes :)
15:06pmonksamalloy I’d say it’s relevant - doesn’t hurt to know that the JVM itself can read just about anything. The fact the the clojure reader happens to hardcode UTF8 for source is also relevant.
15:06pmonksBut whatever...
15:06pmonksWe’re splitting hairs. ;-)
15:06amalloypmonks: he's trying to write an alternative clojure reader
15:06pmonksRight, so if he’s doing that on the JVM, he could pick any of the supported encodings the JVM supports, is my point.
15:07amalloyman. i keep trying to get out of the habit of using gendered pronouns on irc, and it's really hard. even with tab-completion for dysfun's actual name, "he" just comes so easily
15:07pmonksThought UTF8 is probably the “best” choice...
15:07EvanRplease dont encode your files in utf16
15:07dysfunwell, 'he' would be the least inappropirate pronoun tbh
15:08TEttingeramalloy: "it"
15:08dysfunactually this isn't for the reader anyway, this is because i'm slurping .clj files out of jars to do stuff
15:08amalloydysfun: of course it's accurate most of the time, and technically is the correct pronoun to use in english if you're not sure of gender, but in practice i'd like to avoid being unwelcoming to any women who do arrive here
15:08dysfuni get a byte buffer and i have to decode it to a string
15:08bridgethillyeramalloy: ^
15:08justin_smithuse EBDIC
15:09justin_smith*EBCDIC sorry
15:09dysfunamalloy: *nod* i get it. but in this case, no foul :)
15:09pmonksThat would be EPcdIC!
15:09TEttingerjustin_smith: that's a painful acronym
15:09justin_smithindeed
15:09dysfunjustin_smith: you know, in perl, the internal encoding on mainframes is UTF-EBCDIC ?
15:09pmonksHaving done EBCDIC both pre and post JVM, I can say that the JVM’s encoding support is pretty fantastic. ;)
15:09justin_smithoooh! use Baudot code, it's 5 bit!
15:09pmonksThough EBCDIC isn’t built in.
15:09EvanRuse KOI-8
15:10justin_smithdysfun: woah
15:10justin_smithI bet you could do UTF5 via BGaudot
15:10justin_smith*Baudot
15:10dysfunand the 'utf8' module magically applies to UTF-EBCDIC on those platforms
15:10pmonksI like WTF-8 meself.
15:11EvanRlibiconv exists
15:11Bronsaamalloy: this is something I've always felt uneasy about when speaking in english. In Italian I can just omit the pronoun and it all works just as fine
15:11arohnerok, another fun transducers question. I'm trying to write partition-all, which means that at the end, in, the ([result]) step, I need to flush state, and call (f1 result x) one more time. Is f1 assumed to be side-effecting or pure?
15:11arohneri.e. can I (f1 result x) (f1 result)?
15:12amalloyBronsa: what about words like "him"? in spanish there's "lo" and "la" which i don't think you can usually omit without changing the meaning of the sentence
15:14aztakgood evening!
15:15noonianaztak: good afternoon!
15:15aztakno no, that's not right. I'm pretty certain it's dark outside!
15:16aztak:)
15:16technomancy~ugt
15:16clojurebotugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html
15:17arohnertechnomancy: thank you for being the voice of sanity
15:18pmonksKind of sad that we’ve figured out a non-timezone-specific greeting but not a non-gender-specific one… #justsayin
15:18noonianin that case, good morning!
15:18technomancypmonks: dunno what thon is talking about
15:18aztakpmonks: +1
15:19amalloy(inc technomancy)
15:19lazybot⇒ 151
15:19EvanRjust use "she" everywhere
15:19nooniannice use of thon
15:19aztakGood morning everyone! :)
15:19technomancy"hello, cats and kittens"
15:19EvanR(dec lazybot)
15:19lazybot⇒ 30
15:22Bronsaamalloy: yeah there are cases where you can't avoid it, but anyway "gli" in Italian has a much shallower gender implication than "him" in english
15:27TEttingergli's right
15:28TEttingerpretty sure "dawg" is gender-neutral
15:28mgaareI can just use "y'all" and people will think I'm charming and southern
15:28EvanRi just banged on this code for several minutes wondering where this bug was coming from that i thought i fixed, only to realize i didnt do "reload"
15:29justin_smiththis is a clojure channel, *1 is the only pronoun we need
15:29TEttingerheh
15:29EvanR*2 is right
15:29justin_smithwell maybe you'll need *2, *3 etc. sometimes
15:29TEttinger*1 is right
15:29TEttingerthis gets confusing
15:29justin_smithbut you'll never need *4
15:29EvanR*23
15:29Bronsa(inc justin_smith)
15:29lazybot⇒ 101
15:30dsrxEvanR: sometimes after writing too much cljs code with my editor connected to the browser through a repl I go back to writing JS on a work project and forget I have to reload :)
15:30dsrxEvanR: (or save the file even!)
15:31EvanRi closed and reopen the file to make sure i saved
15:31EvanRnot the same as reloading
15:31dbaschI use cider-restart more than I should
15:33mr-How would you make something like that readable? :-) (defn fib [n] (if (= n 1) [1] (if (= n 2) [1 1] (conj (fib (- n 1))(+ (nth (fib (- n 1)) (- n 2)) (nth (fib (- n 1)) (- n 3)))))))
15:34dbaschmr-: for one, paste it on refheap with proper formatting :)
15:34amalloymr-: i mean, the simplest change is to not repeat (fib (- n 1)) three different times
15:36dbaschnested ifs also don’t help readability
15:37mr-Would that count as properly formatted? https://www.refheap.com/92111
15:38schmirmr-: no, put closing braces on the same line
15:38justin_smithmr-: you should use let
15:38justin_smith,(doc let)
15:38clojurebot"([bindings & body]); binding => binding-form init-expr Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein."
15:39justin_smith,(let [a 1 b (inc a)] (+ a a b b b))
15:39clojurebot8
15:39mr-justin_smith: cool, thanks.
15:39mr-schmir: will do
15:39schmirmr-: use cond instead of nesting ifs
15:39technomancy*5 is right out
15:39justin_smith(inc technomancy)
15:39lazybot⇒ 152
15:41aztakif I use :keys in a map binding like: (defn xxx [{:keys [foo bar]} :body}] (...)) -- is there a way to rename the binding to something else for 'foo' and 'bar' in the map?
15:42justin_smithaztak: just use normal map destructuring
15:42justin_smith,((fn [{the-a :a the-b :b}] (+ a b)) {:a 1 :b 2})
15:42clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:42justin_smitherr
15:42aztakok - so :keys can only be used to bind to the "real" names?
15:42justin_smith,((fn [{the-a :a the-b :b}] (+ the-a the-b)) {:a 1 :b 2})
15:42clojurebot3
15:43justin_smithright, keys is just a sugar for when you want the same name as in the map
15:43aztakaight - thanks :)
15:44dbaschmr-: this is more readable to me https://www.refheap.com/92112
15:48mr-Any more suggestions to https://www.refheap.com/92114 ?
15:48mr-it's got let and cond now
15:48mr-dbasch: ah, having all the braces close like that is Ok?
15:49justin_smithmr-: it's the only right way™
15:49mr-I see
15:50EvanRi tried to write a trace function. (defn trace [msg x] (println msg) (pprint x) x) and it seems to work except that its not printing anything out
15:50justin_smithmr-: you may find it useful to look at some of the code you use (though clojure.core itself can often be funky), there is clojure.repl/source which will show you the source for most functions
15:51SagiCZ1mr-: put the cond on a new line and all ending braces together after (- n 3) )))))
15:51TEttinger,(defn trace [msg x] (println msg) (pprint x) x)
15:51clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: pprint in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:51TEttinger,(defn trace [msg x] (println msg) (clojure.pprint/pprint x) x)
15:51clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.pprint, compiling:(NO_SOURCE_PATH:0:0)>
15:51mr-SagiCZ1: Ok
15:51justin_smithEvanR: two likely causes: it's happening in a thread where *out* is bound differently, or you are calling it inside a lazy squence construction and the seq is not realized
15:51mr-justin_smith: great, that's exactly what I was looking for :-)
15:52justin_smithalso there is bbatsov's clojure style guide - not 100% uncontroversial, but it's pretty good
15:52EvanRjustin_smith: its happening inside of with-out-str
15:53justin_smithEvanR: so the code that runs it is fully realized, and its output is not in the string?
15:53EvanRits not in the string
15:53EvanRchecking again again
15:54justin_smithEvanR: is it being called inside for, map, filter...
15:55EvanRtheres a map there
15:55justin_smithEvanR: do you consume the contents of map before leaving the with-out-str scope?
15:56justin_smith,(do (map #(println "hello" %) (range 10000)) nil)
15:56clojurebotnil
15:57EvanRwell, the final results are printed out before leaving with-out-str
15:57EvanRthat is still working
15:57EvanRgoing to try to print anything out at all on the inside
15:57justin_smithEvanR: the contents of the mapping?
15:57EvanRuhm the value of the result of mapping
15:57EvanRim not clear on what contents of the mapping means
15:58justin_smithEvanR: can you make a paste of it on maybe refheap.com?
16:00EvanRdoes println and print obey *out* too
16:00justin_smithyes
16:00EvanRjustin_smith: unfortunately for this current code blob its all mixed up with proprietary bullshit
16:00justin_smithOK
16:01technomancydoes cider have a command to remove-ns before reloading?
16:01technomancyI can't find it in the readme; seems like a strange omission
16:02EvanRjustin_smith: i think the code im trying to trace is just never called, no laziness involved
16:02justin_smithoh, that would do it too :)
16:02EvanRhaving a hard time travesing this giant map of maps of maps
16:02justin_smithlaziness is an often source of that
16:03justin_smithEvanR: if you are nesting calls to map inside other calls to map, you should use for
16:03EvanRthis is map nested inside update-ins
16:03EvanRnested inside update-ins
16:03justin_smithsounds like a design problem
16:04EvanRi too new to clojure to know the difference ;)
16:04jakebasileHi all. Has anyone ever run into a situation where `lein ring uberwar` just sits there? I had this working earlier today, but I can't figure out what happened to cause this, or how to debug this.
16:04EvanRdesign problem or design pattern, eye of the beholder
16:05mbriggshey guys, i have an agent question. Is there any guarentee to the ordering that the "send" functions are applied to the value? So if i send 3 times, will those three functions execute in chronological order?
16:06EvanRwe have trace \o/
16:07justin_smithjakebasile: jstack can tell you what a jvm is currently doing
16:08justin_smithjakebasile: the output may or may not help
16:08justin_smith(it comes with every jdk)
16:08jakebasilethanks, i'll look at that. I've even tried reverting my changes from today - no dice. It just hangs
16:10mbriggsnever mind, figured it out in the repl, the answer is yes, they execute in order
16:11justin_smithmbriggs: I don't think there is any guarantee (the sends can come from different threads, weirdness can happen), but that is the likely result, sure
16:11mbriggsgood point, in my test all 3 sends came from the same thread
16:11jro_are there attempts going on to speed up clojure initial loading time?
16:12EvanRto write a constant function, what is it, #(4) ?
16:12EvanR,(#(4) 5)
16:12clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval25/fn--26>
16:13BronsaEvanR: (constantly 1)
16:13justin_smith'#(4) ; EvanR
16:13justin_smith,'#(4) ; EvanR
16:13clojurebot(fn* [] (4))
16:13EvanR,((constantly 3) 5)
16:13clojurebot3
16:13EvanR,('#(4) 5)
16:13clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn>
16:13justin_smithEvanR: see the expansion from my code above
16:13justin_smiththat's why that happens
16:14EvanR,('#(4))
16:14clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn>
16:14EvanRfn star
16:14EvanRok i have no idea
16:14justin_smith(fn* [] (4)) - what do you think that would do?
16:14jro_,(source constantly)
16:14clojurebotSource not found\n
16:15justin_smith$source constantly
16:15lazybotconstantly is http://is.gd/5gCQ2V
16:15BronsaEvanR: fn* is just a lower-level fn, you can ignore the difference for now
16:15justin_smithEvanR: fn* is just fn without some cool features like destructuring
16:15EvanRoh # is for partial
16:15justin_smithEvanR: no
16:15justin_smith# is for reader macros, the #() reader macro is for making anonymous functions
16:16EvanRyurg
16:16justin_smith#(x) expands to an anonymous function that takes 0 arguments and calls x
16:16jro_# does not support making vararg funs=
16:16justin_smith,'#(x)
16:16clojurebot(fn* [] (x))
16:16llasramjro_: That is not true
16:16justin_smith,(#(do %& 5) 1 2 3) ; jro_ nope
16:16clojurebot5
16:16jro_I triet to type question mark after funs?
16:17EvanRim looking for constantly
16:17justin_smithjro_: sorry, I can't parse that
16:17llasramjro_: Ok. You are forgiven. *This* time
16:17llasram;-)
16:17jro_:-)
16:17justin_smithahh, now I get it
16:17justin_smithyeah %& is for varargs inside #()
16:18justin_smith#(do %& 5) is shorter than (constantly 5), but not preferable to it
16:18jro_I tend to write explicit (fn:s as lambdas in most use cases
16:19EvanR,((fn [x] 4) 5)
16:19clojurebot4
16:20jro_very simple funs, e.g. #(= 5 %) are exception
16:20justin_smith(fn [& _] 4) ~= (constantly 4)
16:20justin_smiththat's also shorter, but constantly is still better
16:22EvanRhehe what is ~= supposed to be
16:22EvanRno infix in clojure!
16:22justin_smithis approximately equal to
16:22justin_smithright, it's not valid code
16:22EvanRconstantly takes any number of args
16:22justin_smithno two functions in clojure are ever equal, but those two have the same behavior
16:22EvanRi mean, the result
16:22justin_smithEvanR: so does my anonymous function
16:22justin_smithit takes 0 or more args
16:22EvanRi see that
16:23EvanRexactly one is fine with me
16:27jro_what http client library you use in clojure?
16:27jro_mostly I've used clj-http, but like to find good alternative for async processing
16:27noonianclj-http or http-kit's client; they have similar interfaces
16:28EvanRi used http-kit
16:28noonianhttp://http-kit.org/client.html
16:31EvanRso this "a reader macro" is a thing built into clojure and not programmable?
16:31EvanR#"foo" #(%)
16:31jro_built-in
16:31eggheadEvanR: you can register your own readers to interpret tagged literals EvanR
16:32justin_smithEvanR: http://clojure.org/reader there is data_readers.clj
16:32EvanRwhat is a literal in this context
16:32EvanRill read the reader
16:32justin_smith"When Clojure starts, it searches for files named data_readers.clj at the root of the classpath. ..."
16:33jro_oh
16:40EvanRto prepend a character to a string its just (str "C" foo) ?
16:41justin_smithwell, that's prepending a one character string, but sure
16:41justin_smith,(str \C "foo")
16:41clojurebot"Cfoo"
16:41justin_smiththat's prepending a character
16:41EvanR,(str 'C' "foo")
16:41clojurebot"C'foo"
16:41EvanRblur
16:41justin_smiththat's not acharacter
16:42EvanR\C is a java char?
16:42justin_smithyes
16:42justin_smith' means quote
16:42justin_smithit doesn't get balanced
16:42justin_smith,'C
16:42clojurebotC
16:42justin_smith,(type 'C)
16:42clojurebotclojure.lang.Symbol
16:43justin_smith,(type \C)
16:43clojurebotjava.lang.Character
16:43EvanRwhats the difference between symbol C and keyword :C
16:44justin_smithsymbols are useful in making macros - they are usually resolved to some var
16:44nooniankeywords always evaluate to themselves; symbols are used for variable names and are looked up in the environment when they are evaluated
16:44EvanRinteresting
16:45noonian,a-symbol-that-hasnt-been-defined
16:45clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a-symbol-that-hasnt-been-defined in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:45noonian,(quote a-symbol-that-hasnt-been-defined-but-is-quoted)
16:45clojurebota-symbol-that-hasnt-been-defined-but-is-quoted
16:45noonian,:a-keyword
16:45clojurebot:a-keyword
16:45EvanR,((quote undefined-symbol))
16:45clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: Symbol>
16:46noonianyou just tried to call the quoted symbol
16:46EvanRi tried to evaluate it
16:46justin_smith,((quote undefined-symbol) '{undefined-symbol 1})
16:46clojurebot1
16:46noonianin a repl anything you type will be evaluated
16:46EvanR,(eval 'C)
16:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: C in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:46noonian,(eval (quote foo))
16:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:46justin_smith,(eval (quote *clojure-version*))
16:46clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
16:47noonian,'this-is-shorthand-for-quoting
16:47clojurebotthis-is-shorthand-for-quoting
16:47EvanRok
16:48EvanRim going to need a style guide pretty soon
16:48EvanRmy code is indented more than php
16:49justin_smithEvanR: check out bbatsov's clojure style guide
16:49EvanRdoh, nested #(.. %...) are not allowed
16:50justin_smithEvanR: yeah, which % would be which?
16:50EvanRyou know very well
16:50EvanRwell, nevermind
16:54amalloy_lunchEvanR: your code *will* end up more indented than php. that's not really a problem. in On Lisp, paul graham has this to say about functional programming:
16:54amalloy_lunchThe structure in a functional program comes entirely from the composition of arguments within expressions, and since arguments are indented, functional code will show more variation in indentation. Functional code looks fluid on the page; imperative code looks solid and blockish, like Basic.
16:55jakebasileI'm not sure why, but switching to Oracle's JDK seems to stop `lein ring uberwar` from hanging. I don't really know why - but there it is if anyone else sees it.
16:55TEttingergood to know, jakebasile
16:56EvanRamalloy: in other settings i avoid deeply nesting anonymous functions, it helps debug each one
16:56EvanRfor me
16:56justin_smithEvanR: it can help to use let to bind the anonymous functionas locally
16:57justin_smithEvanR: instead of literally putting each inside the other
16:57EvanRyes ive been doing that, i still end up with 1/2 of my horizontal space gone
16:57EvanRand you still cant test them in isolation (though it may not make sense depending on the closure)
16:59EvanRmy editor is auto indenting stuff all the way under the last word of the previous line, which could be 15 characters out
16:59TEttingeryou can use declare to make something not-an-error-to-be-called before it's defined, then define it after the call, and as long as the function is called after the definition runs, you're fine
16:59EvanRwhich is equivalent to like 7 tabs
16:59justin_smithEvanR: have some code you can paste and share? that may help for offering tips
17:00TimMcamalloy: Did that fl come from your machine or the place you copied it from?
17:01TimMc(in "fluid on the page")
17:01TEttingerflappy bird
17:01EvanRjustin_smith: no :(
17:01amalloywhoa
17:01amalloyTimMc: http://ep.yimg.com/ty/cdn/paulgraham/onlisp.pdf apparently has the fl ligature in it
17:02amalloyi didn't notice it at all
17:02TimMcMakes for fewer c㏊racte₨. :-P
17:03amalloyit actually looks like everywhere in that pdf that fl is used, he uses fl instead
17:05justin_smithflævør flæv
17:07llasramThat sort of ligature-insertion is something that TeX tends to do for you
17:21numbertenis there a core function that given a seq returns both its head and tail?
17:21numbertenlike: (foo [1 2 3]) => [1 '(2 3)]
17:21noonian,((juxt first rest) [1 2 3 4])
17:21clojurebot[1 (2 3 4)]
17:21numberteni always forget about juxt
17:21EvanRdo sequences necessarily end?
17:21numbertenthat's nifty, thanks
17:22nooniannp
17:22amalloyEvanR: no
17:22amalloy(range) is all the integers from 0 to infinity
17:22noonianEvanR: nope, you can have infinite seqs with no problems as long as you dont try to realize the whole thing
17:22justin_smith,(split-at 1 [1 2 3 4]) ; kind of
17:22clojurebot[(1) (2 3 4)]
17:23justin_smithI see many combined usage of take / drop that should be one call to split-at
17:23EvanRuncons
17:24amalloysnoc for life
17:24justin_smith,(let [[h & t] [1 2 3 4 5]] {:head h :tail t})
17:24clojurebot{:head 1, :tail (2 3 4 5)}
17:27EvanRsnoc doesnt append something to the end?
17:28amalloysnoc doesn't really exist in clojure. i just mentioned it because you were talking about uncons and it seemed relevant
17:29noonianyeah, i just checked if it was in core heh
17:29noonianyou guys are convincing
17:29noonianyou folks*
17:29technomancymirror-universe clojure
17:29justin_smithquick, someone make a pr https://github.com/gfredericks/clojure-useless/blob/master/src/clojure_useless/core.clj
17:30technomancyresulted from a freak nrepl accident
17:30EvanRappends to the end of an infinite sequence
17:31TEttingerinfinite dimensional sequence
17:32amalloyEvanR: actually there is a function to add to the end of an infinite sequence
17:32amalloyidentity
17:32justin_smith,(repeatedly #(repeatedly (range)))
17:32gfrederickspff.
17:32clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn>
17:32justin_smith,(repeatedly #(repeatedly #(range)))
17:32clojurebot#<IllegalStateException java.lang.IllegalStateException: Nested #()s are not allowed>
17:32EvanRrofl
17:33justin_smith,(repeatedly (fn [] (repeatedly #(range)))) ; oops
17:33clojurebot(((0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) ...) ((0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) ...) ((0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) ...) ((0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) ...) ((0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2 3 4 ...) (0 1 2...
17:33EvanRits the ordinal numbers
17:33justin_smiththat's some nice lazy ascii art there
17:33justin_smithEvanR: it's an infinite list of infinite lists of numbers
17:34EvanRwhy stop at just 2 levels
17:34justin_smithlaziness
17:34amalloyjustin_smith: an infinite list of infinite lists of infinite lists of numbers, actually
17:34justin_smith(the programmer kind)
17:34justin_smithamalloy: ahh, yeah, right
17:34EvanRan infinite list of infinite list of ...
17:34TimMcamalloy: (range) isn't infinite on any hardware
17:34TimMceven infinite hardware
17:34amalloy,(last (iterate repeat (range)))
17:35amalloythat's as far as you can go
17:35clojurebot#<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>
17:35TimMcFor that you need (iterate inc' 0) or something.
17:35EvanRthats int?
17:35nooniani feel bad for clojurebot
17:35amalloyclojurebot quailed in the face of my list's multidimensional glory
17:36TimMc,(range Long/MAX_VALUE Double/POSITIVE_INFINITY)
17:36clojurebot#<ArithmeticException java.lang.ArithmeticException: integer overflow>
17:38EvanR,Long/MAX_VALUE
17:38clojurebot9223372036854775807
17:38EvanR,(inc Long/MAX_VALUE)
17:38clojurebot#<ArithmeticException java.lang.ArithmeticException: integer overflow>
17:38EvanRthats awesome
17:39justin_smith,(inc' Long/MAX_VALUE)
17:39clojurebot9223372036854775808N
17:39EvanRwhats N whats inc'
17:39Bronsa,(class 1N)
17:39clojurebotclojure.lang.BigInt
17:40BronsaEvanR: inc' is like inc except it auto promotes to BigInt rather than overflowing
17:40TimMcrange used to use inc' (which used to be called inc)
17:40EvanRdoes big decimal act like floats or does it get arbitrarily big
17:41justin_smith,(*' Long/MAX_VALUE Long/MAX_VALUE)
17:41clojurebot85070591730234615847396907784232501249N
17:41justin_smithEvanR: it stays precise, and uses more and more memory to store the contents
17:42puredanger(/ Long/MIN_VALUE -1)
17:42puredanger,(/ Long/MIN_VALUE -1)
17:42clojurebot-9223372036854775808
17:42puredangershhh :)
17:43noonianhuh, i didn't know about those fns
17:43noonianthanks justin_smith
17:43justin_smithnoonian: np
17:43noonianer Bronsa i guess
17:43nooniani'm late to the party
17:44justin_smithnoonian: in this context TimMc brought it up first
17:44justin_smithregarding range not using inc'
17:44TimMcpuredanger: :-( :-( :-(
17:44Bronsa,(map (partial / Long/MIN_VALUE) (range -1 -10 -1))
17:44clojurebot(-9223372036854775808 4611686018427387904 -9223372036854775808/3 2305843009213693952 -9223372036854775808/5 ...)
17:44puredangerhey, it works for every other long value, so percentage-wise, it's pretty good
17:44Bronsathe sign flips :(
17:44TimMcjustin_smith: I will never not bring up range not being infinite.
17:44puredangerhttp://dev.clojure.org/jira/browse/CLJ-1253
17:45EvanR,(= (Long/MIN_VALUE) (/ Long/MIN_VALUE -1))
17:45clojurebottrue
17:45justin_smitherr
17:45EvanRtherefore 1 = -1
17:45justin_smithweird how Long/MIN_VALUE works in parens
17:45justin_smithnever even thought to try it
17:46Bronsajustin_smith: yeah, older syntax I guess
17:46justin_smith,(Math/PI)
17:46clojurebot3.141592653589793
17:46amalloyjustin_smith: i believe that's legacy syntax, before Long/MIN_VALUE worked at all
17:46TimMcew
17:46puredangeryeah
17:46Bronsa,(macroexpand '(Math/PI))
17:46clojurebot(. Math PI)
17:46TimMcWhat if I want to throw an exceptino about a number not being castable to an IFn?
17:47TimMc,((Math/PI)) ;; I have to add more parens!
17:47clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Double cannot be cast to clojure.lang.IFn>
17:47justin_smithTimMc: you can't get passed Math/PI as the form, you would get it's value instead
17:47BronsaTimMc: almost like C
17:55numbertenis there a reverse nth function that removes the nth element from a seq
17:59amalloynumberten: no, because it can't be made a very efficient function. if your algorithm involves doing that, you're encouraged to reconsider: there's always a better way
17:59dbaschnumberten: but if you must, (concat (take (dec n) s) (drop n s))
18:00noonianyou could write it with a lazy loop recur
18:00numbertenhm
18:00dbaschit’s o(n) regardless
18:01numbertenyeah I was willing to pay the O(n), was just curious if there was a core fn for it
18:03dbaschspeaking of useful things, there used to be a separate function somewhere that was the same as (juxt filter remove), wonder why that’s not in core
18:07amalloynoonian: there's no such thing as a lazy loop recur
18:07noonianer, lazy-seq macro and normal recursion
18:08gfrederickswhich util lib has take-while+1?
18:08SegFaultAXFinger trees would be nice.
18:10gfredericksdbasch: my guess is it's a questionable thing to advertise for general use since it's not very lazy-friendly
18:11dbaschgfredericks: it’s lazy-friendly if used properly
18:11amalloygfredericks: https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L365 ?
18:11dbaschlike everything I guess
18:13gfredericksdbasch: what's the proper use?
18:13gfredericksamalloy: yep that's it
18:14dbasch&(map #(take 3 %) ((juxt filter remove) even? (range))) ;; e.g.
18:14lazybot⇒ ((0 2 4) (1 3 5))
18:14gfrederickswhat if you intend to consume all of each sequence? but they're both too big to fit in memory?
18:15dbaschgfredericks: how is that different from any other case of laziness / eagerness?
18:16dbaschon my computer (range) doesn’t fit in memory
18:16dbaschbut I’m a poor boy
18:17gfredericksdbasch: e.g., (let [nums (range 10000000000), [evens odds] ((juxt filter remove) even? nums)] (doseq [n evens] ...))
18:17gfredericksyou can't process either result as lazily as you can with other lazy ops
18:18gzmmsk,(= (+ 0.1 0.2) 0.3)
18:18clojurebotfalse
18:18gzmmsk,(= (+ 0.2 0.2) 0.4)
18:18clojurebottrue
18:19Bronsagzmmsk: that's how floating points work
18:19EvanRin clojure, when talking about lazy streams, is there an implicit assumption that getting the next thing in the stream will do IO?
18:19EvanRor might
18:19gzmmskBronsa: hmm... trying to write tests for my CG algorithms. so this is impossible?
18:20justin_smithEvanR: the next item may produce any kind of side effect when realized, but putting side effects in lazy sequences outside of a debugging scenario is probably a mistake
18:21SegFaultAXgzmmsk: You should test it the way you test any floating point algorithm. Using an appropriately sized epsilon to account for the inability to represent certain numbers correctly.
18:21EvanRwhoever said that can you please repeat, possibly in a PM :(
18:21gfredericksincidentally this isn't floating point's fault, it's binary fractions in general
18:22Bronsagzmmsk: well you can use BigDecimals instead of doubles to get more precision
18:22gfredericks,(= (+ 0.1M 0.2M) 0.3M)
18:22clojurebottrue
18:22SegFaultAXIf you want to add M to all your numbers.
18:22SegFaultAXYea
18:22gfrederickshow does that work; are BigDecimals base 10?
18:23gfredericks,(reduce + (repeat 10000 0.1M))
18:23clojurebot1000.0M
18:23gfredericks,(reduce + (repeat 10000 0.1))
18:23clojurebot1000.0000000001588
18:23dbaschgfredericks: the answer is in the name :P
18:24amalloygfredericks: they are, yeah
18:24gfredericksI hate the word decimal
18:24dbaschdecimate all decimals
18:24amalloyi'm decimated whenever i hear it
18:24justin_smithgfredericks: clearly we need decibenes
18:24Bronsaoh no, not again
18:25gfredericksit's supposed to mean "base 10" here but surely 99% of everyday usage refers to the method for representing fractional parts of a number
18:25gfrederickswhich can be done in binary in the same fashion
18:25amalloycomputers usually use binary decimals
18:25gfredericksit's even called a "decimal point" wtf
18:25bostonaholicyou mean a binary decimal?
18:26SegFaultAXgfredericks: You mean it's confusing to overload the same term with multiple orthogonal meanings?
18:26gfredericksin any case, if you had a fixed-point binary "decimal" number it would also fail to (= (+ 0.1 0.2) 0.3)
18:27gfredericksSegFaultAX: I think what bothers me is I don't have a fallback word for the positional-fraction-representation-system-thing
18:27gfrederickson the other side I can fallback to "base 10" if I want to be precise
18:27dbaschyou can try to make “denary numbers” happen
18:28SegFaultAXdbasch: Stop trying to make denary numbers happen. It's not going to happen.
18:28dbaschthat’s so denary of you
18:28SegFaultAXSo fetch.
18:28gfredericks"pointed numbers"
18:28justin_smithgzmmsk: ##(Math/ulp 1.0) - for your testing, ulp may come in handy
18:28lazybot⇒ 2.220446049250313E-16
18:28gfredericksI'll define that up front if I ever give a talk on the subject
18:29justin_smithgzmmsk: Unit In Last Place
18:29lodinIs there a way to not import java.lang classes? So that e.g. (defrecord String []) wouldn't throw an exception. (java.lang.String should still be available in it's fully qualified form.)
18:29dbaschwhen I talk about my age, it’s always 0x something
18:30SegFaultAXlodin: Why do you want to do this?
18:30gfredericksSegFaultAX: probably the same reason we encourage reusing names in clojure.core?
18:30justin_smithdbasch: you may want to stop when you are 57004 years old
18:31dbasch(inc justin_smith) ; lol
18:31lazybot⇒ 102
18:31gfredericks,(Long/toString 57004 16)
18:31clojurebot"deac"
18:31lodinSegFaultAX: I have a name that makes sense, but it was taken by java.lang. The full name for my class would of course be foo.bar.X (where X is String above).
18:32SegFaultAXlodin: I fear using a name that is protected in all of Java-land would probably be confusing. Either way, I don't know how to make that name not protected in a namespace.
18:33justin_smith,0xdead ; gfredericks
18:33clojurebot57005
18:33justin_smithbut you probably got that already
18:34lodinSegFaultAX: Ah. Is java.lang names forbidden as class names in other java namespace as well? (I don't know Java.)
18:34gfredericksjustin_smith: yeah I'm sooper good at incrementing hex numbers in my head
18:35SegFaultAXlodin: AFAIK. But I've never really tried. java.lang is the most special namespace in Java.
18:36TEttinger,36rALIVE
18:36clojurebot17800394
18:37amalloyi think you can shadow java.lang classes, but it's just as un-fun in java as in clojure
18:37gzmmskgreat way to use bigdec. thanks for the pointer!
18:37SegFaultAXamalloy: `class String` doesn't blow up? TIL.
18:38lodinSegFaultAX: Just to be clear, I'm not trying to do anything crazy. It's just that if I want to have a record or protocol called e.g. Compiler, I can't.
18:39SegFaultAXlodin: Oh I'm with ya. I'm sure it makes sense, but it may still be a bad idea.
18:39SegFaultAX(Makes sense in the context of your project, that is)
18:40amalloySegFaultAX: yeah, works fine, not even a warning. you just have to refer to java.lang.String longhand anywhere you want to refer to it, within that file
18:41amalloypackage whatever; public class String {public static java.lang.String get() {return "test";}}
18:41SegFaultAXNeat!
18:44gfredericksI am pleasantly surprised that the 2r101... syntax can create bigints if necessary
18:45lodinSegFaultAX: I realized I can just (ns-unmap *ns* String).
18:46lodin'String, that is.
18:46SegFaultAXlodin: Be careful, have fun! :)
18:47gfredericksyou can even do it in your (ns)
18:47lodinSegFaultAX: I've changed the name already. :-)
18:48gfredericks(ns foo (:ns-unmap foo String)) ;; works
18:48bearfeederHey all... I'm working on a project where I need to capture generated bytecode so I can transport that bytecode (rather than the raw Clojure source) to another address space
18:48bearfeederI've been digging through Compiler.java
18:48lodingfredericks: Ah. Haven't seen that one before.
18:48gfrederickslodin: I think it only works by accident
18:48bearfeederBut I haven't found a place I can hook into to get the generated bytecode and list of generated classes
18:49bearfeederSo, is there a nice way to capture the bytecode?
18:49lodinIs there a reason all (?) of java.lang is imported by default?
18:49lodinI get that we want String and other data types, but the rest?
18:49gfrederickslodin: you'd rather have to ask for it? there's no import-all functionality anyhow
18:53lodingfredericks: I guess so, yeah. For the same reason :use is discouraged. (Except the core of course.)
18:53gfredericksit's certainly more intuitive to java folk
18:55amalloyi mean, what is there in java.lang that you *don't* want? most of the stuff there is pretty primitive, stuff you'd just assume you can access
18:55gfredericksRuntimePermission
18:55gfredericks,Void
18:55clojurebotjava.lang.Void
18:56amalloygfredericks: yeah, yeah, obviously there's stuff you don't need. but is any of it actually in lodin's way?
18:56amalloylike, excluding the stuff you don't need doesn't buy you anything, because it doesn't conflict with anything you'd write anyway
18:56amalloyand if sun decided it was important enough to automatically import, who are you to decide that they were only right about half of it, or whatever
18:57gfredericksClassValue is weird
18:57amalloyhuh, i didn't know about that one. new to 1.7
18:57justin_smithgfredericks: woah, weird, Void is a class that never has instances
18:58gfredericks,(Void.)
18:58clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Void, compiling:(NO_SOURCE_PATH:0:0)>
18:58amalloyjustin_smith: used in reflection
18:58gfredericks,Void/TYPE
18:58clojurebotvoid
18:59gfredericks,(make-array Void/TYPE 3)
18:59clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException>
18:59technomancyanyone want to take bets on it having wacky equality semantics?
18:59amalloytechnomancy: how could it? any semantics at all are correct, if you can't instantiate it
19:00gfredericks,(= Void Double/NaN)
19:00clojurebotfalse
19:00gfredericks,(= Void Void)
19:00clojurebottrue
19:00technomancyamalloy: I figured at least one instance might be created by the JVM internally?
19:00amalloyi don't think so
19:00gfredericks"an uninstantiable placeholder class"
19:00lodinYou're right. I forget that many clojure programers are also Java programmers.
19:01gfrederickslodin: I suspect java programmers were the original audience
19:01dbaschit would be hard to mess this up http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Void.java/?v=source
19:02amalloydbasch: so much wordier than the haskell equivalent: data Void
19:02dbaschamalloy: in Java you literally can’t do nothing in less than 6 or 7 lines
19:03dbaschat least with proper formatting
19:03lodingfredericks: And indeed the connection to the Java world was what originally got me interested. :-) Not for Java's sake, but for the availability of libraries.
19:03gfrederickslodin: the java.lang library is the best!
19:04gfredericksit has...some kinds of numbers...
19:04gfredericks,Compiler
19:04clojurebotclojure.lang.Compiler
19:04gfrederickswoah what
19:04gfredericks,java.lang.Compiler
19:04clojurebotjava.lang.Compiler
19:04gfredericks&Compiler
19:04lazybotjava.lang.SecurityException: You tripped the alarm! class clojure.lang.Compiler is bad!
19:05gfredericks,EnumerationSeq
19:05clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: EnumerationSeq in this context, compiling:(NO_SOURCE_PATH:0:0)>
19:05gfredericks,IPersistentQueue
19:05clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IPersistentQueue in this context, compiling:(NO_SOURCE_PATH:0:0)>
19:05hiredmanhttp://docs.oracle.com/javase/7/docs/api/java/lang/Compiler.html#command%28java.lang.Object%29 best documentation ever?
19:05Bronsahiredman: it's c.l.Compielr, not j.l.Compiler
19:05Bronsacompiler*
19:06technomancyhiredman: wow
19:06Bronsahiredman: uh missed context, nvm
19:06hiredmanBronsa: but there is a java.lang.Compiler, which I had never seen before
19:06gfredericksand it has great docs
19:07justin_smith"Examines the argument type and its fields and perform some documented operation. No specific operations are required." <- can we put this in -main in lein new?
19:07gfredericksbut also while Bronsa is here why on earth does 'Compiler of all things go to clojure.lang?
19:07Bronsagfredericks: no technical reason
19:07gfredericksjust for funsies?
19:07BronsaI guess
19:08gfredericksfigures it's the only thing refer'd from clojure.lang and it happens to shadow something from java.lang
19:08Bronsagfredericks: fun thing is, it's always qualified in the clj files
19:09tufti had a crazy idea: what about a clojure shell? i.e. to take the role of zsh, bash, etc.
19:09tuftobviously would need to communicate with a persistent jvm
19:09justin_smithtuft: you could use scsh as a launching off point design wise
19:09TEttingertuft, and it would need to respond correctly to stuff like ctrl-d
19:09Bronsagfredericks: looking at the impl, it's probably a bug actually
19:10tuftTEttinger: i think you'd write the interface stuff in native code or borrow some from somewhere maybe
19:10tuftjustin_smith: cool thanks
19:10Bronsagfredericks: it should refer to j.l.Compiler but c.l.Compiler is shadowing it https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L58
19:11amalloythat's pretty funny, Bronsa
19:12hiredmanwell, it isn't like java.lang.Compiler is used
19:13tuftjustin_smith: fails my first test, which is that all the usual bourne pedigree built-ins should be functions that work out-of-the-box
19:13gfredericksBronsa: wow good catch
19:13gfrederickswhat are the chances a patch would be rejected as a breaking change?
19:16hiredmanhttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L33-L34 also amusing
19:16Bronsagfredericks: close to the chances a patch has to be accepted in a reasonable amount of time I'd say
19:17bbloomhiredman: ha
19:17bbloomhiredman: i particularly like how F was "t"
19:23Bronsahttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L2060-L2065 wat
19:24eggheadlooks legit Bronsa
19:33dbaschBronsa: values? We don’t need no stinkin’ values!
19:39SegFaultAXI, uh. What?
19:40gfredericksit's clojure's secret sauce
19:41SegFaultAXSo that's where it is. I always wondered where they kept it.
19:41dbaschit’s the Clojure Mojo, aka CloJo
19:42oskarkvWhy do I get this error? https://www.refheap.com/ada027007d68400bd52bddc77
19:43gfredericksI don't know.
19:44SegFaultAXIs this a cider session we're looking at?
19:44amalloyoskarth: that is like a million lines of code, which use functions that aren't defined in this file
19:45SegFaultAXIs it possible the namespace was reloaded?
19:45oskarkvSegFaultAX No, not cider.
19:49gfredericksoskarkv: it will probably help a lot to try to minimize the example
19:50oskarkvamalloy The error seems to be specifically about calling hudnode-code, which I just defined. The contents of that functions should not matter, I think; the error is about trying to call it, no?. And my second batch of input uses only one other macro, "with-gensyms".
19:52oskarkvgfredericks yeah I'll try
20:03{blake}Is possible to un-import?
20:04gfredericks,(doc ns-unmap)
20:05clojurebot"([ns sym]); Removes the mappings for the symbol from the namespace."
20:05gfredericks,(import 'java.util.UUID)
20:05clojurebotjava.util.UUID
20:05gfredericks,(ns-unmap *ns* 'java.util.UUID)
20:05clojurebotnil
20:05gfredericks,UUID
20:05clojurebotjava.util.UUID
20:05technomancymutability!
20:05technomancy~guards
20:05clojurebotSEIZE HIM!
20:06gfredericksoh wait
20:06gfredericks,(ns-unmap *ns* 'UUID)
20:06clojurebotnil
20:06gfredericks,UUID
20:06clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: UUID in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:06gfredericksthat was it
20:07{blake}(inc gfredericks)
20:07lazybot⇒ 99
20:07{blake}daaaww....so close
20:07{blake}Thanx!
20:15TEttinger,(rand-int 2)
20:15clojurebot0
20:15TEttingersorry gfredericks, you get +0 karma
20:17gfredericksquick I gotta tell a good joke
20:19amalloygfredericks: make it a calculus joke. people love to look smart by laughing at those
20:19gfredericksokay so rich hickey, stu halloway, and alex miller walk into a bar
20:21gfredericksand the bartender says "this must be clojure conj"
20:22gfredericksso that's the joke.
20:22amalloygfredericks: i was really looking forward to a punch line
20:23gfredericksI considered having the bartender complain about stacktraces
20:23SegFaultAXDefinitely an immutability joke in there somewhere.
20:24amalloygfredericks: rich asks for a new england martini, and the bartender brings back sixty empty glasses, all stacked inside each other: "sorry, i haven't heard of that one"
20:24gfrederickslol
20:24gfredericks(inc amalloy)
20:24lazybot⇒ 176
20:25gfredericksaw crap that's not how this was supposed to end
20:25amalloy*chuckle* situational humor is more fun anyway
20:25amalloy(inc gfredericks)
20:25lazybot⇒ 100
20:26amalloyokay, audience participation time: the joke needs punchlines for alex and stu too
20:33SegFaultAXamalloy: I don't get your joke, what did I miss?
20:34amalloySegFaultAX: the cups are a stacktrace from attempting to resolve an unbound drink order. if you care to look further, you can consider that they're empty and useless to rich, just like clojure beginners think stacktraces are
20:35SegFaultAXAh. Nice.
20:37amalloythe best jokes require lengthy explanation
20:38SegFaultAX,(doc joke)
20:38clojurebotPardon?
20:52visofhi
20:52visofhow can i convert this to clojure https://www.refheap.com/92128?
20:52visofhow can i convert this to clojure https://www.refheap.com/92128 ?
20:53visof(.flatMap lines <fun here>)
20:54visofguys can anybody help ?
20:54seancorfieldvisof: looks like it splits a sequence of lines into a sequence of words, split at whitespace?
20:54amalloyvisof: some folks might be inclined to help you, but if you paste the same message twice in two seconds and then prod them to hurry up in under two minutes, that's not very polite
20:55amalloythe clojure equivalent of `new Foo() {public whatever bar(int x) {return y;}}` is (reify Foo (bar [this x] y))
20:55seancorfield,(clojure.string/split "A line\nAnother line\n" #"\s")
20:55clojurebot["A" "line" "Another" "line"]
20:55Jaoodis that java 8 code?
20:56amalloyseancorfield: i think the point is to translate the java into java-interop forms, not to find out how to split a string
20:56visofamalloy: i sent it twice to correct the link by removing ?
20:56seancorfieldIt depends what visof means by "convert this to clojure"...
20:57amalloythat's true, i suppose
20:57seancorfieldI was going to suggest (mapcat (fn [line] (clojure.string/split line #"\s")) lines)
20:57seancorfieldI just wondered whether #"\s" matched newlines so I asked the bot
20:57clojurebotExcuse me?
20:59amalloyseancorfield: a more interesting question is whether #"." matches newlines
21:00amalloythe answer turns out to be that it depends: you can pass in a flag saying which way you want it to act, with the ?s flag
21:01amalloylike in #".(?s)." the first . doesn't match newlines, but the second does
21:04visofamalloy: so the piece of java i posted should be converted to (.flatMap lines (FlatMapFunction. (reify FlatMapFunction (call x) x))) ?
21:05visofamalloy: i returned x because x don't splitted
21:05visofi got error, so i'm just return x for now to try to figure it out
21:13visofamalloy: ?
21:20visofhi guys not body can help?
21:27Bronsavisof: work with this (.flatMap lines (reify FlatMapFunction (call [x] your-impl-here)))
21:28Bronsavisof: but please don't keep asking for help, this isn't a helpdesk and pinging people for help isn't really polite
21:28seancorfieldvisof: I answered your question with idiomatic Clojure about half an hour ago
21:29seancorfieldit's also past the end of the working day in the USA so I expect a lot of folks are just idling / away at this point
21:30seancorfieldit's 6:30pm here in California and I'm about to go feed the cats and then have dinner / watch TV...
21:46numbertenbeen playing around with this function for a bit anyone mind looking it over for me? http://pastebin.com/euKX8SiT getting IndexOutOfBounds errors though not sure how/why
22:14ed-gStraw poll. What's everyone's favorite way to build forms for the editing of data in a relational database? I'm a fan of Enlive for HTML templates, and YESQL for relational database access.
22:17beppued-g: I'm not using Clojure, yet, but I use React.js on the front-end. (no templates; just React components).
22:19numbertensolution to that pastebin (for any interested), was removing the first 0-arity case and replacing it with a (cond (empty? colls) nil :else <old case>)
22:19numbertendoesn't really explain why the old version threw an indexoutofbounds, but seems to work nonetheless
22:21quilenumberten: couldn’t it throw here: (drop (inc i) colls) if i was the index of the last item in colls?
22:21justin_smithnumberten: ##((fn [cols] (nth cols (rand-int (count cols)))) [])
22:21lazybotjava.lang.IndexOutOfBoundsException
22:21justin_smiththat's what it did every time
22:23numbertenah
22:23ed-gbeppu: thanks. react looks really cool, but for maximum compatibility I'm building this as an "old fashioned" server-side web app.
22:23quilei take that back… (drop …) doesn’t care
22:23numbertenyeah (nth [] 0) >.>
22:23numberten,(nth [] 0)
22:23clojurebot#<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>
22:24numbertenweirdly enough I had print debugs in the let and they would only ever fire for the first call to the function
22:24numbertenyou'd think they would have fired since the case where colls = [] is at the very end
22:25justin_smith,(nth [:a] (rand-int 1))
22:25clojurebot:a
22:25justin_smith,(nth [:a] (rand-int 1))
22:25clojurebot:a
22:25justin_smithhmm
22:27numbertenyeah if you add a _ (println "foo") to the let in the original
22:27oskarkvSpent a while, more than I care to admit, on debugging an "unable to resolve symbol" error, that came from me trying to use a record function body as a closure.
22:27numbertenand do (foo [(range 10)]), you get one print and then the exception
22:28oskarkvIf only the error message was more specific. :P
22:41gizmo385If I have a type, Vertex, and I want to call a function defined in the Vertex type from another type, how can I do that?
22:41gizmo385Every time I've tried, I get "no matching method" errors
22:43gfredericksgizmo385: can you show us what you tried exactly?
22:44gizmo385(let [new-u (IVertex/connectTo u v)] ...
22:45gizmo385Where IVertex is the interface that defines connectTo
22:46gizmo385I've also tried to replace (IVertex/connectTo ...) with (Vertex/connectTo ...) which is the type that implements IVertex
22:48gfredericksIVertex is an interface? is `u` an object that implements IVertex?
22:49gizmo385u is a Vertex, which implements IVertex
22:51gfredericksokay, then I think you want (.connectTo u v)
22:51gfredericksthey syntax you're using is only for static methods
22:51gfredericksthe*
22:51gizmo385Ah okay
22:52gizmo385If I have a function defined in IVertex that has the same name as a function in another interface, how can I specify which one I want to call?
22:53gizmo385Or will it just figure it out?
22:53gfredericksI don't think java really allows that situation?
22:53gizmo385I suppose the way I phrased that was somewhat confusing
22:53gizmo385If I'm in a type A
22:54gizmo385that contains instances of type B
22:54gizmo385and both A and B defined some function f
22:54gizmo385If I want to call f, how can I specify which f I want to call?
22:54wefa.f or b.f
22:55gfredericksgizmo385: what do you mean by being "in a type A"?
22:55gizmo385I'm defining a function inside type A
22:55gfrederickswith deftype or defrecord?
22:55justin_smithgizmo385: since we have actual functions (and hell even java has java.util.function.Function) please use the word method to refer to methods
22:56justin_smithgfredericks: he is talking about methods on classes
22:57gfredericksjustin_smith: I realize that much, but it sounds like he's defining a method, so was just interested in what that meant
22:57gizmo385deftype
22:58gfredericksgizmo385: inside a deftype method is pretty normal clojure code -- the only thing magical about it is that the fields of the deftype are lexically available
22:58gizmo385Sorry for calling them function, I'm still trying to get the hang of the lingo in clojure. The class structure is different from what I'm used to
22:58gizmo385Ah okay. That makes sense.
22:58gfredericksgizmo385: so doing method calls works the same way there as elsewhere, i.e. the meaning of the method call depends on the type of the object you're calling the method on
22:58gizmo385Thanks :)
22:59justin_smithgizmo385: well, on top of that, clojure functions are classes! (that's how they can be first class) it's a different world
23:00gizmo385justin_smith, how does it handle the typing?
23:00justin_smith,(class (fn []))
23:00clojurebotsandbox$eval25$fn__26
23:01justin_smith,(class (fn []))
23:01clojurebotsandbox$eval51$fn__52
23:01justin_smitheach is it's own class with only one instance
23:02gizmo385Has this changed since the introduction of lambdas in Java 8?
23:02rritochgizmo385: Types only define the interface (arguments and return types) which an implementing class must implement (unless it is abstract). If the two interfaces define different arguments than you can define your method in clojure with separate implementations for each if the number of arguments is different, otherwise you may need to rely on conditional logic (instance?) to determine which
23:02gizmo385The introduction of the new bytecode instruction seems like it would provide significant performance increases for a language like Clojure
23:02justin_smithgizmo385: we don't use java lambdas (yet?) - we target 1.6 compatibility
23:02TEttingerno, that would reduce availability to JDK 8 only
23:02gizmo385Ahh
23:03rritochgizmo385: This is a fairly core feature of Java and an annoyance when part of a team where co-workers insist on using the same function name in multiple interfaces.
23:04justin_smithmethod, please, no need to add confusion here
23:04rritochjustin_smith: In clojure function is appropriate for methods since the java method actually calls the clojure function
23:11rritochgizmo385: What you can do, is "wrap" the second interface in it's own class and create an instance of it within one of the classess. Such as (defn -init [] [[] {:b (B.)}]) (defn -WrappedMyMethod [this] (.MyMethod (:b (.state this)))
23:13rritochgizmo385: You could also use inheritance, having a parent class implement one interface, have the child class implement the other and utilize exposes-methods which would fundamentally produce the same result without needing to maintain a separate object.
23:14amalloyjustin_smith: functions aren't classes, they're objects. and they're not singletons either, necessarily: in any app you've written i'm quite sure there are multiple instances of the same function class
23:15justin_smithOK
23:15amalloyconsider, eg, ##(letfn [(f [x] (fn [y] (+ x y)))] (map class [(f 1) (f 2)]))
23:15lazybot⇒ (sandbox5671$eval11877$f__11878$fn__11879 sandbox5671$eval11877$f__11878$fn__11879)
23:16rritochgizmo385: I have this problem with my daily work because my boss incists on using "start" as the method to initiate the a modules function, but OSGi uses start to start the bundle. Thanks to this fundamental flaw in design it is impossible to have the activator double as the OSGi service.
23:16raspasovdoes anyone have experience with best practices regarding triggering IO from from inside a (go ) core.async block?
23:16amalloya function's class represents its code, more or less, and instances of it represent the lexical scope of a particular instance of that class
23:16raspasovI know IO within a (go ) is discouraged
23:18raspasovso I'm thinking about starting a (future) from inside the Go block, passing a (chan 1) to that future and waiting within the (go ), aka parking via (<! (chan 1)), for a response on that same (chan 1)
23:19raspasovbecause I don't want to continue the Go block unless that (future) is successful
23:19justin_smithso the future would do all the printing
23:19raspasovthe future tries to write to a log file
23:19raspasovi.e. disk IO operation
23:20justin_smithwhat about a dedicated logging thread, it takes a task and a chan from it's in chan, writes out the task, sends a status back to the chan
23:22raspasovlet me do a gist
23:27raspasovhttps://gist.github.com/raspasov/f16ea712780e6c90908b
23:27raspasovgithub wasn't coloring the syntax but somehow I made it do it lol
23:28raspasovjustin_smith: the (start-write-loop) is essentially a dedicated logging thread (lightweight go thread)
23:29raspasovit buffers a bunch of writes for ~1ms, sends them to disk, and confirms all those writes to the caller
23:31raspasovI'm doing a lot of disk because I'm trying to balance between throughput and speed of writing
23:31raspasovI'm doing all of this*
23:31raspasovsorry
23:31raspasovI'm doing all of this because I'm trying to balance between throughput and safety
23:32raspasovthe previous sentence didn't make sense :0
23:32raspasov:)
23:32rritochraspasov: Why are you trying to implement synchronous logic in an asynchronous system? The asynchronous way of handing "wait" conditions is to have the IO function call a callback function when it completes. Typically this would be done with a state variable (atom), you can go into a wait mode after calling future, and the callback could then set either a success or fail state.
23:32justin_smithraspasov: so is each spit going to a different file?
23:33raspasovjustin_smith: no it's the same file
23:33rritochraspasov: Sometimes you may need to put intermediate data into a queue which gets processsed from the callback, but that depends on your application
23:33justin_smithraspasov: you'll get much better performance by leaving the file open
23:34justin_smithrritoch: the point of core.async is to eliminate callbacks and use channel ops as their replacement
23:34raspasovjustin_smith - but I do want to flush it to disk on a regular basis (~1ms)
23:34justin_smithraspasov: (flush)
23:34justin_smithor the jvm interop which accomplishes this for your particular stream
23:35raspasovI see, so you're saying try to keep the file always open
23:35raspasovI did a benchmark, and open/close once per 1ms didn't seem like it made a difference, but I might be wrong
23:36justin_smithraspasov: I think you'll get the most robust design and best throughput if one thread simply has the file open, takes requests for doing output from a channel, each one accompanied by a "status" channel, and once writing and flushing sends a status back on that channel
23:36raspasovrritoch: if you look at the code, I believe I'm almost doing what you're describing
23:36justin_smiththe requesting go block can park on the status channel
23:36raspasovrritoch: via the (chan 1)'s that I'm passing
23:37raspasovjustin_smith: thanks for the input, that makes sense, I'll try doing that
23:37raspasovjustin_smith: I'm almost doing that, with the only difference that I'm closing/opening the file instead of just flushing it
23:41raspasovjustin_smith/rritoch: thanks for the feedback guys, much appreciated, I'll give it a try
23:41justin_smithraspasov: yeah, I'd use clojure.java.io/writer to create a BufferedWriter, and then periodically call the .flush method on that stream
23:42justin_smithraspasov: that also means you can eliminate the buffering logic - the underlying class has that covered
23:42justin_smithyou can simplify your code immensely
23:43rritochraspasjustin_smith: It looks like I solved the AOT/script issue I was talking to you about yesterday.
23:44justin_smithoh yeah?
23:45rritochI created a new macro (fscript) which creates an gensym named function with metadata of :fscript true
23:46rritochAnd this is the runner: (defn run-fscripts [script-ns] (doseq [[s v] (doall (filter #(:fscript (meta (second %))) (ns-publics (symbol script-ns))))] (v)))
23:47rritochThere is also a loader in play at another layer of this system, which doesa load-reader loading if the namespace isn't yet defined (find-ns)
23:48rritochThis should solve the performance issues since loading only needs to happen once, I haven't yet fully tested within the application, but these functions are working, so I'm not yet sure if the load is ever needed when the system is aot compiled.
23:49rritochThe only dilema is if a reload occurs the namespace doesn't get cleaned-out first (require :reload-all) so you end up with multiple copies of the script, running and a giant memory leak.
23:50justin_smithrritoch: I don't understand why you need functions with gensym names, why not for example a vector of functions (that could be reset to nil so that they can be garbage collected)
23:52rritochjustin_smith: resetting a vector to nil, and deleting a namespace before reloading it is fundamentally equivalent operations.
23:53justin_smithsure, but one of them doesn't involve creating a bunch of vars with nonsense names
23:53rritochjustin_smith: Both methods are possible, this is just the one I went with.
23:53rritochThe names aren't nonsense
23:54justin_smithgensyms are nonsense
23:54rritochI'm using (gensym "__fscript_") so they're easily identified as fscript functions with or without the metadata
23:55rritochThe metadata is simply to allow developers to name the functions themselves
23:55rritochInstead of (fscript ...) they can (defn ^{:fscript true} MyScript [] ....)
23:58rritochEither way, needing to remove-ns before reloading is a fairly small price to pay for the performance advantage of not needing to compile multiple scripts on every http request.
23:58rritochcompile and/or eval