2014-11-20
| 00:05 | technomancy | TimMc: whoa |
| 00:15 | FriedBob | Woo hoo! Figured out how to get the edn-config stuff and not have to use profiles. Now I can move on to the meat of the project and see how much of what I have read has stuck. |
| 00:26 | kenrestivo | is there a way in schema to say, i want a map here, but its structure is opaque and i don't have time to specify the whole deep thing? |
| 00:27 | kenrestivo | i.e. {:foo s/SomeRandomMapIDontControl} |
| 00:34 | rritoch | kenrestivo: XML Schema? |
| 00:34 | kenrestivo | prismatic schema |
| 00:34 | kenrestivo | https://github.com/Prismatic/schema |
| 00:37 | rritoch | kenrestivo: Hmm, sorry can't help you there... is XSD it's <xs:any namespace="##any" processContents="skip"/>, no idea what prismatic would use since I've never used it. |
| 00:40 | rritoch | kenrestivo: Looking at the source though it looks like there is an Any, I'm just not sure what syntax you'd use |
| 00:40 | rritoch | https://github.com/Prismatic/schema/blob/master/src/cljx/schema/core.cljx#L242-L244 |
| 00:40 | rritoch | kenrestivo: Maybe s/Any |
| 00:40 | kenrestivo | yeah i saw that. also an empty map seems to work {} |
| 00:40 | kenrestivo | i want to specify that it's a map, just not what's in the map |
| 00:41 | kenrestivo | {s/Any s/Any} might work too |
| 00:47 | ambrosebs | kenrestivo: perhaps (s/pred map? 'map?) |
| 00:47 | ambrosebs | just going off the readme |
| 00:48 | kenrestivo | it seems like there are several ways. so far {} works, {s/Any s/Any} works, {s/Keyword s/Any} works. pred probably can too. |
| 01:02 | rritoch | Where is the clojurescript syntax #+clj documented? It looks like a reader macro but I can't find documentation for it |
| 01:03 | justin_smith | rritoch: that's cljx notation |
| 01:03 | justin_smith | it means code that is only used in clojure (jvm) and not in clojurescript |
| 01:06 | rritoch | justin_smith: Thanks, that helps, checkout out the cljx now. I'm easing into clojurescript since the web platform is nearly fully functional. I added a http-mapper to the kernel, and an implementation to the core which should now make it possible to serve static files |
| 01:07 | rritoch | justin_smith: While doing that I realized that I can make a servlet specific for serving resolved ".clj" resources so that will probably be my next step which will invalidate the need for template engines since the role of delivering extension based content types would be taken over by servlets |
| 01:08 | rritoch | justin_smith: And this may also mean that within a month I should finally be out of the systems level code and actually into web application development |
| 01:21 | rritoch | Is it possible to "include" one lein plugin in another? Looking at the cljx features it looks like cljx would be very useful when generating OSGi bundles but I have a lein plugin which generates the OSGi bundles so I'm not sure how I could refrence cljx code from another leiningen plugin, I've never tried anything like that before. |
| 01:23 | rritoch | If I load cljx as a dependency instead of as a plugin would that make the cljx code available to my leiningen plugin? |
| 01:24 | justin_smith | rritoch: it should, yes |
| 01:25 | rritoch | justin_smith: Cool :) That's been one of the big complications I've been trying to resolve, how to compile clojurescript into web applications prior to deployment, and cljx seems to solve much of that problem, and provides the benefit of code-reuse between the server side (clj) and the client side (cljs). |
| 01:26 | rritoch | justin_smith: Sneaking into Web 5.0 land :) |
| 01:28 | clojer | Anyone deploying on Openshift? I'm missing something getting a default app to start. Probably something really obvious :( |
| 01:28 | rritoch | Someone in here was also working on making browser plugins using clojurescript which is another important leap I'll need to make to enter Web 5.0 land. Being able to offload processes to the client for offline processing is key to Web 5.0. |
| 01:31 | justin_smith | clojer: I don't know anything about openshift, but I know that it is easy to deploy an uberwar webapp to aws elastic beanstalk, and pretty straightforward to deploy a self-hosting webapp (ie. http-kit) on aws ec2 or heroku |
| 01:31 | justin_smith | clojer: in fact, technomancy works at heroku and often helps people here to get their apps set up to run there |
| 01:33 | clojer | justin_smith: I have the community cartridge and app setup but it doesn't appear to be started. I ssh'ed into the account and ran lein run but an error was returned: Could not transfer artifact lein-ring:lein-ring:pom:0.7.5 from/to clojars (https://clojars.org/repo/): Specified destination directory cannot be created: /var/lib/openshift/546d7bd35973ca795600002c/.m2/repository/lein-ring/lein-ring/0.7.5 |
| 01:34 | justin_smith | clojer: OK, what's your $HOME set to? |
| 01:34 | justin_smith | clojer: also, it's actually better not to use lein in production at all |
| 01:34 | justin_smith | build an uberjar, and then use java to run it on the server |
| 01:35 | clojer | justin_smith: I thought of trying EC2 but they take card details, if I remember, so you have to watch your usage. |
| 01:35 | justin_smith | clojer: ahh, so openshift has a straightforward free teir? interesting |
| 01:35 | clojer | justin_smith: Lein was a last resort. |
| 01:35 | justin_smith | clojer: did you try creating an uberjar and running it? |
| 01:36 | clojer | justin_smith: Yes. No card and no 1-year expiry .... as far as I'm aware :) |
| 01:37 | clojer | justin_smith: I'm not sure their setup allows this as I didn't setup an app server. You can go with Wildfly 8 but that's a different route. |
| 01:37 | justin_smith | what wouldn't their setup allow? |
| 01:37 | justin_smith | if lein will run, java will run |
| 01:38 | justin_smith | clojer: use an embedded server, I like http-kit |
| 01:38 | justin_smith | java -jar my.uberjar.jar |
| 01:38 | justin_smith | that's it |
| 01:38 | clojer | justin_smith: OK, I'll give it a try. I'm new to deployment as all my Clojure so far has been running locally. |
| 01:38 | justin_smith | (well lein uberjar to create the jar...) |
| 01:38 | justin_smith | clojer: OK. Uberjars make it amazingly simple. |
| 01:38 | justin_smith | it's a single file, you tell java to run it. That's it |
| 01:39 | clojer | justin_smith: How do I tell Java to run it? Sorry :) |
| 01:39 | justin_smith | I already said above "java -jar <name of uberjar>" |
| 01:40 | justin_smith | clojer: if your app will run via "lein run", it will usually run from an uberjar with no issues |
| 01:40 | clojer | Ah, thought that was creation. Great. |
| 01:40 | justin_smith | "lein uberjar" is creation |
| 01:40 | justin_smith | also pretty simple |
| 01:40 | justin_smith | the tricky part is it means your main needs to be aot compiled |
| 01:41 | justin_smith | but, alternatively you can run it via "java -cp <name of uberjar> -m clojure.main your.core |
| 01:41 | justin_smith | " |
| 01:41 | clojer | justin_smith: Does that mean I have to create teh uberjar locally and git-push? |
| 01:42 | justin_smith | clojer: you should be able to scp it |
| 01:42 | clojer | justin_smith: If so there's a JVM mismatch :( |
| 01:42 | justin_smith | I don't even like to have git installed on my server |
| 01:42 | justin_smith | clojer: jvm mismatch... |
| 01:42 | justin_smith | I've never seen that |
| 01:43 | justin_smith | clojer: were there any more details? |
| 01:43 | clojer | justin_smith: When I ran the app locally there was an error which seemed to refer to something deprecated in JDK 8 |
| 01:44 | justin_smith | so you created the uberjar, and tried to run it? |
| 01:44 | clojer | WARNING: :warn-on-reflection is deprecated in project.clj; use :global-vars. |
| 01:44 | clojer | Reflection warning, /private/var/folders/5h/4fvvcx856_lgdmyz0rxgtwgh0000gp/T/form-init3201957262574781917.clj:1:906 - call to invokeStaticMethod can't be resolved. |
| 01:45 | justin_smith | clojer: that's just reflection warnings |
| 01:45 | clojer | justin_smith: No, this was with `lein run` |
| 01:45 | justin_smith | clojer: those are not errors |
| 01:45 | justin_smith | OK |
| 01:45 | justin_smith | those warnings just mean that :warn-on-reflection is on, and you are getting reflection warnings |
| 01:45 | justin_smith | it's an optional feature that helps you get your code to run faster |
| 01:45 | justin_smith | if you use typehints and eliminate the warnings |
| 01:46 | justin_smith | but it doesn't mean your code won't run |
| 01:46 | clojer | justin_smith: It hung at that point, though. |
| 01:46 | justin_smith | OK |
| 01:46 | justin_smith | clojer: do you launch a server in your -main ? |
| 01:47 | justin_smith | I am assuming this is a ring app btw, is it? |
| 01:47 | clojer | justin_smith: Great discovery! It didn't hang. Just no feedback that it was running :) |
| 01:47 | justin_smith | oh, nice |
| 01:47 | clojer | justin_smith: Locally, that is. |
| 01:49 | clojer | justin_smith: I'll have another go getting it pushed and running. Thanks. |
| 01:49 | justin_smith | np |
| 01:50 | justin_smith | like I said, if lein run works, then running the uberjar should (which you can also verify locally) |
| 01:51 | clojer | justin_smith: Just one more thing. |
| 01:51 | justin_smith | OK |
| 01:51 | clojer | justin_smith: the default came with Clojure 1.5.1 so if I revert to the uberjar method do I assume I can upgrade everything to a higher version? |
| 01:51 | clojurebot | Titim gan éirí ort. |
| 01:52 | justin_smith | clojer: the uberjar will use whichever version of clojure your project.clj specifies |
| 01:52 | justin_smith | clojure is just another java library as far as the uberjar is concerned |
| 01:52 | clojer | justin_smith: Yes, thought so. |
| 01:52 | justin_smith | uberjars work fine with 1.5.1 in my experience |
| 01:54 | justin_smith | clojer: the reason I recommend uberjars and not using lein or git on the production machine is because it reduces the number of things that can be misconfigured (or differently configured) between your dev machine and prod |
| 01:55 | justin_smith | clojer: you have a guarantee that what runs on prod is the exact set of versions that worked locally, because uberjar grabs the same artifacts and packages them |
| 01:55 | clojer | justin_smith: Will use uberjar. I'd heard of it before but hadn't tried as I was doing everything locally. Cheers. |
| 01:55 | justin_smith | clojer: also, using a jar directly has faster startup time and lower memory usage than with lein, and that can matter a lot on production |
| 01:56 | justin_smith | clojer: I hope I didn't leave anything out... it's pretty simple though |
| 01:56 | clojer | justin_smith: I'm glad you mentioned that as I was originally going with Go for memory efficiency and because I wasn't aware that Clojure was an option at Openshift. |
| 01:58 | justin_smith | clojer: generally, if java will run, and you have sufficient RAM to spare, clojure will run |
| 01:58 | justin_smith | even android (though the startup time there is painful and the jvm is very nonstandard) |
| 01:59 | clojer | justin_smith: Openshift comes with 3 gears, each of which has 512Mb RAM but you can select a "scaling" option which appears to pool the combined resources. |
| 01:59 | justin_smith | interesting |
| 02:00 | clojer | justin_smith: More precisely it seems to add a Haproxy into the mix. |
| 02:00 | justin_smith | yeah, 512 is a limit you can hit fast in clojure, but with some care you should be able to make it work |
| 02:00 | justin_smith | clojer: that's a setup that isn't as good for clojure |
| 02:01 | justin_smith | clojer: for php or ruby, being able to route to different instances is a great way to scale, but clojure has a high baseline mem usage (thanks to the size of the lang, and the use of immutible data structures everywhere) but it scales very well in one instance |
| 02:02 | clojer | justin_smith: Yes, I'm hoping this "scaling" option creates a combined 1.5GB RAM but I have my doubts. |
| 02:02 | justin_smith | :) |
| 02:03 | clojer | justin_smith: I think the scaling is specific to web requests. |
| 02:03 | justin_smith | yeah, that just isn't what you do in clojure |
| 02:03 | clojer | justin_smith: You never know, though. |
| 02:03 | justin_smith | clojer: so for php you have one process per request |
| 02:03 | justin_smith | clojer: clojure handles threads, and long living processes very nicely |
| 02:04 | clojer | justin_smith: Some warning with uberjar: Warning: specified :main without including it in :aot. |
| 02:04 | justin_smith | clojer: I've done pretty big corparate sites, and I have used a lot of ram, but never more than one machine / vm instance |
| 02:04 | clojer | If you only need AOT for your uberjar, consider adding :aot :all into your |
| 02:04 | clojer | :uberjar profile instead. |
| 02:04 | justin_smith | clojer: that means you should use the java -cp option I mentioned |
| 02:04 | clojer | Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method. |
| 02:05 | justin_smith | clojer: how do you usually run the app? |
| 02:05 | clojer | justin_smith: `lein run` |
| 02:05 | clojer | justin_smith: My first use of `lein uberjar` |
| 02:06 | clojer | justin_smith: Maybe I need to study :uberjar options a bit first |
| 02:06 | justin_smith | OK, you can ignore the warnings and use "java -cp <your jar> -m clojure.main your.ns" |
| 02:06 | justin_smith | wait, let me double check that syntax |
| 02:11 | amalloy | justin_smith: java -cp my.jar clojure.main -m my.ns |
| 02:12 | justin_smith | amalloy: thanks! I was afraid of that. |
| 02:12 | amalloy | or uh, maybe it's not -m to clojure.main? |
| 02:13 | amalloy | &(doc clojure.main/main) |
| 02:13 | lazybot | java.lang.SecurityException: You tripped the alarm! clojure.main is bad! |
| 02:13 | justin_smith | I run clean pretty often, so I will verify as soon as I have an uberjar to test it on |
| 02:13 | amalloy | well, anyway, it says use -m |
| 02:15 | justin_smith | I am totally gonna make a pr to leiningen where it immediately says "use LEIN_SNAPSHOTS_IN_RELEASE to override" instead of getting to the very end of the jar building process, and then bailing |
| 02:15 | clojer | justin_smith: It sounds like a bit of high magic is required to get this uberjar working :( |
| 02:15 | justin_smith | hmm - it's typically been reliable for me - though I usually have a script running things, so I only set it up once for each project |
| 02:15 | justin_smith | not magic at all, I promise |
| 02:16 | justin_smith | clojer: the whole "not needing to aot compile -main" is new for me, and I have not utilized it in production yet |
| 02:17 | justin_smith | but it is a good thing that I do intend to take advantage of |
| 02:17 | clojer | justin_smith: I'll look into it later. Have to dash now. thanks for all the help. |
| 02:19 | justin_smith | $mail clojer if you are using the built in ring server and don't have a standalone server configured in -main, you may want to use "lein ring uberwar" to create the standalone |
| 02:19 | lazybot | Message saved. |
| 02:35 | dysfun | justin_smith: is that preferred over generating an uberjar and providing a server in main? |
| 02:36 | justin_smith | dysfun: not really |
| 02:36 | justin_smith | dysfun: but easier to try out |
| 02:36 | dysfun | that's what i thought |
| 02:36 | justin_smith | (if you are using lein ring) |
| 02:38 | justin_smith | I just noticed that "teach yourself progoramming in ten years" mentions clojure http://norvig.com/21-days.htm |
| 02:47 | rritoch | Is there a good way to change the "source" folder in clojure at runtime? For example, if I have a clojure servlet running on a tomcat server, via whatever means, but I want to pull the sources from a different folder, similar to how yii is deployed where sources are in a non-web accessible location... Would that be possible and if so how? |
| 02:48 | justin_smith | rritoch: I think that would be a question of adjusting the classpath |
| 02:48 | justin_smith | rritoch: I am not sure of the details here though |
| 02:52 | rritoch | justin_smith: So I should be able to use clojure.core/add-classpath for this? |
| 02:53 | rritoch | justin_smith: My concern is that function is deprecated |
| 02:53 | justin_smith | I'm not sure, but that sounds right. When you use require, it looks for files on the classpath. |
| 02:54 | rritoch | Any idea why they deprecated add-classpath? |
| 02:54 | justin_smith | relevant thread on the group https://groups.google.com/forum/#!topic/clojure/eAf3PT5vjsI |
| 03:01 | rritoch | justin_smith: Ok, I think I understand the problem at least. Currentlyl I'm deploying apps with lein grid push, which just compiles and copies code to the web root, but I want to be able to edit code in real time, maybe I can achieve this by just pushing the maven dependencies to the classpath, and a configuration file to direct the servlet to add the source folder to the classpath |
| 03:01 | rritoch | err, push maven dependencies to the lib path ... |
| 03:02 | rritoch | Either way, it looks like I need to make my own add-classpath function since this one is going away, which is really too bad because there are a lot of uses for it. |
| 03:02 | justin_smith | rritoch: you could check out what pomegranate does |
| 03:03 | justin_smith | it adds maven deps to the classpath at runtime |
| 03:03 | justin_smith | or maybe you can just use pomegranate |
| 03:04 | rritoch | Cool, that should work |
| 03:04 | rritoch | The less I need to maintain the better :) |
| 03:08 | rritoch | I also need to figure out what I need to do to ring to get it to work, I'm using hostmonster for my site right now which doesn't provide tomcat, but I'm thinking I can make a ruby app to deploy ring, assuming I can stop ring from blocking tomcat dependencies. |
| 03:08 | rritoch | err, hostgator |
| 03:08 | justin_smith | rritoch: any reason you can't use an in-app web server like http-kit? |
| 03:10 | rritoch | Not particularly, I simply wasn't aware of it, Ring is the only stand alone clojure web server that I'm aware of. |
| 03:10 | justin_smith | rritoch: ring is not a server |
| 03:10 | justin_smith | it is an adapter layer |
| 03:10 | justin_smith | http-kit is ring compatible |
| 03:10 | justin_smith | ring can also be adapted for containers like tomcat or jetty |
| 03:11 | justin_smith | in fact, as far as I know ring is the way you are expected to use http-kit |
| 03:12 | justin_smith | http://www.http-kit.org/ |
| 03:13 | rritoch | Hmm, well that sounds about right. Its usage looks very similar to ring, so as long as it doesn't block my tomcat dependencies that should work |
| 03:14 | rritoch | With ring or http-kit though it looks like I'm still not going to be able to stream content, (such as mmpeg) but it is a step in the right direction |
| 03:14 | justin_smith | rritoch: ring is an adaptor that lets you use the same code for an embedded server (like http-kit) or a container (like tomcat) - but you would only be using one of those at a time |
| 03:14 | justin_smith | rritoch: http-kit explicitly supports websockets and streaming / async connections |
| 03:15 | rritoch | oh? |
| 03:15 | rritoch | Ok, that is what I need then, I just need to figure out how it works and get it integrated. Tomcat is fine for development purposes, but isn't going to be good for end-users |
| 03:15 | justin_smith | that link I pasted above, their example code uses a websocket |
| 03:16 | justin_smith | another option that supports streaming (also ring compatible) is aleph https://github.com/ztellman/aleph |
| 03:17 | justin_smith | it is also standalone like http-kit is |
| 03:17 | rritoch | CPanel's tomcat plugin (experimental) is horrible, and virtually useless, so my choices are to tie into ruby with a standalone implementation, like http-kit, or rewrite the CPanel plugin and hope CPanel accepts it. http-kit seems an easier route. |
| 03:19 | rritoch | (inc justin_smith) |
| 03:19 | lazybot | ⇒ 137 |
| 03:19 | rritoch | I've owed you that for awhile, lol |
| 03:19 | rritoch | I just didn't know how to use it until recently |
| 03:21 | rritoch | Anyhow, thanks again. I think http-kit + pomegranate solve my remaining deployment issues |
| 03:26 | rritoch | I'm also toying with the idea of trying to solve the C10K problem with clojure, but that may be pushing the technology far past it's capabilities. |
| 03:26 | rritoch | If I were to solve C10K with it though, that would be very helpful for marketing purposes |
| 03:28 | rritoch | I've already added a lot of optimizations, but I haven't yet run any significant benchmarks on it |
| 03:33 | szymanowski | hi, is there something other than performance that yields to prefer protocols over multimethods? |
| 03:36 | wei | datomic question: how do you use the pull api to get all entities with a specific attribute? |
| 03:38 | justin_smith | szymanowski: a protocol describes a group of methods a type implements, while a multimethod is a single method. You can easily create a single method protocol of course, but it means that a protocol can tend to be more like an interface (in fact it compiles to one) while a multimethod is just a single generic function |
| 03:44 | szymanowski | yes I know, but they target at the same purpose: polymorphism, and can be used for the same thing no? |
| 03:46 | szymanowski | it is just that everybody seems to automatically use protocols over multimethods and would like to know if it is JUST for performance or other aditional benefits |
| 03:46 | szymanowski | just* |
| 03:46 | justin_smith | szymanowski: they are simpler, they more directly use the built in facilities of the vm |
| 03:47 | szymanowski | does multimethods are really much more slow than protocols? |
| 03:47 | justin_smith | szymanowski: also, consider that if I write a library, and want users to be able to provide an implementation of some part of the logic - it often makes more sense to say "implement this protocol" rather than "implement these multimethods" |
| 03:47 | justin_smith | szymanowski: yes |
| 03:47 | szymanowski | yes I see |
| 03:48 | szymanowski | thank you |
| 03:48 | justin_smith | one advantage for multimethods is in the repl, reloading the codebase |
| 03:48 | justin_smith | protocols are much clumsier for redefining without a restart |
| 03:49 | szymanowski | I really love multimethods, so flexible |
| 03:49 | justin_smith | multimethods also support derive based heirarchies, and arbitrary dispatch functions, but in practice I don't see those features used very much |
| 03:49 | szymanowski | yes |
| 03:49 | justin_smith | usually it's either a keyword lookup, or the type of the thing that are dispatched on |
| 03:50 | szymanowski | yes in this situation I prefer protocols |
| 03:50 | justin_smith | also, because protocols only do type based dispatch, you end up needing to use defrecord or deftype or adding a :type metadata to your code |
| 03:50 | justin_smith | ,(type (with-meta {} {:type 'foo})) |
| 03:51 | szymanowski | protocols doesn't dispatch on type but on class no? |
| 03:51 | clojurebot | foo |
| 03:51 | szymanowski | yes I'm often doing this trick |
| 03:51 | justin_smith | szymanowski: good point, I think it is actually class they dispatch on, yeah |
| 03:51 | szymanowski | that a bit sad I think |
| 03:51 | justin_smith | it's the sacrifice needed so that the performance is at least available |
| 03:52 | szymanowski | but this is maybe that that allow speed |
| 03:52 | justin_smith | szymanowski: yeah, a protocol directly creates a jvm interface, and interfaces only support class dispatch |
| 03:52 | szymanowski | I find that using protocol yields to write more complex code |
| 03:52 | justin_smith | yeah, it can |
| 03:52 | justin_smith | I use them sparingly |
| 03:53 | szymanowski | I like the old school way of doing all with native types plus type metadata |
| 03:54 | szymanowski | thank you, i'm going back to work, have a nice day |
| 03:54 | justin_smith | if possible I avoid type dispatch altogether, and simply write code that uses native types |
| 03:54 | justin_smith | you too |
| 03:55 | justin_smith | (I guess I am implicitly using the built in type / protocol dispatch when I use the core functions of course) |
| 04:43 | schrotti | hm the nrepl used by lein is a 2-3 times slower than the one that comes with clojure.jar |
| 04:43 | schrotti | how come? |
| 04:53 | morfeen | Anybody here have used Clojurescript to build something on the server side? |
| 04:53 | morfeen | with Node, that is |
| 04:58 | dysfun | why would you do that voluntarily when you have clojure available? |
| 05:00 | morfeen | dysfun: npm? |
| 05:00 | morfeen | npm libraries |
| 05:00 | dysfun | clojars? |
| 05:00 | dysfun | there's almost nothing i want for in clojure |
| 05:01 | dysfun | and the only thing i want for involves poking around JNI, so i'm just using something else |
| 05:02 | TEttinger | morfeen, I think people do that, sometimes, but it isn't common |
| 05:02 | morfeen | dysfun: cool, do you use Clojure in production? |
| 05:03 | dysfun | product is in development, but we will be doing soon |
| 05:04 | dysfun | using clojure makes me feel a lot more confident that the concurrency stuff won't become a problem |
| 05:04 | morfeen | Clojars seem cool |
| 05:04 | dysfun | there are a lot of useful libraries |
| 05:05 | dysfun | if you're struggling to find a particular library, http://clojure-toolbox.com/ is a good resource |
| 05:05 | dysfun | or asking in here. but bear in mind there's a choice and people have different tastes |
| 05:06 | dysfun | but we've largely built around what luminus provides. except we've cut a few things out and swapped in some other things |
| 05:06 | dysfun | it'll be open source when we've tidied it all up, so you'll be able to see |
| 05:07 | rritoch | Is there any way to check if a resource (URL) is a file or a directory? |
| 05:07 | morfeen | dysfun: I thought the Clojure community was against the idea of using monolith frameworks |
| 05:07 | morfeen | Luminus seems to be one, if I am not mistaken |
| 05:07 | dysfun | morfeen: it isn't a monolith framework. it's some glue code around a reasonably well chosen selection of libraries |
| 05:07 | dysfun | in fact, i'm not sure it even exists outside of a leiningen template |
| 05:08 | morfeen | right, so is Luminus the way to go with web dev? Like express for node? |
| 05:08 | dysfun | again, people have their preferences. i like it |
| 05:08 | dysfun | we are, like any other programming language, not short for web frameworks |
| 05:09 | morfeen | Cool. |
| 05:09 | dysfun | notably we don't use korma per their recommendations because we're using redis to handle our data |
| 05:09 | clgv | morfeen: not necessarily. you can just have a look which libraries luminus uses and the you can setup your own project with only a subset of them without using luminus |
| 05:10 | dysfun | i'd recommend generating an app with the leiningen template and stripping out anything you don't want. i've done that a few times recently |
| 05:10 | rritoch | I didn't realize that getResource requests on OSGi bundles for directories would return a non-null response, so it is screwing up the following code https://github.com/rritoch/clj-grid-core/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/servlet/standard_servlet.clj#L91-L95 |
| 05:10 | schmir | plain old clojure.jdbc instead of korma is also an option |
| 05:11 | dysfun | schmir: if you hate yourself |
| 05:11 | morfeen | clgv: cool |
| 05:11 | schmir | dysfun: why? |
| 05:12 | morfeen | dysfun: What are you guys building? If you don't mind me asking |
| 05:12 | dysfun | schmir: because it's painful in the extreme. if i had to use it every day i'd quit my job |
| 05:12 | dysfun | morfeen: an open-source e-commerce platform ("online shop platform") |
| 05:13 | clgv | morfeen: optimization algorithms for logistics (but I am the odd one around here ;) ) |
| 05:13 | morfeen | interesting stuff! |
| 05:13 | TEttinger | games. |
| 05:14 | morfeen | TEttinger: that's cool! Clojure or Clojurescirpt? |
| 05:14 | dysfun | i wanted to do some games using actual clojure and web canvas, but JavaFX is crap :/ |
| 05:14 | dysfun | the only way to make it work would be to mix clojurescript and clojure and that started to seem a bit daft |
| 05:15 | SagiCZ1 | morfeen: i am using clojure to build stock trading platform and automatic trading robots |
| 05:15 | TEttinger | morfeen, I have one bad little demo in clojure, but I've been working on making the art assets to do something better. |
| 05:15 | dysfun | SagiCZ1: interesting. some people came to me with a similar problem the other day and i said "i'd use clojure". not alone :) |
| 05:16 | sveri | Hi there, timbre or something else for logging? Voting is opened now |
| 05:16 | dysfun | timbre is very lovely |
| 05:16 | TEttinger | the final game project may be in clojure or clojurescript, I'm just not an expert with web stuff |
| 05:16 | SagiCZ1 | dysfun: the only thing i am concerned about, is that the platform has to be incredibly stable since outages could cost real $$.. i am not sure if clojure is mature enough to run for days without crash.. then again the bugs would be probably introduced by me anyways |
| 05:17 | dysfun | SagiCZ1: there are ways around that involving load balancers |
| 05:17 | schmir | +1 for timbre |
| 05:18 | SagiCZ1 | TEttinger: are you using a 3d engine? i would love it if someone could wrap jMonkeyEngine in clojure.. it is very powerful but the API is a mess |
| 05:18 | schmir | dysfun: I don't think korma takes much pain away from sql... |
| 05:19 | TEttinger | SagiCZ1: erlang and its VM are possibly more reliable than the JVM, but clojure is certainly pretty reliable. My lightly-used IRC bot has had long periods of uptime, only broken when my household internet fails |
| 05:19 | schmir | but then I also haven't used it... |
| 05:19 | dysfun | schmir: i think it eliminates one category of pain entirely, but does nothing for the fact you still have to think in SQL |
| 05:19 | SagiCZ1 | TEttinger: thanks for sharing the experience, that's reassuring.. |
| 05:21 | dysfun | and there's an awful lot of clojure being used in banks. i think we'd have heard something if there was a major problem with stability |
| 05:21 | TEttinger | it's running on windows server 2008 R2 (on a laptop; I needed to fresh install and I had a copy of the OS from school for free). that OS has also been surprisingly reliable |
| 05:21 | SagiCZ1 | dysfun: in banks? never heard of that |
| 05:21 | SagiCZ1 | TEttinger: i was thinking whether i really need to run this on linux since i am a windows guy.. maybe windows server would be an option |
| 05:22 | TEttinger | linux is cheaper if you aren't a student :) |
| 05:22 | TEttinger | BSD is also legendary for its reliability |
| 05:22 | SagiCZ1 | TEttinger: i actually do have dreamspark licence so its free anyways |
| 05:22 | TEttinger | heh, good then! |
| 05:24 | clgv | SagiCZ1: Clojure has been major enough to run for days for a while |
| 05:24 | clgv | SagiCZ1: I have run experiments spanning at least 3-7 days using all cores on the machines running on 6 machines |
| 05:25 | SagiCZ1 | clgv: yeah.. i guess the risk of my own bugs would be magnitudes higher than some inherited instability |
| 05:25 | clgv | SagiCZ1: yes, that is the challenge ;) |
| 05:26 | SagiCZ1 | cglv: i actually chose clojure also because it is so easy to test pure functions, compared to traditional junit tests in mutable java which gave me many headaches in my day job |
| 05:26 | clgv | SagiCZ1: I had a number of try-catches which ensured that single failing runs do not take down the whole system |
| 05:26 | dysfun | SagiCZ1: well we know datomic is being used in lots of banks, and it's written in clojure... |
| 05:26 | SagiCZ1 | clgv: yeah i am planning on including some sort of recovery system |
| 05:26 | SagiCZ1 | dysfun: super cool! |
| 05:27 | dysfun | well, 'lots of' may be overstating it, but certainly a handful |
| 05:27 | SagiCZ1 | dysfun: one would be enough to convince me, banks are serious business |
| 05:29 | dysfun | SagiCZ1: you might not say that if you'd worked in one. but those stories aren't for this channel :) |
| 05:29 | SagiCZ1 | dysfun: hah i see your poitn |
| 05:29 | SagiCZ1 | *point |
| 05:30 | dysfun | i am constantly amazed the banking system works at all |
| 05:30 | SagiCZ1 | dysfun: you could be amazed equally about any compex burreocracy system.. (i cant spell) |
| 05:31 | dysfun | SagiCZ1: quite. i've had my fill of beaurocracies for a while |
| 05:31 | clgv | "office jackstraw games"? the first one to move in office losses? ;) |
| 05:32 | dysfun | if you find yourself in the office at 1 in the morning, ever, you should seriously take a look at your life and how it got this way |
| 05:34 | clgv | oh yeah that's bad. |
| 05:34 | clgv | my personal record is around 11pm - shortly before submission deadline ended |
| 05:34 | Glenjamin | i know a few places that still do really-late-night rollouts |
| 05:35 | dysfun | hah, i pulled an all nighter once |
| 05:35 | morfeen | Could you recommend a Clojure book for me? I am a node developer, so I am used to some of the ideas of functional programming, like higher order functions. I am currently reading Clojure in action. |
| 05:35 | dysfun | Glenjamin: if your system isn't set up to facilitate remotely flicking a switch to roll backwards and forwards, make it so |
| 05:35 | schmir | morfeen: joy of clojure. |
| 05:35 | schmir | morfeen: but finish clojure in action first |
| 05:35 | dysfun | morfeen: The joy of clojure is quite good if you like the functional bits. and it does a good job of explaining why if you understand some already |
| 05:36 | morfeen | schmir: is Joy of Clojure a reference book? |
| 05:36 | dysfun | no, it's a guided tour through the language |
| 05:36 | Glenjamin | mm, very much so |
| 05:36 | dysfun | there's enough material to make it a useful reference, i suppose |
| 05:37 | schmir | morfeen: no, but it's probably not the best book if you know nothing about clojure |
| 05:37 | morfeen | so, Joy of Clojure is mostly about the philosophy? |
| 05:37 | dysfun | schmir: on the other hand i find clojure in action to be a terrible book |
| 05:37 | morfeen | dysfun: why is that? |
| 05:38 | dysfun | mostly because we have much better libraries these days and it's getting old |
| 05:38 | schmir | dysfun: I read it a few years ago...and I think it was ok. |
| 05:38 | dysfun | but because the libraries were crap back then, it's a very hard progression |
| 05:39 | schmir | speaking about libraries...the clojure cookbook is nice |
| 05:39 | dysfun | and by introducing things like redis pretty early on, the author overloads you with information too quickly |
| 05:39 | dysfun | it's more like "how to solve the specific problem i solved with clojure, and a bad tutorial to step you into it" |
| 05:40 | dysfun | if you have the same problem, and you come at it with with existing knowledge of the other tools he uses, i can see it might be useful |
| 05:41 | Glenjamin | i found the most helpful thing when learning clojure was to have a problem to solve |
| 05:41 | dysfun | or a project :) |
| 05:41 | Glenjamin | tutorials/4clojure/koans to get started, then dive into a problem/project and keep looking things up |
| 05:59 | SagiCZ1 | morfeen: i would strongly suggest to avoid Joy of Clojure.. i personally regret the time spending reading through this book, which is very long for what it has to offer.. i followed it with Clojure Programming and felt that it was much better read with more value to it.. try it.. also braveclojure is not that bad, koans and 4clojure is also enjoyable |
| 06:14 | m1dnight_ | If i have (assoc {} \x 10), how do I get the value for \x? |
| 06:14 | m1dnight_ | I figured (\x <map) but that doesn't work |
| 06:14 | Bronsa | (get {\x 10} \x) |
| 06:14 | Bronsa | ,(get {\x 10} \x) |
| 06:14 | clojurebot | 10 |
| 06:14 | m1dnight_ | oh |
| 06:14 | Bronsa | ,({\x 10} \x) |
| 06:14 | clojurebot | 10 |
| 06:15 | m1dnight_ | oooh |
| 06:15 | m1dnight_ | but.. |
| 06:15 | m1dnight_ | ,(:key {:key value}) |
| 06:15 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: value in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 06:15 | m1dnight_ | okay i must have been mistaken |
| 06:15 | m1dnight_ | thnx |
| 06:15 | SagiCZ1 | ,(:key {:key 'value}) |
| 06:15 | clojurebot | value |
| 06:15 | Bronsa | ,(:foo {:foo 1}) |
| 06:15 | clojurebot | 1 |
| 06:15 | Bronsa | m1dnight_: in clojure, keywords are functions |
| 06:15 | Bronsa | m1dnight_: maps vectors and sets are also functions |
| 06:15 | Bronsa | m1dnight_: char literals are not |
| 06:16 | SagiCZ1 | and although maps are also functions, its recommended to use keywords as function, if you want to switch to records later |
| 06:20 | dysfun | why? don't records also act as functions like maps? |
| 06:20 | Bronsa | no |
| 06:20 | SagiCZ1 | dysfun: they don't |
| 06:20 | dysfun | hrm |
| 06:20 | dysfun | that seems an omission |
| 06:20 | Bronsa | you might want to implement a different IFn behaviour |
| 06:20 | dysfun | oh i see what you mean |
| 06:21 | dysfun | it seems like a sensible default though |
| 06:25 | morfeen | SagiCZ1: thanks, will checkout Clojure Programming. |
| 06:26 | SagiCZ1 | morfeen: the authors are Emerick, Carper, Grand |
| 06:27 | morfeen | SagiCZI: I'm currently reading Clojure in Action, have you read that book? |
| 06:27 | SagiCZ1 | nope, is it good? |
| 06:28 | morfeen | It's alright, but some people in this channel do not recommend it |
| 06:28 | dysfun | i think it was just me, actually |
| 06:28 | SagiCZ1 | i see.. |
| 06:28 | SagiCZ1 | opinions may differ i guess |
| 06:28 | morfeen | dysfun: some people, was you :D |
| 06:28 | clgv | morfeen: "Programming Clojure" (now in 2nd edition) was really good to get going rapidly |
| 06:28 | morfeen | clgv: great! |
| 06:29 | clgv | morfeen: pay attention to the order of the two words.. |
| 06:29 | clgv | two pretty different books |
| 06:29 | morfeen | clgv: order of what 2 words? |
| 06:29 | SagiCZ1 | there is also a very interesting chapter explaining how to develop really abstract code in a way i wouldnt imagine before |
| 06:29 | morfeen | Ah alright |
| 06:30 | dysfun | clgv: my flatmate is learning clojure. he programs mostly scala. would you recommend it to him as an intro? |
| 06:30 | SagiCZ1 | oh its a different book |
| 06:30 | SagiCZ1 | nevermind |
| 06:31 | clgv | dysfun: I'd make the choice between "Programming Clojure" and "Clojure Programming" depending on which writing style you like better |
| 06:31 | clgv | dysfun: I think that both have sample chapters |
| 06:31 | Glenjamin | as in your preferred noun-verb order? |
| 06:31 | SagiCZ1 | Glenjamin: :D |
| 06:31 | dysfun | (inc Glenjamin) |
| 06:31 | lazybot | ⇒ 9 |
| 06:32 | morfeen | SagiCZ1, clgv: You are both talking about different books right? |
| 06:32 | SagiCZ1 | morfeen: yes |
| 06:32 | morfeen | So of the 2, which one should I read, if I want to get up to speed real quick? |
| 06:32 | clgv | morfeen: see my comment above ,) |
| 06:33 | SagiCZ1 | morfeen: i cant compare, sorry |
| 06:33 | morfeen | I mean, I do have some exposure of FP with Javascript. |
| 06:34 | clgv | morfeen: from my point of view "Programming Clojure" since it has pretty technical writing opposed to the more narrative style of "Clojure Programming" |
| 06:34 | SagiCZ1 | i started from scratch and Clojure Programming was easy to grasp so it might be to slow for you |
| 06:34 | SagiCZ1 | *too slow |
| 06:34 | clgv | morfeen: but have a look at their sample chapters |
| 06:34 | morfeen | Cool. |
| 06:35 | clgv | replace "has pretty technical writing" by "is written in a more technical style" |
| 06:35 | clgv | ;) |
| 06:38 | kyrre | morfeen, i'd get programming clojure and then after a while follow it up with "the joy of clojure" |
| 07:00 | morfeen | kyrre: Cool. Programming Clojure it is then. |
| 07:01 | clgv | morfeen: make sure you get the 2nd edition |
| 07:05 | boyscared | it's clojure conj day!!@#! |
| 07:05 | boyscared | there aint no party like a clojure conj party |
| 07:05 | boyscared | cuz a clojure conj party infinitely recurses |
| 07:06 | clgv | ah really? |
| 07:10 | clgv | "tex in clojure" sounds interesting |
| 07:19 | luxbock | how long did it take the last time for the talks to be uploaded online? |
| 07:23 | clgv | 1-2 months it seems |
| 07:23 | clgv | judging from youtube info "posted on" and the conference date |
| 07:42 | jmnoz | beginner question: where can I find information about how to modify/troubleshoot project dependencies? |
| 07:43 | mavbozo | assuming you use leiningen: lein deps :tree |
| 07:44 | jmnoz | but if I want to modify the code in one of my dependencies? |
| 07:47 | mavbozo | jmnoz: I misunderstood you, what kind of problem that makes you think that you have to change the code in you dependencies? |
| 07:47 | mavbozo | *your dependencies*? |
| 07:48 | jmnoz | I am trying the lein-plugin figwheel on a windows machine and there seems to be some error with path names in that code. |
| 07:49 | jmnoz | I would like to troubleshoot figwheel, should I clone the git repository and somehow point leiningen at my local files? |
| 07:52 | mavbozo | jmnoz: yeah, I met that kind of path problem too. I did clone the lib repo and install it locally and modify it to find the problem. |
| 07:52 | jmnoz | ha! :) |
| 07:54 | rritoch | jmnoz: Yes, clone the repository locally and make your changes, you can then use "lein install" to install them to your localrepo, you may also want to change the version number to an unreleased version so there's little risk of changes made by the maintainer overwriting your local deployment. |
| 07:54 | jmnoz | excellent, thanks |
| 07:55 | mavbozo | jmnoz: there's a instruction to install lein plugin here https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 07:55 | mavbozo | jmnoz: basically you just run lein install in your plugin project |
| 07:55 | jmnoz | alright great, thanks folks. |
| 07:56 | mavbozo | jmnoz: and creating .lein-classpath in your own project directory that contains path to the src directory of the above plugin |
| 07:56 | dysfun | justin_smith: i'm wanting to integrate some full packet logging into groundhog, wondering if you had any thoughts |
| 07:57 | dysfun | well, some content and timings anyway |
| 07:59 | clgv | woah, building "pixie" requires quite some time. |
| 07:59 | dysfun | llvm :) |
| 07:59 | clgv | no pypy |
| 08:00 | dysfun | oh right. i was confusing it with the other one |
| 08:00 | dysfun | but pypy is llvm, no? |
| 08:01 | clgv | not that I know |
| 08:02 | dysfun | ah, it's RPython |
| 08:02 | dysfun | which transpiles to c |
| 08:19 | tbaldridge | Yeah, the RPython translation process is one of the most advanced partial evaluators I've ever seen. That's why it takes so much time. |
| 08:20 | tbaldridge | I've tried compiling a RPython program before that contained a lisp program as a string, it did so much partial evaluation, it didn't even build the compiler, it just read/compiled/ran the lisp program and emitted the output as a constant. |
| 08:21 | Bronsa | sounds impressive |
| 08:22 | clrnd | tbaldridge, wait, what? |
| 08:24 | tbaldridge | clrnd: if the input to your reader/interpreter is a constant inside the interpreter, then that string's compiled output is a constant. |
| 08:24 | tbaldridge | clrnd: so running something like this in RPython (defn -main [] (eval (read-string "42"))) gets compiled as int main () {return 42;} |
| 08:25 | clrnd | I'm not sure what RPython is, but why does it know Lisp? |
| 08:33 | jmglov | I'm seeing the classic "Exception in thread "main" java.lang.NoClassDefFoundError: clojure/tools/logging/impl/LoggerFactory" error when aot compiling a project that depends on clojure.tools.logging. |
| 08:33 | jmglov | I figured I'd stop by and see if anyone has some insights to get me unstuck. |
| 08:34 | jmglov | I did some research, and found others having the issue, but I couldn't find any solutions out there. |
| 08:35 | jmglov | This guy is using clojure.tools.logging and logback together, which is exactly my configuration: https://groups.google.com/forum/#!msg/datomic/6xWGFB-Dx68/_Hr2I4lv39gJ |
| 08:46 | mnngfltg | jmglov, does it work in a simple project (after `lein new`)? Maybe there's some interference with another package you're including. |
| 08:47 | jmglov | mnngfltg: It looks like this bug: http://dev.clojure.org/jira/browse/CLJ-1544 |
| 08:47 | jmglov | There's a minimal repro in this repo: https://github.com/arohner/clj-aot-repro |
| 08:47 | sdegutis | Most of the return values from my API (see https://github.com/sdegutis/clover) are in vectors because they act like tuples, but some of them are single values (like :404), so should those be in vectors for consistency, or just bare for simplicity and/or efficiency? |
| 08:47 | mnngfltg | jmglov, can you disable AOT? |
| 08:48 | jmglov | mnngfltg: Nope, because this library is being used by a Ring app that is deployed with "ring uberwar", which does some AOT compilation. |
| 08:48 | jmglov | I definitely stay away from AOT if I can. :) |
| 08:49 | tbaldridge | sdegutis: I'd convert everything into maps. Vectors/tuples imply meaning in the ordering. This makes programatic use of your api harder as you have to somehow express to the program(er) what each slot means. |
| 08:49 | mnngfltg | jmglov, too bad. Sorry I don't know nothing about the issue |
| 08:49 | tbaldridge | sdegutis: better explicit than implicit. |
| 08:50 | jmglov | mnngfltg: No worries. Do you know anything about how AOT works? |
| 08:50 | mnngfltg | know :( |
| 08:51 | mnngfltg | no :( |
| 08:51 | sdegutis | tbaldridge: One of the goals of my API is simplicity, so we return [:redirect "/"] because it's shorter and easier to type and remember than {:operation :redirect, :location "/"} or something similar. |
| 08:51 | jmglov | I'm seeing if I can hack around this by AOT compiling c.t.l, then rsyncing its target/ into my project's target. |
| 08:51 | tbaldridge | sdegutis: but it's not simple, what does slot 1 and slot 2 mean? |
| 08:51 | tbaldridge | sdegutis: if you pass me a map I know it instantly, I don't have to ask you |
| 08:51 | sdegutis | tbaldridge: The ideal is that valid return value patterns would be easy enough for the programmer to remember, and in the cases where memory fails, there'll be a lookup table in the docs. |
| 08:52 | tbaldridge | sdegutis: the ideal is data that is self-expressing. |
| 08:52 | sdegutis | tbaldridge: That's true, until you forget what the keys are (I've forgotten Ring's keywords many times). |
| 08:52 | tbaldridge | sdegutis: if I forget a english keyword name, how on earth am I going to remember what slot 1 is vs slot 2? |
| 08:53 | tbaldridge | words are quite a bit easier to understand vs raw numbers |
| 08:53 | sdegutis | tbaldridge: They should be obvious by reflecting the order of a function call, like [:redirect "/"] or [:404]. |
| 08:53 | sdegutis | So I'm wondering, should I indicate 404 by returning [:404] or just :404 ? |
| 08:53 | sdegutis | Everything else in my API uses [...] so far, so I'm leaning towards [:404] for consistency. |
| 08:54 | tbaldridge | sdegutis: well you often want a message with the error, bare error codes rarely are sufficient |
| 08:54 | tbaldridge | especially for 400 errors |
| 08:54 | sdegutis | Wait, 404 error codes come with a message? |
| 08:55 | sdegutis | tbaldridge: Do you mean the HTML of the page that a 404 error can return? |
| 08:55 | sveri | Hi, what is the fastest way to integrate a simple storage engine with restart persistence for some key / values only, at best case it can be redistributed with the application and requires no extra setup on running the application |
| 08:55 | tbaldridge | 400 = bad data, so when you send that error, it's often nice to say "400 - you didn't give a valid email address" |
| 08:56 | sdegutis | Ah! Well then, that's a fine reason to use [:404] :) |
| 08:56 | sdegutis | Thanks tbaldridge :) |
| 08:56 | tbaldridge | sdegutis: have fun with vectors once you start including extra headers, encoding options, etc, then the vector approach is going to fall apart. |
| 08:57 | sdegutis | tbaldridge: Good point. I'll probably also allow maps as a fallback for more complex return values, but the goal is to avoid having more complex return values in the first place, or at least that they be very rare. |
| 08:58 | sdegutis | tbaldridge: 99% of my web app's return values are simple and can be expressed either like [:404] or [:redirect "/cart"] or [:render {:user-name username}] or similar. |
| 09:00 | jmglov | Ugh, that worked. |
| 09:01 | Bronsa | sdegutis: kind of funny that the other day you were complaining about clojure libs being written by the authors ad-hoc to solve their problems and now you're desigining a lib based on your web app's needs |
| 09:02 | sdegutis | Bronsa: I wasn't complaining, I was stating the facts :) |
| 09:02 | jmglov | I cloned git@github.com:clojure/tools.logging.git, added ":aot :all" to the project.clj, did a "lein compile", then copied tools.logging/target to my project dir. Then a "lein compile" of my project worked. |
| 09:02 | tbaldridge | sdegutis: that's kindof my point though, you can express that as {:status :redirect :url "/cart"} and then you won't have to make your framework accept vectors or maps. Having conditional logic like that is kindof a code-smell |
| 09:02 | Bronsa | your opinions, not facts |
| 09:02 | sdegutis | Bronsa: Okay :) |
| 09:02 | tbaldridge | and when you're starting your framework design with code-smells, that's also a code-smell. |
| 09:02 | jmglov | I'll drop that into the bug report, just to help out poor souls like me. |
| 09:02 | tbaldridge | that's what I'm reacting against here. |
| 09:02 | jmglov | But I don't like it, no sir! |
| 09:03 | sdegutis | tbaldridge: I would have (strongly) agreed with you a year or two ago on that. |
| 09:04 | sdegutis | tbaldridge: But I am beginning to disagree with the principles that I held strongly as I came into the Clojure community (which also holds them strongly). |
| 09:04 | Bronsa | jmglov: don't open a ticket on tools.logging's jira, your bug doesn't seem like a bug there at all |
| 09:05 | sdegutis | tbaldridge: Now it seems very reasonable to me to provide shortcuts where they make good sense. However, I do think that determining if it makes good sense requires a bit of time working *without* said shortcuts to get to know the problem domain very intimately first. |
| 09:06 | jmglov | Bronsa: Sorry, I was talking about the Clojure bug I linked previously: http://dev.clojure.org/jira/browse/CLJ-1544 |
| 09:06 | Bronsa | jmglov: ah ok, sorry |
| 09:06 | jmglov | You are certainly right that the bug has nothing to do with tools.logging. |
| 09:06 | jmglov | It's just a crazy compile-order issue with AOT in the Clojure compiler, best I can tell. |
| 09:07 | jmglov | But hey! I learned something new in the last 3 hours of troubleshooting this. :) |
| 09:08 | Bronsa | unfortunately there are quite a bunch of bugs related to aot compilation |
| 09:09 | Bronsa | most of them are related to what I believe is a wrong classloader setup by the compiler but I never investigated this |
| 09:09 | jmglov | Interesting. |
| 09:10 | jmglov | I'm certainly going to read the commit that fixes the bug. |
| 09:10 | sdegutis | Speaking of which, every time I add :main to "project.clj", I get some weird error when doing `lein ubarjar` talking about AOT or whatever. When will that go away? I'm using the latest lein (2.5.0). |
| 09:10 | jmglov | sdegutis: You actually need to add an :aot directive for that namespace. |
| 09:10 | jmglov | Lemme find an example... |
| 09:10 | Bronsa | jmglov: best of luck waiting for that commit |
| 09:11 | sdegutis | Oh. |
| 09:11 | sdegutis | Is using :main & :aot the recommended way to give a `lein uberjar` file a 'main' function to run? |
| 09:12 | jmglov | Ah yes: (defproject "foo" "0.1", :main foo.core, :aot [foo.core]} |
| 09:12 | jmglov | sdegutis: Yes, AFAIK. |
| 09:13 | jmglov | At least, that's what my Googling seemed to indicate a few months back when I was trying to figure out how to get rid of that warning. :) |
| 09:13 | sdegutis | :) |
| 09:19 | clgv | tbaldridge: so it did finish meanwhile. note to myself recompile during meetings ;) |
| 09:20 | clgv | tbaldridge: does pixie have exploratory functions to find out what functions/macros are defined= |
| 09:26 | sdegutis | Anyone interested in working with me to port http://slim-lang.com/ to Clojure? |
| 09:26 | sdegutis | I found a good name for it: https://github.com/sdegutis/slim-cljm |
| 09:32 | mearnsh | half the work done then |
| 09:40 | egli | sdegutis: I don't see what slim could give you over hiccup |
| 09:41 | sdegutis | egli: inline Markdown |
| 09:41 | egli | hiccup has actual data structs |
| 09:41 | egli | slim has indenting and weird conventions |
| 09:42 | egli | can't you have inline md in hiccup? |
| 09:42 | egli | in the sense of [:h1 (markdown "**foo**)] |
| 09:42 | sdegutis | egli: Sure, if you want to put the entire thing inside a giant string. Not very pretty when it's multi-line. |
| 09:43 | sdegutis | egli: Our website's "/legal" page is mostly Markdown, and it's incredibly awkward to have expressed it in Hiccup. |
| 09:43 | egli | aren't there md->html->hiccup converters? |
| 09:44 | sdegutis | Uhh... |
| 09:44 | sdegutis | What would that look like? |
| 09:45 | Frozenlock | this? https://github.com/chameco/Hitman |
| 09:45 | egli | sdegutis: feed in md out comes html pipe it through another converter and you get hiccup |
| 09:45 | Frozenlock | Or even this https://github.com/theJohnnyBrown/endophile |
| 09:46 | sdegutis | Instaparse is awesome. |
| 09:47 | Frozenlock | I should start a project to play with it. |
| 09:47 | Frozenlock | I heard all kind of praises for instaparse. |
| 09:49 | sdegutis | Anyway that still doesn't address the problem I want to solve, which is to write inline Markdown. |
| 09:49 | luxbock | there's now Instaparse for ClojureScript as well |
| 09:49 | Frozenlock | o_O |
| 09:49 | luxbock | https://github.com/lbradstreet/instaparse-cljs |
| 09:51 | Frozenlock | sdegutis: you want to write markdown into a clj file? (as opposed to slurp it) |
| 09:51 | sdegutis | No, I want to write it into my Slim file. |
| 09:51 | sdegutis | It gets tedious after a while to write all sorts of double-quotes everywhere just because you want to write raw (or interpreted) content. |
| 09:52 | sdegutis | That's why http://slim-lang.com/ is so appealing to me. |
| 09:54 | TEttinger | huh, I hadn't seen https://codeclimate.com/ before |
| 10:05 | sveri | what happened to lighttable, no more menus in 0.7.1? |
| 10:11 | tbaldridge | that's one reason I moved away from LT, each version seemed to remove more of the GUI. |
| 10:11 | sdegutis | It's the evolution of Emacs, so its destiny is to have no GUI. |
| 10:11 | Frozenlock | sdegutis: really? Emacs seems to be its ultimate form. :-p |
| 10:12 | teslanick | LightTable: This Isn't Even My Final Form |
| 10:12 | Frozenlock | teslanick: that's what emacs tell me each time I open my .emacs file. |
| 10:12 | Frozenlock | *tells |
| 10:13 | daniel_ | nick |
| 10:13 | mavbozo | tbaldridge: what do you use as LT replacement? |
| 10:14 | tbaldridge | I've tried LT a few times, used to use emacs, now I use Cursive 100% of the time |
| 10:14 | sdegutis | Is there a lazier way to specify (-> 3 foo bar quux)? |
| 10:15 | sdegutis | Er sorry, #(-> % foo bar quux), in other words, a function. |
| 10:15 | Bronsa | what do you mean by lazier |
| 10:15 | sdegutis | (= (-> 3 inc inc) ((comp inc inc) 3)) |
| 10:15 | sdegutis | ,(= (-> 3 inc inc) ((comp inc inc) 3)) |
| 10:15 | clojurebot | true |
| 10:15 | sdegutis | Ah, comp is like -> then? |
| 10:15 | Bronsa | no |
| 10:16 | Bronsa | ,((comp inc -) 2) |
| 10:16 | clojurebot | -1 |
| 10:16 | Bronsa | ,(-> 2 inc -) |
| 10:16 | clojurebot | -3 |
| 10:16 | sdegutis | ,(= (-> 3 inc -) ((comp - inc) 3)) |
| 10:16 | clojurebot | true |
| 10:16 | sdegutis | Ah, they're backwards. |
| 10:16 | sdegutis | Good! |
| 10:17 | Bronsa | reverse order, also comp is a function that returns a function, -> is a macro that does lexical transformation |
| 10:18 | Bronsa | so (comp foo bar) ~= #(-> % bar foo) |
| 10:18 | Bronsa | it's actually #(->> %& (apply bar) foo) |
| 10:19 | sdegutis | Oh, also -> calls the function immediately with args, comp does't. |
| 10:19 | sdegutis | So (-> 3 (foo)) turns into ((comp #(foo %)) 3) |
| 10:19 | sdegutis | Yikes. |
| 10:19 | Bronsa | ,(macroexpand-1 '(-> 3 (foo))) |
| 10:19 | clojurebot | (foo 3) |
| 10:20 | sdegutis | Right. |
| 10:20 | sdegutis | Frozenlock: lol |
| 10:20 | clojurebot | Excuse me? |
| 10:20 | mavbozo` | ,%& |
| 10:20 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %& in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 10:20 | Bronsa | mavbozo`: it's #() syntax |
| 10:20 | Bronsa | ,(#(vec %&) 1 2 3 4) |
| 10:20 | clojurebot | [1 2 3 4] |
| 10:21 | Bronsa | ,(#(vec % %&) 1 2 3 4) |
| 10:21 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/vec> |
| 10:21 | Bronsa | ,(#(vector % %&) 1 2 3 4) |
| 10:21 | clojurebot | [1 (2 3 4)] |
| 10:21 | Bronsa | ,(#(vector %1 %2 %&) 1 2 3 4) |
| 10:21 | clojurebot | [1 2 (3 4)] |
| 10:21 | Bronsa | mavbozo`: %& is & foo for the #() fn literal |
| 10:22 | mavbozo` | (inc Bronsa ) |
| 10:22 | lazybot | ⇒ 2 |
| 10:23 | Bronsa | mavbozo`: no space before the paren ;) |
| 10:23 | sdegutis | I'm trying to turn a bunch of (-> routes (wrap-reload) (wrap-cookies) ...) into a function that can take a routes later. |
| 10:23 | sdegutis | The only solution I came up with was to put # around it and replace routes with % |
| 10:23 | Bronsa | sdegutis: what's wrong with that? |
| 10:23 | sdegutis | It's just not as pretty I guess. |
| 10:24 | sveri | I use cursive myself, but I like the instant of LT and therefor use it for this from time to time |
| 10:24 | mavbozo` | (inc Bronsa) |
| 10:24 | lazybot | ⇒ 73 |
| 10:25 | Bronsa | sdegutis: I dislike #() and % myself, but they are handy. I worked around this by prettifying them via font-lock |
| 10:25 | sdegutis | I meant pretty in a different way. |
| 10:26 | agarman | ƒ(... ) is nice looking |
| 10:26 | luxbock | Bronsa: what do you use for that? pretty-mode? |
| 10:26 | Bronsa | i.e. this is how I see #(-> foo % bar) http://i.imgur.com/mk3nv65.png |
| 10:27 | Bronsa | luxbock: no https://github.com/Bronsa/.emacs.d/blob/master/config/hooks.el#L11-L31 |
| 10:27 | andrewhr | the sad thing about Cursive it’s the buggy experience of IntelliJ’s Ideavim |
| 10:29 | luxbock | Bronsa: thanks, I'll these out |
| 10:32 | otfrom | anyone here at the conj? |
| 10:33 | hyPiRion | yess |
| 10:33 | clgv | hyPiRion: did the talks start, yet? |
| 10:33 | clgv | hyPiRion: where is the live stream? ;) |
| 10:33 | tbaldridge | clgv: no live stream, but they said they're doing "same day upload" |
| 10:34 | hyPiRion | idk if there's a live stream, but yes, we've been through two |
| 10:35 | andrewhr | tbaldridge: nice to know! :) |
| 10:35 | tbaldridge | https://twitter.com/clojure_conj/status/535087288725012480 |
| 10:36 | tbaldridge | That's the official tweet, and a link to the YT account |
| 10:36 | Frozenlock | Same day upload? That's amazing! |
| 10:37 | tbaldridge | they pulled it off at Clojure/West, I think my talk was online 4 hours after I gave it |
| 10:37 | tbaldridge | Frozenlock: most of that was due to InfoQ from what I understand, they delay things like crazy |
| 10:38 | Frozenlock | Ah, that would explain a lot... |
| 10:38 | tbaldridge | I think their goal was a steady stream of talks year round, and they didn't want some sort of "here's 20 Clojure talks" thing either. So they'd interleave conference videos and then only release 2-3 videos a week. |
| 10:39 | tbaldridge | I understand why they did that, but it's still a bad idea IMO. |
| 10:39 | clgv | tbaldridge: oh that'd be great |
| 10:40 | clgv | I am interest in th Tex+Clojure combination - I couldnt find its repository so far |
| 10:43 | sdegutis | ,(:path (meta (defn ^{:method :get, :path "/foo/:bar"} get-foo-bar [] 3))) |
| 10:43 | clojurebot | "/foo/:bar" |
| 10:43 | gfredericks | does anybody know if I can get emails for all activity on a project on jira? |
| 10:44 | Bronsa | gfredericks: you have to ping puredanger for that |
| 10:44 | gfredericks | oh |
| 10:44 | Bronsa | gfredericks: I think ATM only project leads get emails on activity |
| 10:45 | Bronsa | gfredericks: maybe andyf can do that too, not really sure |
| 10:45 | clgv | gfredericks: test.check? |
| 10:47 | gfredericks | yeah |
| 10:47 | dogonthehorizon | Greetings all, I'm attempting to call java.nio.file.Paths/get in my code with a string argument but the REPL is using the URI variant of the function instead... any idea on how I can force it to use the string variant instead? |
| 10:48 | clgv | gfredericks: oh, it has a new release :) |
| 10:48 | gfredericks | oh cool |
| 10:50 | clgv | shrinking shuffle :) |
| 10:50 | luxbock | Bronsa: now my clj files do indeed look a lot prettier |
| 10:51 | luxbock | I added a font-lock-builtin-face for the lambda character as well |
| 10:52 | Bronsa | luxbock: nice |
| 10:53 | justin_smith | dysfun: cool |
| 10:54 | Bronsa | ... hudson won't cut releases again |
| 10:54 | Bronsa | this is so annoying |
| 10:57 | justin_smith | dysfun: care to elaborate? the reference to packets seems abit odd since it is inside ring and all... |
| 10:57 | boyscared | good conj so far |
| 10:59 | andyf | gfredericks: I don?t know how to set it up for you to get all updates for a whole project |
| 10:59 | andyf | project leads do, but not sure if that is possible, or how, for others. |
| 11:00 | daniel_ | is there a live feed of the conj? |
| 11:00 | boyscared | no |
| 11:00 | Bronsa | I'm so done with hudson |
| 11:00 | boyscared | the vids should be on clojuretv shortly after concluding though |
| 11:01 | daniel_ | cool |
| 11:03 | simpleirc1 | hi why people choose clojure over cl? |
| 11:03 | clgv | simpleirc1: jvm nad its million libraries |
| 11:03 | gfredericks | andyf: computers are hard |
| 11:03 | clgv | *and |
| 11:04 | mavbozo`` | simpleirc1: awesome community |
| 11:04 | daniel_ | simpleirc1: its not so fringe |
| 11:04 | tbaldridge | simpleirc1: also, the JVM GC and JIT are top notch, really hard to beat for the "normal" use cases of Clojure. |
| 11:05 | clgv | mavbozo``: sell the "someone else has done the basic tasks for a lot of domains already" first ;) |
| 11:05 | andyf | simpleirc1: Some people have found that they really like data that is immutable by default, with explicit places you can say 'this is mutable'. |
| 11:05 | andyf | CL tends to be mutable by default |
| 11:05 | Bronsa | I guess I won't cut a t.a release today |
| 11:05 | SagiCZ1 | tbaldridge: its actually super easy to write a code that holds on references thus causing memory leaks in clojure.. |
| 11:06 | dysfun | justin_smith: packets wasn't what i actually meant. i meant to record the timings of data coming in and out to provide an idea of how long bits of response take to happen and can be analysed later in aggregate |
| 11:06 | tbaldridge | SagiCZ1: that's easy in any language with lazy constructs |
| 11:06 | tbaldridge | Ever since I started using transducers problems like that completely disappeared for me. |
| 11:06 | SagiCZ1 | i gues.. it usually didnt happen to me in java |
| 11:06 | tbaldridge | SagiCZ1: how often did you use lazy seqs i Java? ;-) |
| 11:06 | Bronsa | SagiCZ1: java doesn't have lazy-seqs |
| 11:07 | SagiCZ1 | i know i know... i was trying to say i didnt use any languages with lazy constructs before |
| 11:07 | tbaldridge | Fun fact, Rich used to write Common Lisp: http://foil.sourceforge.net/ |
| 11:07 | mavbozo | http://cdn.cognitect.com/stateofclojure/2014/clj-general.txt |
| 11:07 | mavbozo | from the latest clojure survey |
| 11:08 | clgv | SagiCZ1: holding on to the wrong reference is pretty usual in java before someone takes the time and hunts those down ;) |
| 11:08 | justin_smith | dysfun: aha, I have something like that as its own middleware, one moment |
| 11:08 | andyf | simpleirc1: Search for "Clojure for Lisp programmers" on YouTube for a talk by Rich on some of the design goals of Clojure that were different from CL, by choice. |
| 11:08 | tbaldridge | but from what I've heard, Haskell has the same problems. The entire language is lazy, so sometimes you "blow the heap" |
| 11:09 | justin_smith | $google clojure for lisp programmers youtube hickey |
| 11:09 | lazybot | [Clojure for Lisp Programmers Part 1 - Rich Hickey - YouTube] http://www.youtube.com/watch?v=cPNkH-7PRTk |
| 11:09 | justin_smith | it was worth a shot :) |
| 11:09 | Bronsa | tbaldridge: does pixie have "proper" lazy-seqs or only sequence+transduce style lazy-seqs? |
| 11:11 | clgv | technomancy: currently the fibonacci on pixie doesnt seem to beat a non-optimized clojure one, though I couldn't really time it, since I have no idea how to get timestamps in pixie ;) |
| 11:12 | TEttinger | clgv: did you mean that for tbaldridge? |
| 11:12 | daniel_ | whats pixie |
| 11:12 | Glenjamin | $google pixie lisp |
| 11:12 | lazybot | [pixie-lang/pixie · GitHub] https://github.com/pixie-lang/pixie |
| 11:12 | TEttinger | daniel_: clojure-inspired lisp running on the same kind of VM as PyPy |
| 11:12 | clgv | TEttinger: no technomancy was asking the hard question how the performance of the fibonacci function is on pixie ;) |
| 11:13 | Glenjamin | which reminds me, i should take another crack at getting pixie to build |
| 11:13 | clgv | that got me curious as well. but I guess there are no optimizations for that yet ;) |
| 11:14 | clgv | Glenjamin: current master built just fine some hours ago - you need libuv-dev and libffi-dev though |
| 11:14 | Glenjamin | yeah, pkgconfig on os x is annoying |
| 11:14 | Glenjamin | combined with me not really knowing how it works |
| 11:15 | clgv | Glenjamin: on debian-based OS it is just an "apt-get install" away ;) |
| 11:15 | Glenjamin | i think i have ffi and uv installed now, just need the makefile to find them |
| 11:15 | clgv | you can take a coffee or two during build :D |
| 11:16 | Glenjamin | seems to be going using the notes on https://github.com/pixie-lang/pixie/issues/49 |
| 11:17 | Glenjamin | warnings are ruining the nice picture |
| 11:17 | tbaldridge | Glenjamin: yeah, the warnings are being fixed. |
| 11:17 | clgv | hehe. it's a pixie, I guess? the warnings ruined it here as well |
| 11:18 | tbaldridge | And I'd be more than happy to help people build and install pixie, but sadly I'm working today. Will be on 20% time tomorrow, so I'll hang out here as well as in #pixie-lang |
| 11:18 | Glenjamin | output like this sounds like made-up tech they use on movies: |
| 11:18 | clgv | tbaldridge: did someone spend hours on the ascii image progressbar or is that generated from an image? |
| 11:18 | Glenjamin | [jitcodewriter:info] there are 988 JitCode instances. |
| 11:18 | tbaldridge | clgv: it's a mandelbrot fractal |
| 11:19 | clgv | tbaldridge: oh interesting. do I find its parameters in the pixie repository? |
| 11:19 | SagiCZ1 | does average clojure newbie need to learn about transducers or is it some super hard core niche thing i would use once in ten projects? |
| 11:19 | tbaldridge | clgv: actually that's part of the RPython compiler framework, it does it on its own. |
| 11:19 | clgv | SagiCZ1: I'd say, not immediately |
| 11:19 | Frozenlock | I never looked at transducers. Shameful, I know... |
| 11:19 | clgv | tbaldridge: ah ok |
| 11:19 | sdegutis | ,(namespace *ns*) |
| 11:19 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Namespace cannot be cast to clojure.lang.Named> |
| 11:20 | Bronsa | ,(ns-name *ns*) |
| 11:20 | clojurebot | sandbox |
| 11:20 | clgv | SagiCZ1: actually as newbie hold on to stable clojure which does not contain transducers ;) |
| 11:20 | tbaldridge | SagiCZ1: IDK, I mean we got along for years without them, but these days I think transducers should be taught before lazy seqs. |
| 11:20 | SagiCZ1 | what is stable clojure? or why is clojure with transducers unstable? |
| 11:20 | tbaldridge | once they're stable, there's still a few bugs in transducers. |
| 11:20 | hiredman | tbaldridge: a feature which isn't in a released version yet? |
| 11:20 | Glenjamin | do you think they should be taught under the "transducers" banner, or just as "here's how to combine a bunch of operations" ? |
| 11:20 | TEttinger | 1.7.0 is the transducer release |
| 11:21 | TEttinger | it's in alpha |
| 11:21 | SagiCZ1 | oh i see |
| 11:21 | clgv | tbaldridge: really, we didn't really explain that those sequence functions are lazy at all in the first lectures to not confuse the students which knew only Java |
| 11:22 | tbaldridge | I guess my point is, why would I ever want lazy-seq map, when I have transducer's map? Transducers give you most of the power of lazy seqs without some of the drawbacks. |
| 11:23 | sdegutis | tbaldridge: Which drawbacks? |
| 11:23 | tbaldridge | There's no reason to teach features in the order they were released. |
| 11:23 | Frozenlock | tbaldridge: do you have a link to a further explanation for this? |
| 11:25 | luxbock | tbaldridge: are you working on any videos about transducers? I subscribed to your pivotshare site |
| 11:25 | luxbock | for the core.async videos, but now I'm kind of wondering how much of that stuff is going to be outdated with the addition of transducers |
| 11:26 | Glenjamin | oo, RPython now appears to be generating C code |
| 11:27 | clgv | tbaldridge: true, but if you introduce students to a completely different paradigm of programming. most try to not to overwhelm then |
| 11:27 | tbaldridge | luxbock: yes there are 3 transducer videos, more to come later this week |
| 11:27 | clgv | tbaldridge: e.g hey that's a function that applies a given function to all elements of the given list |
| 11:27 | Glenjamin | you could teach ##((map inc) [ 1 2 3 ]) instead of the seq version |
| 11:27 | lazybot | ⇒ #<core$map$fn__4338$fn__4339 clojure.core$map$fn__4338$fn__4339@45acd1f6> |
| 11:28 | Glenjamin | &*clojure-version* |
| 11:28 | lazybot | ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"} |
| 11:28 | tbaldridge | clgv: and then you spend the rest of the day explaining how bindings don't work right, how you can't read from a file with them, etc. |
| 11:28 | Bronsa | Glenjamin: that's not how transducers work |
| 11:28 | Glenjamin | :s |
| 11:28 | justin_smith | Glenjamin: I assume you want to call sequence? |
| 11:28 | Glenjamin | oh right |
| 11:28 | Glenjamin | duh |
| 11:28 | clgv | tbaldridge: not really. reading files is for later anyway |
| 11:29 | luxbock | tbaldridge: ah nice, I hadn't realized they were out already. I sent a request to pivotshare to add RSS feeds as a feature but so far they haven't added it |
| 11:29 | Glenjamin | &(sequence (map inc) [ 1 2 3 ]) |
| 11:29 | lazybot | ⇒ (2 3 4) |
| 11:30 | mavbozo | isn't How to Design Programs book a good and tested method on teaching students without overwhelming them? |
| 11:30 | clgv | mavbozo: havent heard of it thus far |
| 11:31 | tbaldridge | Glenjamin: clgv: the way walked through it in my videos is to start with eager map and filter. Then extract the conj, then integrate it with a loop, now name that loop reduce, etc. One step at a time. |
| 11:31 | tbaldridge | Teach the rationale, not the public APIs, at least that's how I like to go about it. |
| 11:31 | mavbozo | clgv: some consider it a improvement over SICP |
| 11:31 | clgv | tbaldridge: sounds good. I did not refer to your videos since I don't know them ;) |
| 11:32 | zakwilson | Is there a clojure library with a macro providing functionality similar to and and or, but catching exceptions and treating them as false? |
| 11:33 | sdegutis | zakwilson: Not that I know of, I'm not sure I see the benefit to that. |
| 11:33 | clgv | zakwilson: easy write-up - you can just modify the source of `and` and `or` |
| 11:34 | zakwilson | Yeah, I have no doubt I could write it. I was more wondering how popular the idea was. |
| 11:34 | clgv | zakwilson: wrap "(try ~x (catch Exception e false))" around "~x" |
| 11:35 | clgv | ah probably "nil" is better as return |
| 11:35 | justin_smith | I could see that leading to really weird bugs if you did not specify which exceptions you catch |
| 11:36 | justin_smith | I can't tell you how many times I have gone down a rabbit hole debugging because some lib was doing a try/catch/nil that one wouldn't expect... |
| 11:36 | zakwilson | It can't really do anything that you couldn't do with try/catch, but it seems like it might be clearer in some situations. |
| 11:36 | justin_smith | zakwilson: point being it makes the bad behavior easier |
| 11:36 | justin_smith | catching all exceptions and returning nil is already a problem |
| 11:37 | justin_smith | this is a functional language, your try/catch can easily be wrapping *my* code |
| 11:37 | gfredericks | does anybody regularly make use of a "sample" function that returns a random sample of a sequence w/o holding the head? |
| 11:37 | clgv | justin_smith: yeah that's the huge disadvantage |
| 11:38 | Glenjamin | datapoint: "something_flaky rescue nil" is relatively common in short ruby scripts |
| 11:38 | Glenjamin | dunno if that's for or against |
| 11:38 | zakwilson | justin_smith: yeah, I can see that, though I was just recently dealing with a library in Python that was too far the other way. It returns an object that may or may not have a certain attribute, which should contain a dictionary that may or may not have a certain key. |
| 11:41 | zakwilson | It ends up being that it needs to be wrapped in a try/catch or a bunch of really ugly calls to getattr. It would be less problematic in idiomatic Clojure. |
| 11:41 | justin_smith | zakwilson: we already have error-free nil returning property lookup (via get or some->) |
| 11:42 | tslocke | Is there a core function equivalent to (fn [col] [(map first col) (map second col)]) ? |
| 11:42 | justin_smith | ,(some-> [1] .length) |
| 11:43 | clojurebot | 1 |
| 11:43 | justin_smith | ,(some-> nil .length) |
| 11:43 | clojurebot | nil |
| 11:43 | tbaldridge | tslocke: try juxt !!! |
| 11:43 | clgv | zakwilson: isn't duck typing common in python? |
| 11:43 | Bronsa | tslocke: (juxt keys vals)? |
| 11:43 | justin_smith | tslocke: (map (juxt first second) coll) |
| 11:43 | Glenjamin | ~juxt |
| 11:43 | clojurebot | juxt is a little hard to grok but it's the best thing ever |
| 11:43 | tbaldridge | , ((juxt first second) [[1 2] [3 4]]) |
| 11:43 | tslocke | ty all |
| 11:43 | clojurebot | [[1 2] [3 4]] |
| 11:44 | justin_smith | tbaldridge: you may want a map in there :) |
| 11:44 | tbaldridge | um, no, bad example |
| 11:44 | tbaldridge | lol yeah |
| 11:44 | Bronsa | justin_smith: that doesn't work the way he asked |
| 11:44 | justin_smith | no? |
| 11:44 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 11:44 | tbaldridge | tslocke: congrats, you just found a use case for everyone's favorite function |
| 11:45 | justin_smith | Bronsa: oh, right |
| 11:45 | Bronsa | ((juxt keys vals) {1 2 3 4}) vs (map (juxt key val) {1 2 3 4}) |
| 11:45 | justin_smith | tslocke: Bronsa's right, that's not the answer |
| 11:46 | tslocke | ,(map (juxt first second) ‘[[a 1] [b 2] [c 3]]) |
| 11:46 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ‘ in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 11:46 | tslocke | lol |
| 11:46 | Bronsa | wut |
| 11:46 | justin_smith | tslocke: yeah, that acts as identity |
| 11:46 | justin_smith | Bronsa: smartquote |
| 11:46 | tslocke | ,(map (juxt first second) `[[a 1] [b 2] [c 3]]) |
| 11:46 | clojurebot | ([sandbox/a 1] [sandbox/b 2] [sandbox/c 3]) |
| 11:47 | Bronsa | ,(= \‘ \') |
| 11:47 | clojurebot | false |
| 11:47 | zakwilson | clgv: yes, but it doesn't help here. If you have an object that supports the expected properties and methods, you can use it in place of another, but my problem involved an object that may or may not have the right properties, despite being the same type. |
| 11:47 | Glenjamin | you want the opposite of zip i guess |
| 11:47 | EvanR | how do i implement a protocol for the data structure "map" |
| 11:47 | Bronsa | fucking unicode |
| 11:47 | Glenjamin | EvanR: IAssociative perhaps |
| 11:47 | Bronsa | EvanR: extend the protocol to IPersistentMap |
| 11:47 | Bronsa | Glenjamin: there's no IAssociative, there's a c.l.Associative |
| 11:48 | Glenjamin | bah, i'm rubbish at remembering the interface names |
| 11:48 | EvanR | i dont think you can implement protocols for interfaces? |
| 11:48 | Bronsa | EvanR: yeah you can |
| 11:48 | justin_smith | EvanR: why wouldn't you? |
| 11:48 | EvanR | is that new? |
| 11:48 | Bronsa | EvanR: nope, always been teh case |
| 11:48 | justin_smith | EvanR: that's the point of protocols isn't it |
| 11:48 | Glenjamin | i was under the impression you only implement for interfaces |
| 11:48 | zakwilson | justin_smith: property lookups of various types are probably the most common use case for error-free-or, and since those are typically error-free anyway.... |
| 11:48 | Bronsa | btw this is one of my main issues with protocols. in cljs those interfaces are protocols |
| 11:49 | Glenjamin | defprotocol generates an interface |
| 11:49 | Bronsa | and you can't extend protocols to protocols |
| 11:49 | Bronsa | so doing that in clojurescript means extending a protocol to all the concrete types |
| 11:49 | Bronsa | which.. should be implementation details |
| 11:49 | Bronsa | I would love if clojure had the concept of a "supertype" |
| 11:49 | EvanR | ill try |
| 11:50 | Bronsa | i.e. PAM, PHM & co would be PersistentMaps & extending a protocol to persistentmap would extend that for every type registered as a PersistentMap |
| 11:54 | EvanR | so i can implement a protocol for java classes, java interfaces, types |
| 11:54 | EvanR | but i cant implement java interfaces for any of these right |
| 11:55 | Bronsa | you can implement java interfaces for deftypes, you just can't extend an existing class to a java interface |
| 11:55 | EvanR | how does that look |
| 11:55 | Bronsa | (deftype foo [] Interface (method [arg |
| 11:55 | Bronsa | ] body)) |
| 11:56 | EvanR | ok |
| 11:56 | tslocke | fwiw |
| 11:56 | tslocke | ,(reduce #(map conj %1 %2) [[] []] [[:a 1] [:b 2]]) |
| 11:56 | clojurebot | ([:a :b] [1 2]) |
| 11:57 | tslocke | Kinda ugly though |
| 11:57 | tslocke | I think transducers would be the way to go but not got them at my fingertips yet |
| 11:57 | justin_smith | tslocke: not ugly to me, but maybe I have reduce-stockholm-syndrome |
| 11:57 | EvanR | cant resolve IPersistentMap |
| 11:57 | Bronsa | EvanR: clojure.lang.IPersistentMap |
| 11:57 | justin_smith | EvanR: clojure.lang. |
| 11:58 | EvanR | whats the interface for "set" |
| 11:58 | Bronsa | IPersistentSet |
| 11:58 | justin_smith | ,(clojure.string/join \space (supers (class #{}))) |
| 11:58 | clojurebot | "interface clojure.lang.IEditableCollection interface java.lang.Runnable interface clojure.lang.IFn class clojure.lang.APersistentSet interface java.io.Serializable interface clojure.lang.IHashEq interface java.util.Collection interface clojure.lang.IObj interface clojure.lang.IMeta interface clojure.lang.IPersistentCollection class java.lang.Object interface java.util.concurrent.Callable interfac... |
| 11:59 | justin_smith | for some reason IPersistentSet is near the bottom there... |
| 12:00 | justin_smith | $(clojure.string/join \space (supers (class #{}))) |
| 12:00 | justin_smith | &(clojure.string/join \space (supers (class #{}))) |
| 12:00 | lazybot | ⇒ "interface clojure.lang.IHashEq interface java.io.Serializable interface clojure.lang.IEditableCollection interface java.util.Set interface java.lang.Runnable class clojure.lang.APersistentSet interface java.util.concurrent.Callable interface java.lang.Iterable inter... https://www.refheap.com/93685 |
| 12:03 | KnightsWhoSayNi | :q |
| 12:03 | KnightsWhoSayNi | blergh |
| 12:04 | clgv | Ni! Ni! Ni! |
| 12:05 | EvanR | ,((symbol ":a") {:a 2}) |
| 12:05 | clojurebot | nil |
| 12:05 | EvanR | ,((symbol "a") {:a 2}) |
| 12:05 | clojurebot | nil |
| 12:05 | EvanR | whats the big idear |
| 12:06 | Bronsa | :a is not a symbol |
| 12:06 | Bronsa | it's a keyword |
| 12:06 | EvanR | oh |
| 12:07 | bcm | Hmm, why test.check? |
| 12:09 | gfredericks | bcm: you're asking why it exists? |
| 12:10 | justin_smith | ,((keyword "a") {:a 2}) ; EvanR |
| 12:10 | clojurebot | 2 |
| 12:11 | EvanR | yes, and i finally got it to work after saving my file and reloading my source files several times |
| 12:11 | clgv | EvanR: you can explore types via ##(type :a) |
| 12:11 | lazybot | ⇒ clojure.lang.Keyword |
| 12:11 | EvanR | ##? |
| 12:12 | justin_smith | EvanR: inline syntax for lazybot |
| 12:12 | EvanR | yes i got type |
| 12:13 | kenrestivo | ,phm is persistent hash maps |
| 12:13 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: phm in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 12:13 | kenrestivo | ~phm is persistent hash maps |
| 12:13 | clojurebot | Alles klar |
| 12:15 | clgv | phm? |
| 12:15 | clojurebot | phm is persistent hash maps |
| 12:15 | clgv | clojurebot: botsnack |
| 12:15 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 12:15 | clgv | you have to reinforce it ;) |
| 12:27 | marchdown | Hello there. I’ve a couple of questions about lazy sequences. First, how do I take a difference of two lazy sequences, second, where do I chant appropriate incantations to get bignums in the following example: https://gist.github.com/marchdown/d89c273506f120c9f7ba |
| 12:29 | marchdown | I mean, is there a canonical difference function, or do I have to inspect two lazy sequences element-by-element and discard some by hand? |
| 12:29 | dnolen_ | marchdown: use +' for auto promotion, no canonical difference function, you probably need to do something by hand |
| 12:29 | marchdown | Thanks. |
| 12:30 | marchdown | Yep, that works. |
| 12:30 | dnolen_ | marchdown: you do have clojure.data/diff, never tried it w/ lazy seqs |
| 12:31 | marchdown | What should I read up on once I begin to care about performance? As in timing and profiling tools? |
| 12:32 | Bronsa | marchdown: https://github.com/hugoduncan/criterium |
| 12:32 | justin_smith | standard java profilers work |
| 12:32 | justin_smith | or criterium for microbenchmarks, yeah |
| 12:32 | marchdown | Thanks. |
| 12:33 | tbaldridge | marchdown: the two rules are a) only benchmark after the code is warm (see criterium for help) b) don't profile inside lein, it does crazy stuff to the JVM to help with development. |
| 12:33 | tbaldridge | sometimes at the cost of runtime performance. |
| 12:34 | clgv | it should be safe to profile within "lein" when your profile.clj replaces the default jvm args lein sets |
| 12:34 | clgv | btw. recent versions of criterium warn when that is not the case |
| 12:34 | tbaldridge | probably, but I don't like to risk it. I just compile via uberjar and then do java -jar. |
| 12:35 | technomancy | lein with-profile production run ... |
| 12:35 | marchdown | regarding lein, how do I grow past single core.clj source file? Simply adding (ns foo.core (:require foo.bar)) is not enough to call quux defined in bar.clj |
| 12:36 | technomancy | marchdown: (:require [foo.bar :as bar]) |
| 12:36 | technomancy | bar/quux |
| 12:36 | marchdown | Thanks! |
| 12:37 | noonian | or (:require [foo.bar :refer [quux]]) |
| 12:37 | tbaldridge | technomancy: but what are the settings of with-profile production? That's the problem if I'm citing benchmark results it's easier to just use a jar and remove all doubt. |
| 12:38 | TimMc | marchdown: Or your original :require, but then use foo.bar/quux |
| 12:38 | technomancy | tbaldridge: production is an empty profile |
| 12:38 | tbaldridge | technomancy: that goes for any dev tool btw, not just lein |
| 12:39 | technomancy | but yeah, the closer to production the better |
| 12:40 | technomancy | don't profile on a mac if you're deploying on linux |
| 12:40 | gfredericks | hey I just succeeded in getting the phrase "test.chuck" onto a slide at clojure conj |
| 12:44 | clgv | gfredericks: you did a talk about test.check? |
| 12:44 | clgv | and snuck in the lovely chuck? ;) |
| 12:45 | gfredericks | no I'm not even there |
| 12:45 | gfredericks | somebody mentioned test.chuck |
| 12:45 | clgv | ah kk |
| 13:21 | sdegutis | So far this API isn't looking different enough to be worthwhile: https://github.com/sdegutis/clover |
| 13:25 | expez | Given a jar, how would I go about getting a list of all exported symbols? |
| 13:26 | justin_smith | expez: you can open the jar as a zip file and look at the namespaces |
| 13:26 | justin_smith | there is no specific "list of vars created in a jar" |
| 13:26 | justin_smith | expez: or do you mean classes/ |
| 13:27 | expez | justin_smith: Vars, initially, but would like to do classes too. Visual inspection is not an option. I was thinking maybe I could ingest everything with tools.analyzer and query the ASTs or something |
| 13:27 | justin_smith | expez: the problem is there is no manifest that lists all namespaces contained |
| 13:28 | expez | just consume all .clj files? |
| 13:28 | justin_smith | not to meantion dirty tricks that create a var without using top level def / defn |
| 13:28 | justin_smith | expez: I guess you could hack that up with t.a.jvm yeah |
| 13:29 | expez | I was thinking an 'import symbol at point' operation would be nice for clj-refactor. it would then build a cache of symbols on the classpath and just import it if it's one or prompt you if several. |
| 13:29 | justin_smith | expez: you keep saying symbol when you mean var |
| 13:29 | expez | Building ASTs are expensive, but you could cache that stuff |
| 13:30 | expez | my bad, is java.util.Date. considered a var? |
| 13:30 | justin_smith | maybe you are looking for some sort of compile time abstraction |
| 13:30 | justin_smith | but it isn't a symbol, or a var |
| 13:31 | justin_smith | it's a reader macro that resolves to (new java.util.Date) |
| 13:31 | expez | the thing at point might not even resolve to a var, right? |
| 13:31 | justin_smith | right |
| 13:31 | Bronsa | well it *is* a symbol justin_smith |
| 13:31 | justin_smith | Bronsa: OK |
| 13:32 | Bronsa | also it's not a reader macro |
| 13:32 | justin_smith | just not one that can be read as such |
| 13:32 | Bronsa | ,(read-string "foo.") |
| 13:32 | clojurebot | foo. |
| 13:32 | expez | clojure.tools.analyzer.ast.query this looks like it might have some stuff, where you can build a db from ASTs and query it. |
| 13:32 | Bronsa | justin_smith: it can be read, the transformation happens at macroexpansion time not at read-time |
| 13:32 | justin_smith | Bronsa: oh, thanks for clearing that up |
| 13:33 | Bronsa | I have no idea what I'd call that though |
| 13:33 | Bronsa | a macroexpansion-time transformation |
| 13:33 | Bronsa | expez: yeah, you need to depend on Datomic to use that though |
| 13:34 | justin_smith | expez: I imagine namespaces like this could easily trip you up https://github.com/Prismatic/hiphip/blob/master/src/hiphip/double.clj |
| 13:35 | expez | Does this seme doable, Bronsa? Just ingest every .clj file found on classpath with tools.analyzer to get a list of symbols to possibly import? |
| 13:36 | technomancy | expez: are you familiar with slamhound? |
| 13:36 | expez | justin_smith: it's just a helper function, if it works 90% of the time that's still cool. |
| 13:36 | Bronsa | expez: I wasn't following the conversation, what are you trying to do? |
| 13:36 | expez | technomancy: I know what it is. Does it contain code I should pilfer? |
| 13:37 | technomancy | expez: well, it does the same thing, basically, but with a dramatically simpler approach |
| 13:37 | expez | Bronsa: user hits 'import symbol at point' and clj-refactor imports the symbol below the cursor, possibly with a prompt if it's ambiguous |
| 13:37 | technomancy | (all-ns) + (ns-publics n) |
| 13:37 | technomancy | after loading all namespaces on the classpath |
| 13:37 | technomancy | you don't need the analyzer for that |
| 13:37 | technomancy | provided you're OK with compiling everything you find |
| 13:38 | Bronsa | you'd need to do that with t.a anyway |
| 13:39 | expez | man, didn't even know about all-ns. The docstring is a bit sparse, but the seq is of every ns on the classpath? |
| 13:39 | justin_smith | expez: no, all the ones loaded already |
| 13:40 | justin_smith | and also, namespaces made by shady methods where the ns does not reflect an artifact in the classpath as well |
| 13:40 | Shayanjm | someone should make a cool clj dsl for working with these sets: http://opendata.cern.ch/ |
| 13:40 | Shayanjm | :) |
| 14:00 | kenrestivo | using the clojure.tools.namespace.repl/refresh thing... it tries to compile test/ files and chokes on them. anyone else seeing that? |
| 14:01 | kenrestivo | specifically, it compiles test/foo/core_test.clj which has in it a (:require [foo.core :refer :all]), and can't find that namespace at wherever it is in the compilation at that point |
| 14:08 | mi6x3m | hey bbloom, did you by any chance find the reason for the issue yesterday? |
| 14:08 | mi6x3m | I thought I'd search for it this evening |
| 14:14 | emacsnub | does annotating your code w/ core.typed act as type inference? |
| 14:14 | emacsnub | act as type hinting |
| 14:15 | clrnd | emacsnub, I'm sure core.typed use type inference, otherwise you'd need to type every sub-expression |
| 14:18 | amalloy | emacsnub: i would be quite surprised if it acted as typehinting |
| 14:18 | emacsnub | amalloy: clrnd: thanks! |
| 14:19 | emacsnub | :amalloy so it probably won't improve runtime performance, right |
| 14:19 | amalloy | kenrestivo: test/ is on the classpath during dev, so if you attempt to reload everything on the classpath then test/ will be included |
| 14:20 | amalloy | but it should work fine, i would think, as long as the dependencies are declared properly and you don't do anything grossly side-effectful at the top level of your tests |
| 14:20 | clrnd | core.typed doesn't touch the runtime at all, afaik |
| 14:21 | amalloy | emacsnub: no, core.typed only acts at compile time; as far as i know, the bytecode generated for a function that's typed with core.typed will be identical if you remove the annotations |
| 14:21 | emacsnub | oh ok |
| 14:22 | emacsnub | thanks again |
| 14:41 | gfredericks | so I think something about autocompleting is causing my emacs to be really laggy while typing clojure code |
| 14:41 | gfredericks | sound familiar to anybody? |
| 14:42 | gfredericks | even worse if I type a prefix of something quickly and then try to autocomplete it, it will likely autocomplete from a prefix of the prefix |
| 14:42 | tbaldridge | reason #42 why I stopped using emacs |
| 14:42 | gfredericks | what nobody STOPS using emacs |
| 14:42 | jaaqo | My lagginess was about cider, cider-nrepl and company version mismatches |
| 14:43 | Bronsa | I have never had lag with ac-slime |
| 14:43 | technomancy | gfredericks: autocomplete.el? |
| 14:43 | joshuafcole | gfredericks: oh? |
| 14:44 | joshuafcole | :P |
| 14:44 | technomancy | gfredericks: it's a pretty crap implementation from what I understand; the alternatives are a lot more stable. |
| 14:44 | gfredericks | technomancy: I see "AC" in my modeline; what does that suggest? |
| 14:44 | technomancy | gfredericks: yeah, you probably want to ditch that |
| 14:45 | jcsims | gfredericks: I switched from auto-complete to company awhile back, and it's treated me well |
| 14:45 | technomancy | I just use the built-in completion because I'm a luddite |
| 14:47 | amalloy | i use AC but not ac-slime. i heard bad things about ac-slime years ago |
| 14:47 | Bronsa | amalloy: ? |
| 14:47 | gfredericks | is there a good lein plugin for generating a Main class so you can have an arg-free executable jar but otherwise avoid AOT? |
| 14:48 | TimMc | gfredericks: There's a bad lein plugin. |
| 14:48 | amalloy | as i recall, the same thing gfredericks is saying. long pauses while typing because autocomplete is trying to find all possible completions |
| 14:49 | gfredericks | TimMc: what's the bad one? |
| 14:49 | TEttinger | https://github.com/llasram/lein-otf |
| 14:50 | Bronsa | dunno, I never noticed any lag & type pretty fast |
| 14:50 | TimMc | https://github.com/timmc/lein-otf is broken with lein 2.4.3 or 2.5.0 (I forget which I've tried), but it's really really easy to replicate in your own code. |
| 14:51 | amalloy | TimMc: why do this with a java loader class that reads the manifest, rather than injecting a clojure file like: (ns my.loader (:gen-class)) (defn -main [& args] (require 'real.main) (apply (ns-resolve 'real.main '-main) args))? |
| 14:52 | amalloy | i don't know how to do that in a lein plugin, but that's how i've produced non-aot runnable uberjars by hand |
| 14:52 | gfredericks | speaking of which what's the right way to "inject" some clojure code as above which is intended to work when packaged up as well? |
| 14:52 | EvanR | why is the datomic pull api only getting some of the things nested past depth 3 (i know this is technically the wrong channel but if you know the answer to this ill be happy to hear the answer in #datomic) |
| 14:52 | gfredericks | we were talking about util libs a while ago and the problem applies there too |
| 14:53 | TimMc | amalloy: I think I did, but it was pulled in from the dependency. |
| 14:53 | TimMc | I don't recall the tradeoffs of various injection strategies. |
| 14:53 | amalloy | TimMc: pulled in from the dependency? |
| 14:54 | TimMc | As in, a clojure file was injected, but it still read from the manifest. |
| 14:54 | TimMc | I had to much with stuff in or near the manifest anyhow, IIRC. |
| 14:55 | TimMc | Anyway, I should just replace the readme with "Just make another nsthat requires your real ns and calls -main, okay?" |
| 14:56 | gfredericks | you could call the namespace itself -main |
| 14:56 | TimMc | I.. could. |
| 14:56 | gfredericks | don't judge me. |
| 14:56 | amalloy | gfredericks: if i made suggestions as outrageous as yours i'd live in constant fear of the inquisition arriving on my doorstep |
| 14:57 | gfredericks | hey great I love questions |
| 14:57 | amalloy | gfredericks: is your answer to this question a lie? |
| 14:58 | dbasch | amalloy: perhaps |
| 14:58 | TimMc | where's technomancy |
| 14:58 | technomancy | you'll never catch me |
| 14:59 | gfredericks | amalloy_: I’m really happy for you, Imma let you finish but Beyonce had one of the best videos of all time |
| 14:59 | TimMc | Get back here! I need that "mu" character! |
| 15:00 | technomancy | (defun mu () (interactive) (insert "無")) |
| 15:00 | TimMc | gfredericks: "What is 2 + 2? (This is strictly a 3-or-5 question.)" |
| 15:01 | dbasch | TimMc: pancakes |
| 15:01 | gfredericks | ,(bit-or 3 5) |
| 15:01 | clojurebot | 7 |
| 15:01 | TimMc | haha |
| 15:02 | dbasch | (inc gfredericks) |
| 15:02 | lazybot | ⇒ 108 |
| 15:02 | TEttinger | clojurebot: mu |is| 無 |
| 15:02 | clojurebot | In Ordnung |
| 15:02 | TEttinger | ~mu |
| 15:02 | clojurebot | mu is 無 |
| 15:03 | TimMc | ~無 |
| 15:03 | clojurebot | excusez-moi |
| 15:03 | TEttinger | better, TimMc? |
| 15:03 | TimMc | *nod* |
| 15:04 | TEttinger | $google 無 |
| 15:04 | lazybot | [無 - Wiktionary] http://en.wiktionary.org/wiki/%E7%84%A1 |
| 15:05 | TEttinger | neither yes nor no, interesting |
| 15:18 | bbloom | mi6x3m: iirc you were doing (foo a b c :x 1 :y 2 :z 3) positional arguments like that |
| 15:18 | bbloom | that's not a map, and so won't be formatted as a map |
| 15:18 | bbloom | there's no general way to tell keyword args from positional args |
| 15:19 | bbloom | so there's no general way to print them where key/value pairs stay on a line |
| 15:19 | bbloom | at best, you could use a heuristic |
| 15:19 | danielcompton | ~karma amalloy |
| 15:19 | clojurebot | excusez-moi |
| 15:21 | bbloom | clrnd: i tink emacsnub's intended question was: does using core.typed preclude the need to write clojure's type hints to the compiler for avoiding reflection and boxed math |
| 15:21 | danielcompton | karma amalloy |
| 15:21 | danielcompton | ,karma amalloy |
| 15:21 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: karma in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:21 | gfredericks | is bbloom time-traveling again? |
| 15:21 | justin_smith | danielcompton: $karma amalloy |
| 15:21 | TimMc | gfredericks: I COME... FROM THE PAST! |
| 15:21 | danielcompton | $karma amalloy |
| 15:21 | lazybot | amalloy has karma 197. |
| 15:21 | justin_smith | (identity amalloy) |
| 15:21 | lazybot | amalloy has karma 197. |
| 15:21 | justin_smith | or that :) |
| 15:22 | danielcompton | whew, I didn't miss the big 200 |
| 15:22 | gfredericks | bbloom: how many fingers am I holding up? |
| 15:22 | clrnd | bbloom, ooohhhhh, yeah probably |
| 15:22 | bbloom | amalloy: i'm not sure, but there may be variants of defn that accept annotations and do hinting, but i dunno |
| 15:23 | shafire | hello smart people |
| 15:27 | bbloom | gfredericks: can you hear me now? |
| 15:27 | gfredericks | bbloom: ACK |
| 15:27 | bbloom | gfredericks: i have no idea wtf is wrong |
| 15:28 | bbloom | maybe i was rate limited or something? .... i've set my irc client to join far fewer channels |
| 15:28 | justin_smith | bbloom: I've had that delay thing before. IRC is weird. |
| 15:28 | bbloom | *shrug* |
| 15:28 | clrnd | lol |
| 15:28 | gfredericks | bbloom: does it apply across all freenode or just to #clojure? |
| 15:29 | bbloom | gfredericks: doesn't seem to affect private messages |
| 15:29 | bbloom | not sure about other channels |
| 15:29 | gfredericks | aw snap |
| 15:29 | bbloom | it's kinda hard to find out b/c people may just ignore you heh |
| 15:29 | bbloom | i feel like i'm manually implementing TCP :-P |
| 15:29 | gfredericks | yeah and it's hard to guess on this end because you might just be having an unsurprisingly laggy IRC conversation |
| 15:30 | gfredericks | I didn't guess it till I saw two late replies back to back |
| 15:30 | bbloom | that's why i was testing with the ghost_of_bbloom via a web irc client |
| 15:30 | TEttinger | you could be missing out on show gratis spam! solo hoy! |
| 15:30 | bbloom | no, i'm not missing out on that at all lol |
| 15:32 | justin_smith | TEttinger: we should totally have a bot that a) changes nicks periodically b) spouts a small bit of markov generated clojure related gibberish periodically c) kickbans anyone that sends it a pm which matches our profile |
| 15:33 | gfredericks | d) kickbans random people periodically |
| 15:33 | justin_smith | sure, why not |
| 15:34 | justin_smith | gfredericks: but our spammer is predictable enough that false positives would be pretty easy to prevent - ie. repeatedly using the same text |
| 15:34 | TimMc | This would require getting additional ops. |
| 15:34 | TEttinger | yes. |
| 15:35 | Montanan | I'm staring at the core.async example, line 91 of https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj and wondering how we get out of the (while true ...) loop |
| 15:35 | justin_smith | Montanan: replace true with a different condition? |
| 15:35 | TimMc | I think if we should have two bots. One periodically says ~guards and the other inc's the first. If both get the same message from the same sender within 30 minutes of each other one kickbans the sender. |
| 15:36 | TimMc | They'll blend right in. |
| 15:36 | justin_smith | haha |
| 15:36 | Montanan | my question is, why does it leave the (while true ...) loop |
| 15:36 | aperiodic | Montanan: you don't. that's the magic of go blocks; when it's waiting for a new value from the channel, it stops executing that go block's state machine and frees the thread up to go do something else. |
| 15:36 | justin_smith | Montanan: does it ever leave? |
| 15:36 | justin_smith | aperiodic: that example is a thread, not a go block |
| 15:37 | Montanan | whoah, that's a trip. Thank you aperiodic |
| 15:38 | aperiodic | Montanan: and the thread keeps going because the `go` macro is asynchronous (the body gets executed in a different thread, I think) http://clojure.github.io/core.async/#clojure.core.async/go |
| 15:38 | aperiodic | justin_smith: what? there's a go call right on that line. |
| 15:38 | tbaldridge | first conj vid: https://www.youtube.com/watch?v=BNkYYYyfF48&feature=youtu.be |
| 15:40 | nullptr | tbaldridge: awesome, didn't realize these were posted so quickly -- thanks |
| 15:40 | justin_smith | aperiodic: what line? |
| 15:40 | aperiodic | justin_smith: line 91, as Montanan said https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj#L91 |
| 15:40 | justin_smith | aperiodic: oh, I did not see the line part, sorry |
| 15:49 | Montanan | aperiodic: when the let block ends, is the thread or go block cleaned up? |
| 15:54 | aperiodic | Montanan: I'm not sure. I'm not that familiar with core.async. My guess would be no, since the thread actually executing the go block still has a reference to the channel and it's still open. I would think that the channel needs to be explicitly closed first, then the thread where the go block is executing will notice and release references to the channel & go block, and then after the channel is released on the calling/consuming side everything can be |
| 15:55 | aperiodic | Montanan: but like I said, I don't know much about core.async, so you should verify that somehow. |
| 15:55 | justin_smith | Montanan: what do you mean by "when the let blcok ends" |
| 15:55 | justin_smith | when all code inside it has stopped running? |
| 15:57 | justin_smith | objects that don't have references outside a specific thread will be reclaimed sometime after that thread is reclaimed |
| 15:57 | Montanan | Thank you aperiodic. Yes justin_smith, when the main thread of execution leaves the let block |
| 15:57 | justin_smith | Montanan: main thread? |
| 15:59 | justin_smith | I mean if I use my definition of main thread, nothing inside a thread or go block is run in the main thread |
| 16:01 | Montanan | I'm following, justin_smith, once outside the let block, there is no reference to the thread, and thereby it should be reclaimed later |
| 16:02 | Montanan | I should be able to verify that in a debugger |
| 16:03 | justin_smith | Montanan: right, jvisualvm will show you all the threads that exist |
| 16:03 | justin_smith | it's much trickier in core.async |
| 16:03 | tbaldridge | Montanan: os the gist is, the that everything gets reclaimed after the last reference to it is gone. For go blocks, when they pause they are attached to channels. |
| 16:03 | justin_smith | since they use a thread pool, and have some implementation dependent definition of a go block that may be hard to recognize in a profiler or debugger |
| 16:03 | tbaldridge | So they live as long as the channels they are attached to. |
| 16:04 | tbaldridge | with (thread...) blocks there is an actual OS thread running that block, and the OS keeps a pointer to that thread, so it never gets reclaimed. |
| 16:04 | tbaldridge | until it exits that is. |
| 16:05 | justin_smith | tbaldridge: so the actual answer to Montanan 's earlier question was that he could stop the go block by closing the channels |
| 16:05 | tbaldridge | justin_smith: well closing them will cause them to start returning nulls, which will cause that go block to loop forever. |
| 16:06 | tbaldridge | if you just drop the reference to the channel, the go block will attach to it, then the channel will get reclaimed, and with it the go. |
| 16:06 | justin_smith | tbaldridge: oh, ok |
| 16:06 | justin_smith | tbaldridge: the interaction between gc and clojure constructs still confuses me sometimes, thanks for clearing that up |
| 16:11 | Montanan | Thank you tbaldridge, justin_smith. |
| 16:12 | justin_smith | Montanan: tbaldridge has some video tutorials for core.async |
| 16:13 | Montanan | Looks like he gets some of my loot |
| 16:22 | SagiCZ1 | do you have any idea what could be causing this? |
| 16:22 | SagiCZ1 | NumberFormatException For input string: "198717588" |
| 16:22 | SagiCZ1 | I mean, it looks pretty parsable to me.. |
| 16:22 | SagiCZ1 | ,(Integer/parseInt "198717588") |
| 16:22 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "198717588"> |
| 16:22 | justin_smith | &Integer/MAX_VALUE |
| 16:22 | lazybot | ⇒ 2147483647 |
| 16:23 | SagiCZ1 | ,(< 2147483647 198717588) |
| 16:23 | clojurebot | false |
| 16:23 | justin_smith | &(> Long/MAX_VALUE 198717588 Integer/MAX_VALUE) |
| 16:23 | lazybot | ⇒ false |
| 16:23 | justin_smith | hrm |
| 16:24 | tbaldridge | ,(< 2147483647 198717588N) |
| 16:24 | clojurebot | false |
| 16:24 | justin_smith | (Integer/parseInt "198717588") |
| 16:24 | tbaldridge | hrm... |
| 16:24 | justin_smith | &(Integer/parseInt "198717588") |
| 16:24 | lazybot | ⇒ 198717588 |
| 16:24 | SagiCZ1 | ,(Integer/parseInt "198717588") |
| 16:24 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "198717588"> |
| 16:24 | justin_smith | ,(map int "198717588") |
| 16:24 | clojurebot | (65279 49 57 56 55 ...) |
| 16:24 | SagiCZ1 | what is this sorcerry |
| 16:24 | justin_smith | there's your problem |
| 16:24 | justin_smith | unicode! |
| 16:24 | amalloy | (inc justin_smith) |
| 16:24 | lazybot | ⇒ 138 |
| 16:24 | tbaldridge | rofl |
| 16:24 | SagiCZ1 | sorry im slow, could you elaborate? |
| 16:24 | tbaldridge | that's awesome |
| 16:25 | justin_smith | ,(char 65279) |
| 16:25 | clojurebot | \ |
| 16:25 | amalloy | SagiCZ1: that's not a 1, it's a different unicode character that renders the same as a 1 |
| 16:25 | amalloy | or similarly, at least |
| 16:25 | justin_smith | ,(char 49) |
| 16:25 | clojurebot | \1 |
| 16:25 | dbasch | on my screen it renders like _1 |
| 16:25 | SagiCZ1 | isnt that nice |
| 16:25 | justin_smith | I think that may be a BOM hidden in the screen |
| 16:25 | clojurebot | Pardon? |
| 16:25 | kenrestivo | that charactter renders as a \ |
| 16:25 | justin_smith | ,(str (char 65279)) |
| 16:25 | clojurebot | "" |
| 16:25 | Bronsa | I see an small underscore |
| 16:25 | dbasch | same as Bronsa |
| 16:26 | Bronsa | shade |
| 16:26 | amalloy | &(printf "%x" 65279) |
| 16:26 | lazybot | ⇒ feffnil |
| 16:26 | amalloy | yeah, that's a BOM |
| 16:26 | Bronsa | http://i.imgur.com/xjjHK5V.png |
| 16:26 | amalloy | FEFF |
| 16:26 | justin_smith | ZERO WIDTH NO-BREAK SPACE |
| 16:26 | justin_smith | old-name: BYTE ORDER MARK |
| 16:26 | SagiCZ1 | ,(Integer/parseInt "198717588") |
| 16:26 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "198717588"> |
| 16:27 | justin_smith | SagiCZ1: it has hidden whitespace, so it isn't parsable |
| 16:27 | SagiCZ1 | i am not sure what i can do about it.. its a string from a text file, can i trim it or something? |
| 16:27 | justin_smith | ,(Integer/parseInt (sube "198717588" 1)) |
| 16:27 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sube in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:27 | justin_smith | ,(Integer/parseInt (subs "198717588" 1)) |
| 16:27 | clojurebot | 198717588 |
| 16:27 | amalloy | SagiCZ1: probably, read the text file better so that it doesn't include the BOM |
| 16:27 | justin_smith | a regex that trims should handle it |
| 16:28 | TimMc | SagiCZ1: Stop using notepad? |
| 16:28 | amalloy | it's probably the first two bytes in the file, and when you specify the proper character encoding you should be able to read it just fine |
| 16:28 | kenrestivo | right, we've been around this block before here. |
| 16:28 | SagiCZ1 | TimMc: its notepad++ |
| 16:29 | SagiCZ1 | amalloy: i was joining these files earlier, so im afraid the bom is actually in the middle of the new file |
| 16:29 | kenrestivo | the dreaded feff |
| 16:29 | justin_smith | ,(Integer/parseInt (second (first (re-seq #"([0-9]+)" "198717588")))) ; SagiCZ1 |
| 16:29 | clojurebot | 198717588 |
| 16:29 | dbasch | SagiCZ1: where do the files come from? |
| 16:30 | TimMc | BOM: Because no one would ever cat files together, ever. |
| 16:30 | csd_ | I'm looking for code similar to Rich Hickey's ants.clj. Any suggestions? |
| 16:30 | justin_smith | ,(Integer/parseInt (ffirst (re-seq #"([0-9]+)" "198717588"))) ; actually this is better |
| 16:31 | clojurebot | 198717588 |
| 16:31 | SagiCZ1 | justin_smith: thank you very much.. but i still wonder how to fix the actual file.. notepad++ doesnt show any weird unprintable characters |
| 16:31 | TimMc | SagiCZ1: Notepad++ is probably adding it. |
| 16:31 | SagiCZ1 | TimMc: i am not saving it though |
| 16:31 | justin_smith | SagiCZ1: you could slurp the file, and filter all characters that equal (char 0xfeff) |
| 16:31 | SagiCZ1 | justin_smith: i could do that |
| 16:31 | justin_smith | err, I mean remove of course |
| 16:31 | SagiCZ1 | yeah sure |
| 16:32 | justin_smith | and then spit it back out again, of course |
| 16:32 | TimMc | .replaceAll |
| 16:32 | justin_smith | even better |
| 16:32 | SagiCZ1 | these files used to be in a really obscure encoding.. i think it was utf16 little endian.. i had a lot of trouble even decoding it.. but after that i spit it back with the default spit encoding so i dont know what went wrong |
| 16:33 | TimMc | &(first "198717588") |
| 16:33 | lazybot | ⇒ \ |
| 16:33 | TimMc | &(first (.replaceAll "198717588" "\ufeff" "")) |
| 16:33 | lazybot | ⇒ \1 |
| 16:33 | SagiCZ1 | TimMc: this just baffles me honestly |
| 16:34 | TimMc | BOM is pretty baffling. :-( |
| 16:34 | justin_smith | BOM is also the name of a character in one of Samuel Beckett's weirdest plays |
| 16:34 | SagiCZ1 | justin_smith: what a coincidence |
| 16:34 | justin_smith | heh |
| 16:35 | justin_smith | yeah, the play is pretty baffling too |
| 16:35 | SagiCZ1 | zero width no break space.. who thought that would be a nice character to have? |
| 16:35 | justin_smith | http://en.wikipedia.org/wiki/What_Where |
| 16:36 | justin_smith | SagiCZ1: it's used as a marker. It should be metadata, but it is in the file. |
| 16:36 | SagiCZ1 | i see |
| 16:36 | justin_smith | "The byte order mark (BOM) is a Unicode character used to signal the endianness (byte order) of a text file or stream." |
| 16:36 | justin_smith | http://en.wikipedia.org/wiki/Byte_order_mark |
| 16:37 | SagiCZ1 | so feff is bom? |
| 16:37 | justin_smith | yes |
| 16:37 | SagiCZ1 | but what is it doing in the middle of the file? |
| 16:37 | justin_smith | feff is bom, and should only be at the beginning of a file |
| 16:37 | justin_smith | because someone fucked up, clearly |
| 16:37 | SagiCZ1 | justin_smith: i did |
| 16:37 | justin_smith | well, whatever tool was combining the files should not have left a bom in the middle |
| 16:37 | csd_ | SagiCZ1: is this a Clojure exercise? why not just use a hex editor to remove it |
| 16:38 | SagiCZ1 | when i was reading and writing the new tweaked files i used write and getBytes.. actually its a little snippet you wrote for me.. i think it wrote the bom too |
| 16:38 | SagiCZ1 | csd_: its not an exercice and i would totally do it manually if there wasnt 100GB of those files |
| 16:38 | justin_smith | yeah, getBytes and write would let you do something like that :) |
| 16:38 | csd_ | oh its more than one? |
| 16:39 | SagiCZ1 | justin_smith: at least i know how it happened.. |
| 16:39 | Guest70412 | Does anyone know if it is possible to call a function in a namespace in a lein project.clj? I'm trying to call a function to return a generated version number to use in the defproject. |
| 16:40 | TimMc | justin_smith: It's not exactly SagiCZ1's fault. |
| 16:40 | Guest70412 | I can write simple functions at the top of the project.clj but was unable to call into another namespace or add the ns macro to the top of the project.clj |
| 16:40 | justin_smith | TimMc: well, he used byte oriented methods for textual data. I put it a bit harshly, and for that I apologize. |
| 16:41 | justin_smith | sorry SagiCZ1 |
| 16:41 | hyPiRion | Guest70412: You can do (require '[my-namespace :as my-ns]) then (my-ns/my-function ...) if the namespace is on the classpath |
| 16:41 | Guest70412 | I guess there is a bootstrap problem |
| 16:41 | TimMc | justin_smith: I feel like a lot of text-oriented tools screw this up too. |
| 16:41 | TimMc | It's just a bad situation. |
| 16:41 | justin_smith | yeah |
| 16:41 | SagiCZ1 | justin_smith: no problem, i didnt see the harsh tone, language barrier i guess :) |
| 16:41 | Guest70412 | thanks @hyPiRion |
| 16:42 | hyPiRion | Guest70412: But it sounds like a bad idea to use functions outside of core clojure, at least that's my gut feeling |
| 16:43 | justin_smith | Guest70412: maybe what you really want is to write your own lein plugin and run it? |
| 16:43 | Guest70412 | hyPiRion: I have some code that gets version numbers from the build server and I was wondering if I could share the code between clojure projects. |
| 16:43 | Guest70412 | justin_smith: didn't actually consider that |
| 16:44 | Guest70412 | justin_smith: could be a good shout if it's possible to set the version of the current project |
| 16:44 | justin_smith | Guest70412: or you could make your version-fetching code into a standalone lib, install it locally, and add it to deps in your profiles.clj |
| 16:44 | SagiCZ1 | TimMc: i was vaguely aware that i should use text oriented functions/methods when i work with text files, but then i needed this line by line zipping writer and write/getBytes was a way i figured out with the help of this channel.. i guess i will just go through the file and remove all invisible characters besides newlines |
| 16:45 | justin_smith | SagiCZ1: ahh, in that case it was me, I remember that now |
| 16:45 | justin_smith | haha |
| 16:45 | justin_smith | (dec justin_smith) |
| 16:45 | lazybot | You can't adjust your own karma. |
| 16:45 | SagiCZ1 | justin_smith: yeah, it was actually a problem with heap space, beacuse i was keeping the whole file in memory |
| 16:45 | justin_smith | right, and I suggested a solution using getBytes and write |
| 16:45 | amalloy | SagiCZ1: BOMs in the middle of the files might not be the only problem, if you copied a bunch of bytes around without caring about their encoding |
| 16:45 | SagiCZ1 | yea |
| 16:45 | dbasch | justin_smith: you can inc everyone else, which produces the same effect :P |
| 16:46 | justin_smith | dbash |
| 16:46 | justin_smith | (map inc #clojure) |
| 16:46 | SagiCZ1 | amalloy: i am afraid of that.. they still seem to be readable though |
| 16:46 | amalloy | eg, any characters that take more than like 7 bits may be mis-encoded |
| 16:47 | SagiCZ1 | amalloy: the files contained jsut numbers, letters and ",:." |
| 16:47 | Guest70412 | thanks justin_smith and hyPiRion, I'll see what works |
| 16:47 | justin_smith | SagiCZ1: plus newlines, one assumes |
| 16:47 | SagiCZ1 | justin_smith: yeah |
| 16:48 | amalloy | when you say "letters", are you sure that there's nothing like ä? |
| 16:48 | SagiCZ1 | amalloy: yes, i think it could be encoded in plain ANSI |
| 16:48 | amalloy | then you are probably okay to just throw away and FEFFs you see |
| 16:49 | SagiCZ1 | is it possible to modify the file in place by the way? i always create a new one |
| 16:49 | dbasch | SagiCZ1: yes if you seek and replace bytes |
| 16:49 | dbasch | of course you can’t shrink it |
| 16:49 | SagiCZ1 | dbasch: ok thats horrible, scratch that thought |
| 16:50 | dbasch | well you can shrink it but that would be blasphemy |
| 16:51 | dbasch | “now I’m going to move 1GB one byte up” |
| 16:51 | justin_smith | dbasch: finger tree of inodes? lol |
| 16:52 | SagiCZ1 | i guess there is no easy way to wrap the .getBytes so that it wouldnt write the bom character huh? |
| 16:52 | SagiCZ1 | https://www.refheap.com/93692 |
| 16:53 | kenrestivo | i'm sorry if i'm being dense, but what is required to turn a manifold stream into a core.async channel? i only see docs to to the inverse. |
| 16:53 | amalloy | SagiCZ1: the question is where this "lines" thing has come from |
| 16:53 | amalloy | the BOM have been skipped while reading in the first place, if you were reading lines correctly |
| 16:54 | hyPiRion | Guest70412: You can use the update-in leiningen task to inject the version number – I just verified it |
| 16:54 | SagiCZ1 | amalloy: they come from (line-seq (io/file "filepath)) |
| 16:55 | technomancy | the version is available at runtime now on the classpath |
| 16:55 | technomancy | check the faq for the 2.5.0 release |
| 16:55 | justin_smith | SagiCZ1: amalloy: wouldn't that be a bug in line-seq if that's the case? |
| 16:56 | amalloy | justin_smith: not necessarily. i don't know what line-seq's API is for setting the character encoding |
| 16:56 | amalloy | it can't necessarily just guess character encodings by magic; if your file is encoded in some surprising way, you'll have to say so or else get out garbage |
| 16:57 | justin_smith | amalloy: hmm, looking at the soure it just wraps BufferedReader / .readLine |
| 16:57 | justin_smith | one would think that would be well behaved |
| 16:57 | amalloy | justin_smith: obviously it's not a problem with line-seq. the question is io/reader |
| 16:57 | SagiCZ1 | by line-seq i am reading from a ZipEntry - InputStream .. i guess that reads boms as well |
| 16:57 | hyPiRion | technomancy: could you use that to change the version in the first place? Like replace something like `lein update-in : assoc :version '"my-version"' -- my-task` |
| 16:57 | hyPiRion | I must've missed that |
| 16:58 | technomancy | I think so |
| 16:58 | TimMc | amalloy: I don't know that io/reader properly removes the BOM. |
| 16:58 | TimMc | All my experiences with BOM disposal have been manual. |
| 16:58 | amalloy | TimMc: you have to set the character encoding |
| 16:58 | SagiCZ1 | and what is InputStream? isnt it just input of bytes? |
| 16:58 | amalloy | if your file is encoded as utf-16, you have to say so when making the reader |
| 16:58 | amalloy | "remove the BOM" is the wrong level to be thinking about this problem at |
| 16:59 | SagiCZ1 | amalloy: but ui/reader has some default encdoing doesnt it? if you dont specify it |
| 16:59 | TimMc | You'd think. |
| 16:59 | amalloy | sure, it's utf-8, of course |
| 16:59 | SagiCZ1 | and if it reads the file so i can see the text.. thats not a guarantee it is the correct encoding? |
| 16:59 | justin_smith | right, because bom is likely invisible |
| 17:00 | justin_smith | and utf8 uses a different bom (or does not use it at all) |
| 17:00 | SagiCZ1 | but i can't be certain about the encoding can i? unless i would specifically ask the creator of the file.. |
| 17:00 | TimMc | amalloy: The last place I worked involved text analytics and we just had a special reader that would strip the BOM when reading a file. |
| 17:01 | justin_smith | SagiCZ1: well, that's part of what bom does, is help you figure out the encoding |
| 17:01 | amalloy | TimMc: that is so wrong |
| 17:01 | TimMc | We were setting the encoding properly but still ahd to do that. |
| 17:02 | SagiCZ1 | justin_smith: i see.. notepad says its ANSI as UTF-8 .. but i guess i added some UTF-16 in the mix.. what a mess.. i guess i should have just paid for high quality data |
| 17:02 | nickik | Does anybody know how one could get the full url out of a pedestal request |
| 17:03 | TimMc | amalloy: You're saying that if I slurp a BOM-laden text file it should strip that initial U+FEFF? |
| 17:03 | TimMc | because that's not what I see. |
| 17:04 | SagiCZ1 | TimMc: even if you slurp it with the correct encoding specified? |
| 17:04 | amalloy | TimMc: that was what i thought; i could believe i'm wrong, but when you said "we *just* [strip the BOM when reading a file]" it sounded like that's all you're doing |
| 17:04 | TimMc | SagiCZ1: Yes. |
| 17:05 | SagiCZ1 | TimMc: that's a shame then.. i would think i get just the text with no nonsense |
| 17:05 | TimMc | Besides, slurp should default to UTF-8 if Alan is right (and I think he is). |
| 17:05 | SagiCZ1 | who is Alan again? |
| 17:05 | TimMc | amalloy |
| 17:05 | SagiCZ1 | oh.. duh |
| 17:05 | TimMc | I don't know why I use his wallet name sometimes. |
| 17:05 | amalloy | TimMc: so, i just created a file and saved "abcd" to it, encoded as "UTF-16" by my text editor |
| 17:06 | TimMc | I make no bets on UTF-16. |
| 17:06 | amalloy | and (seq (.getBytes (slurp "/home/akm/utf.txt" :encoding "UTF-16"))) produces (97 98 99 100 10) |
| 17:06 | amalloy | TimMc: huh? |
| 17:06 | amalloy | utf-16 is the only encoding that needs a BOM at all |
| 17:07 | TimMc | And yet UTF-8 has an optional "BOM". |
| 17:07 | TimMc | And some programs add it, just to make our lives miserable. |
| 17:08 | TimMc | Mmmm,  |
| 17:09 | TimMc | (or Ýsfs if you're using UTF-EBCDIC) |
| 17:09 | justin_smith | if we all just stopped using things that default to utf-16 this wouldn't be a problem... oh, wait |
| 17:10 | SagiCZ1 | what defaults to UTF-16? |
| 17:10 | justin_smith | java, windows |
| 17:10 | SagiCZ1 | i see |
| 17:10 | justin_smith | internal string rep in the jvm is utf-16 |
| 17:11 | justin_smith | that was my joke :) |
| 17:11 | amalloy | justin_smith: ucs-2, really, right? |
| 17:11 | SagiCZ1 | i always thought it was utf-8 |
| 17:11 | amalloy | SagiCZ1: that's the format it assumes when reading from disk, if given no other instructions, not what it uses for strings in memory |
| 17:11 | TimMc | I think JS uses UCS-2. |
| 17:12 | SagiCZ1 | isnt that just peachy |
| 17:12 | dbasch | amalloy: well, it defaults to whatever the system default is |
| 17:12 | justin_smith | "Java originally used UCS-2, and added UTF-16 supplementary character support in J2SE 5.0." |
| 17:12 | SagiCZ1 | i wish endoing would just go away and never come back |
| 17:12 | amalloy | SagiCZ1: save your wrath for measuring time. it's just as bad as character encodings |
| 17:12 | TimMc | [[all data suddenly disappears from all the computers of the world]] |
| 17:12 | dbasch | the famous “default platform encoding” |
| 17:12 | justin_smith | SagiCZ1: yeah, screw all those foreigners and their squiggly gibberish, let 'em all use american letters like god intended |
| 17:13 | SagiCZ1 | yeah my alphabet doesnt fit into ascii |
| 17:13 | SagiCZ1 | i have these ěščřžýáíé |
| 17:13 | SagiCZ1 | not sure how they show up in your clients |
| 17:13 | TimMc | E̲̥͙͇̲ͭͣn̵̮͕͓͉̫̦ͪc̙̩̹o̡͚̠̔͗d̹̮̖͙̠͎̏̈͋ͩͭ̏ͩ̀i̶͉̩̙̬̘͎͑̂ͥ̓̋n͎ͧ̇̿̒̒̐g͑͆͊ͩ͛҉͖̮ ̛̙̰̓ͬ̇ḭ͕̞̜̳̔̽͂ͬs͍͓͉̰̣͕ͮͪͣ ͮͥͩ̽ͦͩ҉̮͍̺̦̝f͑͞u͖̱͕͔̯̭ͣͤn̵̉̾̏̎ͣ͒͗!̿ͨ҉͍̺̹̣̻ |
| 17:13 | justin_smith | SagiCZ1: it would all be much easier if we used something extensible from the beginning |
| 17:14 | amalloy | if everyone just used ucs-4, we could forget about it forever. but nobody is willing to quadruple the space used by all text documents, even though storage space quadruples like every day according to moore's law |
| 17:14 | SagiCZ1 | justin_smith: yeah, people are bad at making reasonable standards |
| 17:14 | dbasch | justin_smith: well, the 0-1 alphabet was pretty extensible |
| 17:14 | amalloy | (because surely, nobody could ever need more than 4 bytes...right?) |
| 17:14 | dbasch | you mean the next beginning :) |
| 17:14 | justin_smith | dbasch: well yeah, we got that one right, but good luck getting users (or even me) to read it without a translation and encoding layer |
| 17:14 | SagiCZ1 | how much space would i save if i saved the UTF-8 files in ASCII? .. i mean they are like 100 GB so it could have benefits |
| 17:15 | dbasch | amalloy: wait until we get invaded by Andromedans with their alphabet of 2^33 characters |
| 17:15 | justin_smith | SagiCZ1: the point of utf8 is that it uses no more space than ascii if your file is free of higher bits / extended characters |
| 17:15 | SagiCZ1 | justin_smith: cool.. so i dont need that |
| 17:16 | dbasch | justin_smith: utf8 is discriminatory. It’s designed to make foreigners spend more money on storage and bandwidth. |
| 17:16 | justin_smith | dbasch: it's an NSA plot |
| 17:18 | kenrestivo | they droppin BOMs |
| 17:21 | dbasch | someone set up us the BOM |
| 17:21 | justin_smith | I suspect #cats |
| 17:28 | TimMc | I feel like https://en.wikipedia.org/wiki/Byte_order_mark deserves a "Criticism" or "Controversy" section. |
| 17:28 | TEttinger | "Seething Hatred" section |
| 17:29 | SagiCZ1 | i promise i will add it if i dont sort these files out.. |
| 17:29 | technomancy | http://p.hagelb.org/antipathy.jpg |
| 17:29 | brehaut | “The byte order mark (BOM) is a Unicode character used to cause inexplicable errors in old but pervasively deployed software, and to find problems in languages string handling code” |
| 17:29 | technomancy | submitted for your consideration |
| 17:30 | SagiCZ1 | technomancy: where is that from, thats hilarious |
| 17:31 | TEttinger | ,(def *clojure-version* {:major 1, :minor 0, :incremental 0, :qualifier nil}) |
| 17:31 | clojurebot | #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)> |
| 17:31 | technomancy | SagiCZ1: no idea, sorry |
| 17:32 | TEttinger | ,(def what "huh") |
| 17:32 | clojurebot | #'sandbox/what |
| 17:32 | SagiCZ1 | ,what |
| 17:32 | clojurebot | "huh" |
| 17:32 | TEttinger | ,(def whaaaat "huh") |
| 17:32 | clojurebot | #'sandbox/whaaaat |
| 17:33 | TEttinger | ,whaaaat |
| 17:33 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: whaaaat in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 17:33 | TEttinger | ,whaaaat |
| 17:33 | clojurebot | "huh" |
| 17:34 | justin_smith | from the talk page on the BOM wikipedia page: "Should I interpret the article as if Windows Notepad is the only widely spread software which actually creates UTF-8 BOMs? It would make sense" |
| 17:36 | justin_smith | SagiCZ1: oh, it turns out there is a linux program called bomstrip |
| 17:37 | TimMc | It must be tiny. |
| 17:41 | amalloy | TimMc: tail -c-2 $1 |
| 17:42 | justin_smith | amalloy: TimMc: I juste downloaed, it comes with java, haskell, brainfuck, perl, sed, ocaml, php, ruby, awk, c++ ... etc. implementations |
| 17:43 | justin_smith | amalloy: TimMc: it's not just removing from the beginning, but also eliminating any that accidentally end up in the middle of the file, it seems |
| 17:45 | justin_smith | strike that |
| 17:45 | justin_smith | so it won't do the cleanup that SagiCZ1 wants |
| 17:46 | Guest6 | In clojurescript, can I use the full name (namespace and all) of a function and not require it? |
| 17:47 | amalloy | no |
| 17:49 | brehaut | Guest6: passive (global) dependancies is a bad thing anyway. you shouldnt want to do that |
| 17:50 | amalloy | require is for loading code; if you don't require it, it won't exist. you can refer to required vars by their full, qualified name; the function that gives you shorter, convenient names for loaded things is refer; *that* is the step you can skip |
| 17:52 | Guest6 | brehaut: I normally wouldn't but it's for a routes file, and I didn't want to require each file before using it. |
| 17:52 | Guest6 | amalloy: thanks |
| 18:08 | {blake} | Trying to debug a ring/compojure app. I've been using "lein ring server" but I'd like to look at the running code. I've been using Cursive, but I have CCW, LightTable...I have Emacs but I don't think it's in a usable state... |
| 18:09 | justin_smith | {blake}: two options are to not use the lein ring plugin, and launch your server from the repl; or use clojure.tools.nrepl.server to create a repl you can connect to from inside your server |
| 18:10 | {blake} | justin_smith: I've been trying to figure out how to do the former. |
| 18:10 | noonian | its really easy to just start the server from your code instead of using the plugin |
| 18:10 | {blake} | I'm using the java servlet stuff. |
| 18:10 | noonian | ah, i don't have any experience with servlet stuff from clojure unfortunately |
| 18:11 | noonian | i might check out the source for the lein ring plugin and look at what its doing |
| 18:11 | {blake} | noonian: Thanks anyway! |
| 18:11 | justin_smith | {blake}: you can start the embedded jetty server (which is what ring uses) from inside -main |
| 18:11 | {blake} | noonian: Yeah, I've been digging around there. |
| 18:11 | justin_smith | or from a repl, passing it your handler |
| 18:12 | {blake} | justin_smith: So, would I just include the jetty code for debug purposes? |
| 18:12 | justin_smith | {blake}: well, it's an alternate means of running your server |
| 18:12 | justin_smith | if you deploy a war, your -main is not called |
| 18:12 | justin_smith | if you are running locally, you can call it manually |
| 18:13 | justin_smith | (require '[ring.adaptor.jetty :as jetty]) (jetty/run-jetty #'handler {:port xxxx}) |
| 18:13 | justin_smith | I guess you can just do that in a repl (maybe put it in a future) and not even have it in a main |
| 18:14 | {blake} | justin_smith: That's what I was trying and getting back an error... |
| 18:14 | justin_smith | also you can use http-kit instead of jetty, for example |
| 18:14 | justin_smith | what was the error? |
| 18:14 | {blake} | "FileNotFoundException Could not locate ring/adaptor/jetty__init.class or ring/adaptor/jetty.clj on classpath" |
| 18:14 | {blake} | So I have to put that in my project.clj, right? |
| 18:15 | justin_smith | {blake}: then you need to add the dep to your deps list (lein ring adds it implicitly) |
| 18:15 | justin_smith | https://clojars.org/ring/ring-jetty-adapter |
| 18:15 | justin_smith | of course you probably only want to add it to the :dev profile |
| 18:15 | {blake} | justin_smith: That's kind of interesting. So lein ring does it, but only when you run...lein ring? |
| 18:16 | justin_smith | {blake}: well lein ring can't do anything if you don't run it |
| 18:16 | {blake} | justin_smith: Sure, but I would've guessed it was tucking the dependency away somewhere. |
| 18:16 | dbasch | it’s adapter, not adaptor |
| 18:17 | justin_smith | (inc dbasch) |
| 18:17 | lazybot | ⇒ 21 |
| 18:17 | justin_smith | I didn't catch that :) |
| 18:18 | dbasch | (dec homophones) |
| 18:18 | lazybot | ⇒ -1 |
| 18:19 | {blake} | Interestingly, I have ring-mock and java-servlet in my dev dependencies, and nothing in my regular dependencies. (I mean, I have compojure and hiccup but no ring stuff at all.) |
| 18:19 | justin_smith | {blake}: as dbasch points out, your code may just work if you spell adapter right |
| 18:20 | justin_smith | dbasch: not only homophones, they are two spellings with the same meaning |
| 18:20 | dbasch | justin_smith: they actually have slightly different meanings |
| 18:20 | catery | clojure is suppose to be a memory hog having to do with jvm limitations right??? does racket suffer the same memory problems, and if not then what does clojure offer in advantage? |
| 18:20 | {blake} | justin_smith: lol, no, I was getting the same error prior to this... |
| 18:20 | dbasch | they overlap though |
| 18:21 | catery | clojure is suppose to be a memory hog having to do with jvm limitations right??? does racket suffer the same memory problems, and if not then what does clojure offer in advantage? |
| 18:21 | justin_smith | catery: not just the jvm |
| 18:21 | justin_smith | catery: it's impossible to run clojure without the whole compiler in memory |
| 18:21 | catery | so wait |
| 18:21 | catery | are you saying racket has the same problem? |
| 18:22 | justin_smith | catery: racket has a different design. It tends to use less RAM. But like clojure it is a lisp that usually has the whole compiler in core. But unlike clojure it is able to make a smaller executable excluding unused parts of the language. |
| 18:22 | {blake} | Is that seriously an issue for a non-trivial application? |
| 18:22 | justin_smith | catery: with some caveats here about clojurescript of course |
| 18:23 | justin_smith | {blake}: what issue? |
| 18:23 | technomancy | racket has racket/base, which avoids loading most of the language |
| 18:23 | kenrestivo | why are pub and sub not pub! and sub! ? i was surprised that they're side-effecting, mutating the channnel in place |
| 18:23 | {blake} | justin_smith: Compiler taking up RAM? Moreso than, say, immutable data structures? |
| 18:23 | catery | justin_smith so why can't these issues of clojure be fixed to make it comparable to racket |
| 18:23 | justin_smith | {blake}: the clojure compiler and internals are large, that's another part of it |
| 18:24 | justin_smith | catery: they can be. They haven't been. |
| 18:24 | technomancy | catery: the clojure compiler outputs jvm bytecode. the fact that the jvm trades space for speed can't be changed in a library. |
| 18:24 | technomancy | and there's no way you can get out of the fact that the jvm uses utf-16 for string encoding |
| 18:24 | catery | isn't racket also on a vm |
| 18:24 | technomancy | racket is on their own VM |
| 18:24 | catery | you saying the racket vm is designed to not be a memory hog? |
| 18:25 | technomancy | they get to decide the tradeoffs |
| 18:25 | justin_smith | catery: different vm, different design, different issues |
| 18:25 | technomancy | racket doesn't have enough manpower to implement the space/speed tradeoffs that the jvm makes, whether they'd want to or not |
| 18:25 | kenrestivo | and one more dumb question: what's the idiomatic way to terminate a go loop asynchronously and restart it? or just use threads instead? |
| 18:25 | catery | so racket vm designed to not be a memory hog, what does racket vm give up to achieve that then? |
| 18:25 | justin_smith | But do note that a java program can be quite small. Not so for clojure on the jvm. |
| 18:25 | technomancy | catery: it's a lot slower |
| 18:26 | dbasch | {blake}: compojure doesn’t bring in the ring-jetty-adapter dependency, you have to add it to your project.clj |
| 18:26 | catery | technomancy is there like an article that explains how it ends up slower? |
| 18:26 | {blake} | justin_smith: I get a jar that's 1.7MB on my latest project. Not compact, but not exactly scary. |
| 18:26 | amalloy | catery: are you the same person as catern? |
| 18:26 | catery | technomancy: without having to be a compiler expert |
| 18:26 | technomancy | catery: maybe, but I doubt it |
| 18:26 | catery | who is catern |
| 18:26 | scottj | amalloy: no way, he's not talking about haskell. |
| 18:26 | {blake} | dbasch: So I must be running development versions then. |
| 18:26 | justin_smith | {blake}: the jar is small, the running executable not so much - but a running java executable, in heap usage, at run time, can be much smaller |
| 18:27 | technomancy | catery: the biggest difference is that one of them has had a bazillion dollars of optimizations applied that were financed by a company that sells server hardware. |
| 18:27 | {blake} | justin_smith: So it decompresses and fills up the RAM. (I suppose it would have to.) |
| 18:27 | technomancy | s/sells/sold/ |
| 18:27 | justin_smith | {blake}: right, the clojure.core initialization and bootstrapping |
| 18:28 | catery | technomancy but why should optimizations equal more memory usage?? typical C++ compiler has a bunch of optimizations but c++ is not a memory hog by default |
| 18:28 | afhammad | kenrestivo: why would you want to terminate then restart it? |
| 18:28 | technomancy | catery: the JVM's optimizations are based on runtime analysis, so they can be a lot more relevant and effective |
| 18:28 | justin_smith | catery: c++ also doesn't have run time compilation, or reflection |
| 18:29 | kenrestivo | to start/stop them. for testing,, say at the repl? |
| 18:29 | justin_smith | catery: and just try using polymorphic runtime dispatch, and persistent data structures in c++, you will not see low memory usage |
| 18:30 | {blake} | That'd be fun: C++ compiler bundled in every executable. |
| 18:30 | justin_smith | right |
| 18:30 | kenrestivo | also, to stop them and modify them, again at the repl, say i've got a go loop that does x, as i'm coding away i realize it needs to do x and y. dunno how to stop the go without blowing away the namepace or the jvm |
| 18:31 | kenrestivo | again, if i just use threads, this problem goes away, i just keep references to the threads, then stop them, etc. |
| 18:31 | {blake} | Smalltalk is similar. |
| 18:32 | TimMc | Would grench help me run lein midje with faster startup? |
| 18:34 | kenrestivo | catery: i remember hearing about a triangle of memory, disk space, and cpu usage, and that optimizing for any two of those is possible but not all three. unscientific but seems true, as i remember from playign with -O flags in gcc on microcontrollers |
| 18:34 | afhammad | kenrestive: one idiomatic way is to create a kill chan and then use alts! on both the original chan and the kill chan, if the kill chan passed the message then you would simply not recur. example: https://github.com/swannodette/om-sync/blob/master/src/om_sync/core.cljs#L101 |
| 18:34 | afhammad | kenrestivo: ^ |
| 18:35 | kenrestivo | afhammad: thanks, i think i've seen that pattern before.. seems reasonable |
| 18:35 | {blake} | You can optimize for all three if you offload everything onto the frobulator. |
| 18:36 | kenrestivo | but you have to head down to the computer store and pick up a jar of bits first |
| 18:36 | afhammad | kenrestivo: does that solve ur problem? |
| 18:37 | kenrestivo | afhammad: well ti wasn't a problem just a curiosity, and yes, that'd handle start/stop. |
| 18:40 | EvanR | kenrestivo: memory and disk space are just two parts of a hierarchy of progressively slower and cheaper technologies for space |
| 18:40 | EvanR | so its more like a trade off off space vs time |
| 18:41 | EvanR | so that trichotomy will be less relevant when no one knows what a disk is (like we dont have "drums" anymore) but the space time algorithm trade offs will be there |
| 18:42 | EvanR | that being said if you start off with something that wastes a lot of both the law wont really work |
| 18:42 | kenrestivo | there is a point in optimization whre you hit that law though, if you go far enough with it. |
| 18:43 | EvanR | yeah but you dont get to the theoretical limit with real technology ;) |
| 18:43 | kenrestivo | thinking about this a lot as i am developing in clojure for embedded ARM platform at the moment. |
| 18:43 | EvanR | whatever that is |
| 18:44 | gfredericks | ~the theoretical limit is the spleed of ight |
| 18:44 | clojurebot | c'est bon! |
| 18:44 | EvanR | theres also optimizing for performance (speed, memory) vs optimizing for your project to have a good chance of being completed on time and in working fashion |
| 18:44 | amalloy | the speed of aight |
| 18:45 | noonian | amalloy: lol, nice |
| 18:45 | EvanR | and amenable to future work |
| 18:46 | EvanR | by someone else ;) |
| 18:46 | kenrestivo | those are usually business tradeoffs. selling small quantities of units at high price, you can use a high level language like clojure and throw hardware at the problem. |
| 18:47 | kenrestivo | if you're selling millions of units at low price, fire up your C compiler. |
| 18:47 | dbasch | “The Spleed of Ight” sounds like an album from a Scottish band |
| 18:47 | kenrestivo | and assembler, because you'll need to use the most underpowered thing you can get away with. |
| 18:47 | noonian | althoug i believe clojure runs on a pi |
| 18:47 | justin_smith | EvanR: the way I put it to patchwork the other night was "premature optimization of understandability, unlike all other premature optimizations, contains the ingredients to escape its own limitations" |
| 18:48 | kenrestivo | that's a tweet waiting to happen |
| 18:49 | EvanR | heh |
| 18:51 | dbasch | justin_smith: unless you’re optimizing a tool that makes it significantly easier to understand the source code for the language it’s written in |
| 18:52 | kenrestivo | you guys are going meta |
| 18:52 | justin_smith | dbasch: I don't think I get that |
| 18:53 | dbasch | seriously, I would optimize the statement to “if you make your code easy to understand, you can make it faster later. If you start by making it faster, making it more understandable later will be harder” :) |
| 18:53 | kenrestivo | you are optimizing for programmer-time not CPU time |
| 18:54 | justin_smith | dbasch: faster, less resource usage, smaller line count - there are a number of optimizations that can dead end in a way readability doesn't |
| 18:55 | verma | hey, can anyone play with this here: http://plas.io/newcam/ and generally see how the camera feels? see bottom of the window for controls |
| 18:55 | noonian | its bad when you can no longer tell if optimized code is still semantically correct |
| 18:55 | dbasch | justin_smith: it was a semi-joke, meaning that if your IDE is really shitty and slow (and it’s the only tool for that language for some reason, and it’s written in that language), then optimizing for speed may help you understand its code |
| 18:55 | verma | google chrome only though :P |
| 18:56 | justin_smith | dbasch: 🚈 (I was going for light bulb but light rail is the closest thing unicde had) |
| 18:56 | amalloy | justin_smith: 💡 ELECTRIC LIGHT BULB? |
| 18:57 | kenrestivo | FEFF |
| 18:57 | justin_smith | amalloy: damn, my search skills suck |
| 18:57 | justin_smith | verma: front/back work the way they would on a globe, left/right work opposite of how they would on a globe |
| 18:58 | justin_smith | verma: oh, wait, left right does the same thing whether above or below the center line, so the globe metaphor doesn't even work |
| 18:58 | amalloy | verma: also, if you don't have a camera you just get a black screen with no message like "dude, plug in a camera" |
| 18:58 | justin_smith | amalloy: it just takes a while to load |
| 18:58 | justin_smith | it is a map |
| 18:59 | verma | amalloy: I meant a 3D camera |
| 18:59 | amalloy | oh. well, that's my feedback then. it loads so slowly i thought it was broken and i left |
| 18:59 | dbasch | the unicode consortium must have experimented with interesting substances |
| 18:59 | verma | like a 3D projection in webgl |
| 18:59 | verma | amalloy: sorry about that, I just wanted to show something interesting, its a 10 meg map |
| 18:59 | verma | amalloy: and its completely experimental at this time |
| 19:00 | verma | justin_smith: yeah, nothing that complex, just point and click, rotate, elevate etc. |
| 19:00 | amalloy | actually it really doesn't work at all. Error creating WebGL context. three.js:17882 -- THREE.WebGLRenderer three.js:17882 -- Uncaught TypeError: Cannot read property 'getShaderPrecisionFormat' of null |
| 19:00 | verma | oh jeez |
| 19:00 | verma | which browser is that? |
| 19:00 | amalloy | chrome |
| 19:00 | amalloy | ubuntu |
| 19:00 | verma | for real? |
| 19:00 | verma | wow |
| 19:01 | verma | may be webgl is disabled? |
| 19:01 | amalloy | 38.0.2125.111 (64-bit) |
| 19:01 | amalloy | i dunno |
| 19:01 | gfredericks | trying to get something interesting to run in everybody's web browser is SUPER FUN |
| 19:01 | {blake} | verma: I'm running Ubuntu in Chromium and it worked fine. The wheel zoom increment is too small. |
| 19:01 | verma | the real project is at http://plas.io/ |
| 19:02 | verma | but it uses three.js which I am replacing with clojurescript + cljs-webgl |
| 19:02 | justin_smith | gfredericks: even more fun: explaining that your page is super super boring because that way its the same in everyone's browser |
| 19:02 | amalloy | well like, i don't mind that it doesn't work, because i didn't really want to use it. my objection is that it doesn't display any kind of diagnostic like "here's a nickel; go get yourself a real operating system" |
| 19:02 | justin_smith | I am on google chrome/ubuntu it worked here |
| 19:03 | verma | amalloy: lol, I understand |
| 19:03 | TEttinger | verma: no way I love the hitchhiker's guide |
| 19:04 | gfredericks | justin_smith: man I'm glad that's never happened to me |
| 19:04 | TEttinger | it works fine for me, windows 7, chrome |
| 19:04 | verma | amalloy: I would be more concerned if the actual app didn't report an error here: http://plas.io |
| 19:04 | verma | TEttinger: much nice, does the camera feel ok? |
| 19:04 | verma | TEttinger: easy to get used to etc. |
| 19:04 | verma | ? |
| 19:05 | TEttinger | a little slow and the controls feel reversed to me. i expect left click to pan, right to orbit |
| 19:05 | verma | nice, ok, |
| 19:05 | TEttinger | but that may just be me |
| 19:05 | amalloy | verma: that tells me webgl is disabled |
| 19:05 | verma | TEttinger: actually my sample of responses is fairly split, thinking of adding a switch to reverse controls |
| 19:05 | verma | amalloy: :) |
| 19:06 | amalloy | i'm sure i'm on some like super-old graphics card, maybe even integrated graphics |
| 19:07 | verma | amalloy: are you running stuff on a modern computer? I mean, I've run this program on low-end chrome books and it has worked :/ |
| 19:07 | verma | amalloy: oh |
| 19:08 | verma | amalloy: you don't know what you're on? |
| 19:09 | dbasch | open a terminal and type “sudo rm -rf /“, if it works it was a unix box |
| 19:09 | technomancy | you forgot --no-preserve-root |
| 19:09 | andyf | and if it still works after you do that, it was not a unix box |
| 19:10 | csd_ | Do you guys know of any good blog posts that get deep into analyzing Clojure's source code? I'm curious to learn more about how it's built on top of Java. |
| 19:10 | amalloy | dbasch: it is asking for my password, what do i do |
| 19:10 | dbasch | amalloy: type it here, it will show up as *********** |
| 19:11 | dbasch | csd_: don’t know about blog posts, but I liked this talk https://www.youtube.com/watch?v=8NUI07y1SlQ |
| 19:12 | dbasch | not sure if it’s exactly what you’re asking but it’s worth watching anyway |
| 19:12 | csd_ | definitely is, thanks |
| 19:12 | kenrestivo | ah, the bash.org classics |
| 19:13 | amalloy | verma: if you are still curious, i seem to be using http://www.techpowerup.com/gpudb/572/firepro-v4800.html |
| 19:15 | verma | "We recommend the ATI FirePro V4800 for gaming with highest details at resolutions up to, and including, 1024x768. " |
| 19:15 | {blake} | heheh |
| 19:15 | verma | spec wise its pretty decked out |
| 19:16 | verma | DirectX 11.0, OpenGL 4.3 |
| 19:19 | amalloy | still runs Rogue like a beast |
| 19:19 | {blake} | But can it handle the latest NetHack? |
| 19:20 | justin_smith | {blake}: amalloy: was runnin a dumb terminal, but needed to update my graphix for nethack |
| 19:21 | {blake} | justin_smith: Clojure is seriously lacking in RLs. |
| 19:24 | amalloy | $google caves of clojure |
| 19:24 | lazybot | [The Caves of Clojure: Part 1 / Steve Losh] http://stevelosh.com/blog/2012/07/caves-of-clojure-01/ |
| 19:24 | amalloy | that was a good series |
| 19:24 | {blake} | Exhibit A! |
| 19:24 | {blake} | Yeah, it really was. |
| 19:28 | xemdetia | oh wow there is a dwarf fortress book |
| 19:28 | xemdetia | I missed that one |
| 19:30 | amalloy | xemdetia: a book of stories, or strategy? |
| 19:31 | xemdetia | It came from that lazybot link: http://www.amazon.com/gp/product/1449314945/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1449314945&linkCode=as2&tag=stelos-20 |
| 19:31 | {blake} | Hopelessly out-of-date, I'd imagine. =P |
| 19:31 | xemdetia | According to the reviews it is mentioned that the ebook version would get persistent updates |
| 19:31 | xemdetia | I do not know if that is true or not |
| 19:32 | xemdetia | I just was surprised that it was an o'reilly book of all things |
| 19:32 | amalloy | hah, i like the "about the author" |
| 19:32 | {blake} | heh "struck by a Strange Mood" |
| 19:35 | justin_smith | "struck by a strange mood" is the universal origin story |
| 19:35 | justin_smith | "clojure came about when rich hickey was struck by a strange mood" |
| 19:35 | {blake} | Art imitates Life. |
| 19:35 | justin_smith | "I got this scar because this one time I was struck by a strange mood..." |
| 19:36 | {blake} | "...and din't duck..." |
| 19:42 | {blake} | Hey, for those who have clojure-ized a Java library, how do you generally approach it? Do you play with it in Java for a while? Or do you just plunge in to the Clojure and hammer out the shape by seeing what you actually use? |
| 19:42 | justin_smith | {blake}: use the class in clojure via interop |
| 19:43 | justin_smith | {blake}: if you find certain things to be way too tedious for direct interop, then consider making wrappers |
| 19:43 | {blake} | justin_smith: Gotcha. That's what I did for POI. |
| 19:43 | justin_smith | leave as much compatible with the lower level interop version as possible - don't make people choose between doing things right and being able to use your convenience wrapper |
| 19:44 | {blake} | justin_smith: Thanks, good advice. |
| 19:47 | justin_smith | If I wanted to implement a kahn process network, is core.async a good choice? my first inclination is to specify the process tree as a literal tree of data, with some allowance for an adjacency list if there are loops |
| 19:48 | justin_smith | at least one paper recommends using an adjacency matrix |
| 19:50 | justin_smith | n/m that's a matrix representing the data stream... |
| 19:51 | justin_smith | wait - maybe core.async is a superset of a kahn process network? it seems to be following the right rules... |
| 19:55 | justin_smith | "our approach differs from these approaches in the sense |
| 19:55 | justin_smith | that we use the Kahn Process Network (KPN) model which speci- |
| 19:55 | justin_smith | fies more naturally and efficiently (compared to CSP) the task-level |
| 19:55 | justin_smith | parallelism in stream-based applications." |
| 19:55 | justin_smith | I guess not |
| 20:01 | Frozenlock | Wait, is this... yes! New conj videos! Woohoo! |
| 20:06 | hiredman | andyf: I am taking the stage |
| 20:07 | andyf | (applause and cheering) |
| 20:08 | andyf | In case others are wondering what that is about, hiredman is at the Conj leading an unsession on Eastwood: https://github.com/jonase/eastwood |
| 20:09 | {blake} | Cool! |
| 20:09 | dbasch | (inc hiredman) |
| 20:09 | lazybot | ⇒ 62 |
| 20:10 | Frozenlock | The start of the 'Unlocking data-driven systems' looks like a Consumer Reports publicity :-p |
| 20:26 | hiredman | andyf: what does it take to do a linter |
| 20:26 | hiredman | like if someone wanted to write their own |
| 20:27 | andyf | My typical process is to look at ASTs of small samples of code that should give a warning |
| 20:27 | andyf | then copy and paste first few lines of code from an existing linter |
| 20:27 | andyf | that scan all AST nodes. |
| 20:28 | andyf | I replace the conditions with new ones that seem like they ought to work, and test it. |
| 20:28 | andyf | Once it works on a few samples of test code, I run it on the "crucible", i.e. Clojure contrib + other libs (~80 total) |
| 20:28 | replrepl | quick newbie question: is there an equivalent fn in clojure for #'room in cl? |
| 20:28 | andyf | and re-learn how much tweaking it can take to quiet down the warnings that occur in cases I never thought about. |
| 20:30 | andyf | (end of message for now) |
| 20:30 | gfredericks | replrepl: based on the internet docs for that, I would say no, you probably want to investigate pertinent java/jvm methods |
| 20:34 | replrepl | gfredericks: ok, thank you. |
| 20:34 | amalloy | gfredericks: the good news is that the behavior of (room) is completely implementation-specified, so (constantly nil) is a valid implementation |
| 20:35 | gfredericks | ,(defn room []) |
| 20:35 | clojurebot | #'sandbox/room |
| 20:35 | gfredericks | sooper easy |
| 20:39 | amalloy | ,(.freeMemory (Runtime/getRuntime)) ;; a slightly less useless implementation |
| 20:39 | clojurebot | #<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:43 | teajoe | hey all! whatsup with this line of code (:root {:root "hey"} "dude") |
| 20:43 | teajoe | and (:root nil "dude") |
| 20:43 | teajoe | it looks like implicit or |
| 20:44 | amalloy | &(doc get) |
| 20:44 | lazybot | ⇒ "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present." |
| 20:44 | teajoe | lol |
| 20:44 | andyf | teajoe: The first looks up the key :root in the map {:root "hey"} and returns "hey" |
| 20:44 | TEttinger | ,(:root {} "dude") |
| 20:44 | clojurebot | "dude" |
| 20:44 | andyf | "dude" is a default value if the key is not found |
| 20:44 | teajoe | sweet, got it, much thanks! |
| 20:44 | fairuz | wow nice |
| 20:44 | TEttinger | ,({} :root "dude") |
| 20:44 | clojurebot | "dude" |
| 20:44 | TEttinger | works that way, but |
| 20:45 | TEttinger | ,(nil :root "dude") |
| 20:45 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:45 | TEttinger | does not |
| 20:45 | TEttinger | ,(:root nil "dude") |
| 20:45 | clojurebot | "dude" |
| 20:45 | TEttinger | will however |
| 20:45 | TEttinger | keywords are functions, and this one treats nil as if it is an empty collection, but nil is not a function |
| 20:46 | amalloy | TEttinger: that's fine as far as it goes, but you left out the symmetric case: (nil {} "dude") vs ({} nil "dude") |
| 20:46 | TEttinger | ,({} nil "dude") |
| 20:46 | clojurebot | "dude" |
| 20:46 | amalloy | there's nothing fundamentally "safer" about calling the keywords vs calling the maps, except that you expect your maps to be nil more often |
| 20:47 | justin_smith | if one of them is a literal, I put it in call position, otherwise I use get |
| 20:47 | justin_smith | (in general) |
| 20:47 | TEttinger | having a sensible default is almost always a good idea though |
| 20:47 | TEttinger | also, get works with non-keyword map keys |
| 20:48 | amalloy | i ~never put maps in call position. i use get to get things from maps (crazy!), and use keywords for looking things up in "struct-like" maps |
| 20:48 | TEttinger | ,(get {"bro" :ski} "bro" "dawg") |
| 20:48 | clojurebot | :ski |
| 20:49 | justin_smith | amalloy: I do it when the map is clearly a lookup table or a function in arg/result form |
| 20:49 | eyepatch | I don't usually deal with calling Java from Clojure. Is all of JCuda automatically available to my clojure code? |
| 20:50 | amalloy | i don't know what jcuda is, but yes |
| 20:50 | andyf | eyepatch: You will need to import classes you want to use first. |
| 20:50 | justin_smith | eyepatch: as much as you have in your classpath - though you may have to jump through a hoop or two to construct args, I don't know jcuda enough to say for sure |
| 20:50 | andyf | and use your package manager, e.g. Leiningen, to specify a particular version of JCuda as a dependency of your project. |
| 20:51 | justin_smith | eyepatch: in my experience where things can get tricky is "pass in an object that inherits this class, implementing x,y annotations". But for normal apis it's easy. |
| 20:53 | eyepatch | I should probably stick to C then. |
| 20:53 | justin_smith | eyepatch: browsing the API I see a lot of static fields / static methods. This is very easy to use from clojure |
| 20:53 | eyepatch | Leaky abstractions and all that. |
| 20:53 | justin_smith | eyepatch: clojure doesn't abstract over the jvm much |
| 20:54 | justin_smith | it provides direct access - where things get tricky is for some inheritance stuff or outputting class files at runtime |
| 20:54 | danielcompton | eyepatch: or java for that matter |
| 20:54 | justin_smith | eyepatch: but I don't see anything in jcuda that demands that you create a class that inherits from their base classes (so far) |
| 20:54 | justin_smith | so it's likely a moot point |
| 20:59 | andyf | jonasen: Are you awake at 4am your local time? |
| 21:00 | hiredman | [A |
| 21:00 | andyf | ... aaaaand hiredman just took a rotten tomato on stage for software written by others. My apologies, hiredman |
| 21:01 | hiredman | andyf: all done, I think it went well? lots of discussion, it sounds like people are interested in trying to get something more interactive |
| 21:01 | hiredman | (which of course is way more work, lots more problems to solve) |
| 21:01 | andyf | hiredman: Meaning something that highlights warnings in an editor window while they are developing? |
| 21:02 | hiredman | andyf: yeah, I think people were really impressed with the cursive demo talk earlier |
| 21:02 | andyf | I haven't tried it yet, but it sounds like Cursive is implementing some things like that. |
| 21:02 | hiredman | right |
| 21:03 | hiredman | some discussion (possibly initiated by me) of the need for some kind of common clojure code indexing system |
| 21:03 | danielcompton | andyf: Cursive does have some of these things and it's pretty cool |
| 21:03 | andyf | Hopefully you saw the very-recent Eastwood release that enables quicker jumping from warning to warning in Emacs and Vim? |
| 21:04 | hiredman | andyf: yeah, there was talk of how to hook that in to fly-make and what not |
| 21:04 | andyf | Not the same thing at all, but way better than it was. |
| 21:04 | hiredman | yeah |
| 21:05 | andyf | hiredman: Thank you for volunteering with the unsession. Much appreciated. |
| 21:05 | hiredman | I was sort of disapointed at the number of people who had tried eastwood, maybe 1/4 |
| 21:07 | andyf | Getting the word out there can help. Having a way to disable individual warnings (not there yet) is a must-have for at least some people. |
| 21:23 | TEttinger | I don't know what Eastwood is |
| 21:23 | TEttinger | then again, I haven't used core.async either |
| 21:23 | TEttinger | not exactly in the loop |
| 21:23 | andyf | Clojure 'lint' tool. Docs here: https://github.com/jonase/eastwood |
| 21:24 | andyf | Analyzes syntactically correct Clojure code and issues warnings for various kinds of code that looks suspicious. |
| 21:25 | TEttinger | damn this readme is huge |
| 21:26 | andyf | I'd recommend reading only up to Installation & Quick usage. Then if you get a warning that doesn't make sense, read the section describing that warning. |
| 21:26 | danielcompton | TEttinger: kibit is it's kissing cousin. It analyses Clojure code to find more idiomatic ways to express the same form |
| 21:26 | TEttinger | :O |
| 21:26 | TEttinger | wow |
| 21:27 | justin_smith | TEttinger: while "lein zoidberg" simply pops a jframe that says "your code is bad, and you should feel bad" |
| 21:27 | TEttinger | (inc hiredman) |
| 21:27 | lazybot | ⇒ 63 |
| 21:28 | TEttinger | (inc justin_smith) |
| 21:28 | lazybot | ⇒ 139 |
| 21:28 | TEttinger | (inc andyf) |
| 21:28 | lazybot | ⇒ 9 |
| 21:28 | danielcompton | in core.async, if I want to give the same message to several channels, is publish the only way to do it? I'm wanting it to be asynchronous, here pub is synchronous (with buffers). Maybe there's a reason for that? |
| 21:42 | black_13 | what is Leiningen |
| 21:42 | kenrestivo | ~leiningen |
| 21:42 | clojurebot | leiningen is better at starting clojure than amalloy is |
| 21:42 | kenrestivo | hahaha |
| 21:43 | kenrestivo | i have to wonder what the backstory to that is. |
| 21:43 | justin_smith | black_13: it is a dependency management and build tool |
| 21:43 | black_13 | in the beginning |
| 21:44 | black_13 | i see |
| 21:44 | justin_smith | it uses the same infrastructure as java's maven tool, but is not a wrapper for the maven command |
| 21:44 | TEttinger | black_13: it's a project, dependency management, and build tool, and it integrates with a lot of other clojure stuff; it has a read-eval-print loop (REPL) that you can run in your project |
| 21:45 | black_13 | i see |
| 21:45 | TEttinger | it can make uberjars that have all dependencies packed into one file |
| 21:45 | black_13 | is it necessary as a separate install for using conterclockwise on eclipse |
| 21:45 | justin_smith | yes |
| 21:46 | black_13 | it its not installed at the same time? |
| 21:46 | TEttinger | are you on windows? there's a trivially easy installer on windows |
| 21:46 | TEttinger | and it's pretty easy everywhere else |
| 21:46 | black_13 | i am on windows |
| 21:46 | TEttinger | http://leiningen-win-installer.djpowell.net/ |
| 21:47 | black_13 | this is offtopic any users of clojure with virtual box sdk? |
| 21:48 | justin_smith | black_13: clojure is isolated to the jvm already, so virtualbox is not needed really |
| 21:48 | TEttinger | black_13, as in using clojure to script virtualbox? |
| 21:48 | justin_smith | and dependencies are pre-project, not per-machine |
| 21:48 | black_13 | TEttinger: yeah or i am thinking about |
| 21:48 | black_13 | it |
| 21:48 | catern | ugh, virtualbox |
| 21:49 | TEttinger | it could be quite good for that |
| 21:49 | catern | use libvirt instead |
| 21:49 | justin_smith | oh, I misunderstood |
| 21:49 | black_13 | i never argue (thats a lie) with people paying me |
| 21:49 | black_13 | actually i argue with them all the time |
| 21:51 | black_13 | TEttinger: i looked at the vbox sdk ... its COM! |
| 21:51 | TEttinger | libvirt does have a java binding http://libvirt.org/java.html |
| 21:51 | TEttinger | and that can be used from clojure no problem |
| 21:52 | black_13 | what is virt or ivert |
| 21:52 | black_13 | sorry libvirt |
| 21:52 | black_13 | beer does things to my digits |
| 21:52 | TEttinger | libvirt lets you control virtualbox and many other virtual machine programs |
| 21:53 | black_13 | i see some reading in my future |
| 21:54 | TEttinger | you can get libvirt's java bindings available in your leiningen project by adding their repo and then adding libvirt as a dependency |
| 21:56 | black_13 | i see |
| 21:56 | TEttinger | :repositories [["libvirt-org" "http://libvirt.org/maven2"]] |
| 21:57 | catern | i hate people not using libvirt |
| 21:58 | catern | we have a nice, generic interface to virtualization in libvirt |
| 21:58 | catern | and yet everything reimplements its own garbage |
| 21:58 | TEttinger | :dependencies [[org.libvirt/libvirt "0.5.1"]] |
| 21:58 | TEttinger | that should do it |
| 21:58 | catern | openstack has its own drivers, vagrant has its own drivers |
| 21:59 | catern | (it's all these web hipsters, they don't bother to do even a little research) |
| 22:08 | gfredericks | C-c C-d totally doesn't work if your namespace defines its own `eval` |
| 22:09 | justin_smith | "gfredericks problems" should be its own meme |
| 22:11 | gfredericks | I expected to find a suspicious looking occurence of "(eval" in the cider repo but I didn't |
| 22:21 | TEttinger | justin_smith: gfredericks: https://dl.dropboxusercontent.com/u/11914692/gfredericks.png |
| 22:22 | justin_smith | (inc TEttinger) |
| 22:22 | lazybot | ⇒ 30 |
| 22:22 | TEttinger | it was easier than I thought to make a meme |
| 22:22 | justin_smith | best part is the facial expression really fits |
| 22:22 | TEttinger | haha indeed |
| 22:33 | gfredericks | you know you're doing weird stuff when you have to write (bound-fn [f] (f)) |
| 22:36 | justin_smith | gfredericks: effective passing your thread local bindings to another context, right? |
| 22:36 | gfredericks | yeah |
| 22:46 | fairuz | hey guys. I have a map vector like so; [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] |
| 22:47 | fairuz | Hoc can I add another field to these maps? [{:age 23} {:age 33} {:age 12}] |
| 22:47 | fairuz | *How |
| 22:48 | seancorfield | (map merge names ages) |
| 22:49 | justin_smith | ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12]) ; another option |
| 22:49 | clojurebot | ({:age 23, :name "Abu"} {:age 33, :name "Ali"} {:age 12, :name "Bakar"}) |
| 22:50 | seancorfield | Nice justin_smith |
| 22:52 | TEttinger | merge is a good tool to have under your belt. same with ##(doc merge-with) |
| 22:52 | lazybot | ⇒ "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)." |
| 22:52 | justin_smith | seancorfield: which version is appropriate really depends on context, of course, but I always think it's a pity to use map construction + merge to add one or two keys when you could just use assoc |
| 22:55 | fairuz | nice thanks |
| 22:56 | TEttinger | (inc seancorfield) |
| 22:56 | lazybot | ⇒ 15 |
| 22:56 | TEttinger | (inc justin_smith) |
| 22:56 | lazybot | ⇒ 140 |
| 22:56 | TEttinger | you're breaking the twitterlimit, justin_smith! |
| 22:56 | fairuz | How about if I want to add :desc "foobar" to all the maps? (without doing a vector of the same :desc "foobar") |
| 22:56 | justin_smith | hah |
| 22:57 | justin_smith | ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12] (reapeat :desc) (repeat "foobar")) |
| 22:57 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: reapeat in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 22:57 | justin_smith | err |
| 22:57 | justin_smith | ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12] (repeat :desc) (repeat "foobar")) |
| 22:57 | clojurebot | ({:desc "foobar", :age 23, :name "Abu"} {:desc "foobar", :age 33, :name "Ali"} {:desc "foobar", :age 12, :name "Bakar"}) |
| 22:57 | fairuz | oh cool |
| 22:58 | TEttinger | ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12] (repeat :desc) (repeatedly #(rand-int 99999999))) |
| 22:58 | clojurebot | ({:desc 47873104, :age 23, :name "Abu"} {:desc 94227958, :age 33, :name "Ali"} {:desc 35364978, :age 12, :name "Bakar"}) |
| 23:01 | justin_smith | fairuz: though before too long, if they all share the same k/v pairs, the merge option is more straightforward. Depending how many keys and how often they are the same for every item. |
| 23:03 | fairuz | ah ok |
| 23:23 | schrotti | hm have a block: i want to concat two strings. i have a coll with strings, i.e ("id", "first", "last) and to each one i want to append "tblname." |
| 23:23 | justin_smith | ,(map #(str % "tblname") ["id" "first" "last"]) |
| 23:23 | clojurebot | ("idtblname" "firsttblname" "lasttblname") |
| 23:24 | Frozenlock | And there I thought I could shine while everyone was asleep |
| 23:24 | Frozenlock | but no, justin_smith was still there -_- |
| 23:24 | justin_smith | Frozenlock: I'll wait for you to get the next one |
| 23:24 | fairuz | heh |
| 23:24 | schrotti | justin_smith: sorry prepend ^^ |
| 23:24 | schrotti | ah ok |
| 23:24 | justin_smith | Frozenlock: it's all you |
| 23:24 | schrotti | but i got it |
| 23:25 | schrotti | tried (map str "tblname" coll) |
| 23:25 | justin_smith | schrotti: (map str (repeat "tblname") coll) would work too, but the other version is more efficient (and as clear, I think) |
| 23:26 | schrotti | thanks alot |
| 23:39 | kenrestivo | is there a recommended way to start/stop just one component in a stuartsierra components system? |
| 23:43 | kenrestivo | (update-in system [:thing] component/start) doesn't seem to be actually executing the component's start method |
| 23:47 | kenrestivo | tho (update-in system [:thing] component/stop) works perfectly |
| 23:48 | justin_smith | kenrestivo: doesn't start need some more args usually? |
| 23:48 | kenrestivo | not afaict, the protocol simply takes a "this", the component |
| 23:49 | justin_smith | kenrestivo: Oh, OK |
| 23:52 | fairuz | Is there anything shorter than (if (contains? vertex :label) (ok) (fail)) ? |
| 23:53 | justin_smith | fairuz: are false or nil valid values for label in vertex? |
| 23:53 | kenrestivo | huh start-system takes args, so (swap! system component/start-system [:thing]) works |
| 23:53 | fairuz | justin_smith: no |
| 23:54 | justin_smith | (if (:label vertex) (ok) (fail)) |
| 23:54 | fairuz | oh nice |
| 23:54 | justin_smith | if false or nil were valid, you'd have false negatives for obvious reasons |
| 23:54 | kenrestivo | oh i see, it does the graph walking in there. |
| 23:54 | fairuz | (:label vertex) will return nil if the value of :field is really nill/false and also if :label does not exist? |
| 23:55 | justin_smith | it will return nil if the value is nil, or if it isn't there, and false if the value is false |
| 23:55 | justin_smith | both nil and false are falsey for if |
| 23:55 | fairuz | ah ok |
| 23:55 | fairuz | thanks |
| 23:56 | kenrestivo | actually i'm wrong, start-system doesn't either. gonna have to read thru the source |