#clojure log - Jan 02 2014

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:00 marcopolo`: http://bit.ly/1a2uY0C is the class I'm working with

0:00 Like a factory, but for itself

0:01 The method I'm talking about is getSocketFactory()

0:02 Could I make a wrapper class that has a constructor which calls that method?

0:02 Is there a way to subclass in clojure?

0:02 TEttinger: http://grepcode.com/file/repo1.maven.org/maven2/org.apache.httpcomponents/httpclient/4.1/org/apache/http/conn/ssl/SSLSocketFactory.java#SSLSocketFactory.%3Cinit%3E%28java.lang.String%2Cjava.security.KeyStore%2Cjava.lang.String%2Cjava.security.KeyStore%2Cjava.security.SecureRandom%2Corg.apache.http.conn.ssl.X509HostnameVerifier%29

0:02 it appears to have public constructors

0:02 gtrak: proxy can do it, genclass can do it.

0:02 TEttinger: just not no-arg constructors

0:03 marcopolo`, yeah, subclassing is definitely possible with proxy and genclass, maybe reify

0:04 gtrak: reify no

0:04 reify just handles clojure protocols and java interfaces

0:04 marcopolo`: TEttinger: ideally, I'd like to use to no-arg constructor.

0:05 I can override the constructor with gen-class/proxy?

0:08 TEttinger: http://clojuredocs.org/clojure_core/clojure.core/gen-class yes with gen-class

0:08 there's a :constructor section in there

0:11 marcopolo`: Thanks :)

0:19 danlentz: devn: y by namespace is ok so im past that hurdle. no i am strugling to get lein-autodoc to work

0:20 cmdline java-jar is fine

0:20 lein autodoc -> Exception in thread "main" java.lang.NoClassDefFoundError: lancet/core$WsdlToDotnet (wrong name: lancet/core$wsdltodotnet)

0:20 what the hell is a lancet?!

0:21 mullr: lancet |ˈlansit|

0:21 noun

0:21 1 a small, broad, two-edged surgical knife or blade with a sharp point.

0:21 2 a lancet arch or window.

0:21 • [ as modifier ] shaped like a lancet arch: a lancet clock.

0:21 danlentz: and why does autodoc need it?

0:21 it is certainly drawing blood :)

0:21 mullr: my dictionary doesn't know the answer to that

0:22 danlentz: ah hold on. lein autodoc is probably looking in ~/.m2

0:22 for the jar

0:22 ah.

0:22 tks sometimes it helps to just gripe and things become clear

0:22 :)

2:00 hydromet: hello, I'm a clojure newbie (and having a lot of fun getting to know it, using Light Table, and just recently purchased the O'Reilly book by Chas et al)

2:00 TEttinger: hy hydromet

2:01 *hi

2:01 arrdem: TEttinger: hipster

2:01 hydromet: I was listening yesterday to a presentation Rich gave several years ago to an audience of Java programmers and at one point Rich was describing macros

2:01 hello TEttinger!

2:02 TEttinger: arrdem: I did have a neckbeard before it was hip.

2:02 arrdem: TEttinger: I'm so sorry.

2:02 hydromet: Rich at one point said that one of the beautiful things about macros is that they can be used to extend the language of Clojure itself, giving programmers the same power as Rich himself (since Rich created Clojure)

2:02 * arrdem hates that we have people using so and also as nicks

2:03 hydromet: He also said this is a much better approach than having to beg and wait for Sun (this was before Sun was acquired by Oracle) to make changes to Java if someone wanted to extend Java

2:03 bbloom: arrdem: i also hate that, so annoying

2:03 hydromet: So here's what I don't understand ...

2:03 Since Clojure in and of itself is open source (Eclipse License), what would prevent someone from modifying Clojure regardless of using macros or otherwise?

2:04 arrdem: hydromet: modifying clojure to achieve what...

2:04 TEttinger: it's modifying in your code, rather than changing the compiler/reader

2:04 arrdem: hydromet: rebind a clojure.core symbol like +?

2:04 hydromet: add a Haskell typechecker? gotta give us more to work with here

2:04 hydromet: well Rich's point was that the power of macros is to syntactically change the language (I thought)

2:05 arrdem: eeeeh

2:05 TEttinger: https://github.com/technomancy/leiningen/blob/stable/project.clj#L4 here's an example. defproject isn't part of the language

2:05 arrdem: since we don't have reader macros I would disagree. macros add syntactic sugar, they can't alter the syntax of the language.

2:05 TEttinger: it was added by the leiningen code, but otherwise acts like defn

2:05 hydromet: I just didn't quite understand why he, in the context of talking about macros, said something about having to beg and wait for Sun (Oracle) to make changes to Java

2:05 arrdem: hydromet: link to the talk?

2:06 * arrdem digs for headphones

2:06 hydromet: arrdem: sure, one moment, let me find it

2:06 TEttinger: hydromet, well if you change java, your changes won't be usable by end users

2:06 or rather, if you change the JVM

2:07 hydromet: arrdem: http://www.youtube.com/watch?v=P76Vbsk_3J0

2:07 TEttinger: which is what apparently would be needed to, say, add lambdas to java

2:08 hydromet: TEttinger: but if you use a macro to change itself in Clojure, that doesn't mean your macro becomes available to end users does it? Do you mean end users who run the program (using JRE only, no JDK etc.)?

2:08 TEttinger: or do you mean available to the rest of the programming community?

2:09 arrdem: I'll try to find the point in that video where he says that, one moment please

2:10 arrdem: 1:13:00

2:10 TEttinger: no no, I mean, you could try to add defproject as a keyword to java, but it would take a change to the parser to have the java definition of defproject not try to evaluate the names inside. in clojure you can control what gets evaluated, like how if doesn't execute the branch that the condition doesn't lead to

2:10 hydromet: "what's beautiful about Clojure and Lisps ..."

2:11 arrdem: hydromet: mmkay hang on

2:11 TEttinger: hydromet, does that makes sense?

2:12 java's ability to control what gets evaluated/compiled is limited

2:12 clojure has pretty much full control

2:13 hydromet: arrdem: Rich says at about 1:13:00 "What's beautiful about Clojure and Lisps, you at the same power that I have to write macros"

2:13 arrdem: "You don't have to wait for me, I'm not Sun"

2:13 bingo! Why does Rich say this "I'm not Sun"?

2:14 arrdem: hydromet: so... do you understand how macros interact with the compiler?

2:14 TEttinger: when people wanted changes to core java features, they needed to wait for sun/oracle to make changes

2:14 hydromet: I don't write Java and don't understand enough about Sun / Oracle. I thought they had some weird not fully transparent licensing issues which is why Larry Ellison and Google ended up in a big court battle over Android's Dalvik "clean room" Java systems etc. (ugh)

2:15 arrdem: TEttinger: choose. [1,3] or [4,6]

2:15 Ember-: Sun Microsystems was aquired by Oracle few years back

2:15 there is no Sun Microsystems anymore

2:15 arrdem: Ember-: not helping...

2:15 TEttinger: arrdem: [[LInteger

2:15 arrdem: 1d2

2:15 clojurebot: 2

2:15 arrdem: okay.

2:16 TEttinger: he's yours.

2:16 * arrdem hits the sack

2:16 hydromet: arrdem: so clearly I have a gap in my newbie understanding of how Clojure macros work and what if anything this has to do with open source licensing (comparing to Sun/Oracle Larry Ellison et al)

2:16 TEttinger: heh

2:16 hydromet, it has to do with this

2:16 Ember-: hydromet: opensource licensing and clojure macros have absolutely nothing to do with each other

2:16 arrdem: hydromet: you are taking Rich too literally when he talks about extending the language.

2:16 hydromet: Ember: thanks

2:16 arrdem: ah!

2:16 Cr8: better phrasing

2:16 Ember-: macros are a language feature

2:17 TEttinger: java is written in a lower-level language, I think mostly C++. you can't extend the compiler in java.

2:17 Cr8: you are able to *add functionality* that would *normally* require a change to the language

2:17 TEttinger: clojure is mostly written in clojure

2:17 Cr8: without actually *having* to change the language

2:17 arrdem: hydromet: macros are a compiler structure which allow a programmer to express some operation in terms of compile time code generation not built into the language core

2:17 Ember-: clojure macros are comparable to C macros but they are way more powerful

2:17 TEttinger: not all, some parts are java or javascript (for cljs)

2:17 hydromet: TEttinger: that makes sense (not being able to extend the Java compiler, itself written in C++)

2:17 TEttinger: right, but macros go one step further

2:18 Ember-: the main difference between clojure macros and other clojure code is that clojure macros are executed on compile time

2:18 TEttinger: they expose the ability to change the compiler to code

2:18 Ember-: that results the macro code being replaced by the outcome of that macro code being executed and spitting clojure code out

2:18 thus the final clojure source code "file" which is compiled to .class files is different than what is sitting on your hard drive

2:18 TEttinger: yep

2:19 Ember-: this allows you to do stuff not otherwise possible

2:19 hydromet: Ember: I thought I heard Rich say (in that same presentation that I gave the link to) that Clojure macros should not be confused with simple C macros

2:19 Ember-: hydromet: indeed they shouldn't

2:19 TEttinger: they should not.

2:19 arrdem: hydromet: yes you did hear that, and they should not be

2:19 Ember-: clojure macros are way way more powerful

2:19 arrdem: hydromet: C macros are simple textual replace operations

2:19 hydromet: C macros are essentially about text substitution at compile time, no?

2:19 Cr8: yep

2:20 where as lispy macros are structural

2:20 arrdem: hydromet: Clojure and Lisp macros are full blown code execution for code generation

2:20 Ember-: with clojure macros you can modify clojure code on fly

2:20 arrdem: no no no you _WRITE_ code _WITH_ code

2:20 hydromet: Clojure macros are programs that ask the compiler to transform itself (something like that)?

2:20 Ember-: in clojure code is data and data is code

2:21 hydromet: macros are compile time execution rules

2:21 hydromet: Ember: this is definitely a foreign concept for me so I have to get my brain wrapped around it (I will definitely do so)

2:21 Ember-: clojure compiler works in two phases, first it executes the macros and then it compiles the resulting code into .class files

2:21 arrdem: Okay. Example?

2:21 TEttinger: hydromet, I wouldn't worry too much about macros at the new-user stage. 2 years in and I still haven't written (or needed to write) a defmacro. I anticipate I may soon.

2:21 hydromet: arrdem: I thought you were going to sleep? ;-)

2:22 seriously_random: question about cons: http://pastebin.com/vriyG8ps

2:22 Cr8: ,(clojure.walk/macroexpand-all '(-> 6 inc (/ 2)))

2:22 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk>

2:22 arrdem: hydromet: SOMEONE IS WRONG ON THE INTERNET

2:22 Cr8: aw

2:22 Ember-: and yesh, the first rule of the macro club is: you do not write macros

2:22 Cr8: &(clojure.walk/macroexpand-all '(-> 6 inc (/ 2)))

2:22 Ember-: :)

2:22 lazybot: ⇒ (/ (inc 6) 2)

2:22 Cr8: no that guy is not here

2:22 hydromet: arrdem: huh?

2:22 Cr8: oh yes he is

2:22 logic_prog: in clojurescript, how do I encode HTML encode strings? i.e. "<->" into a literal "<->", rather than be interpreted as a tag

2:22 Ember-: the main reason for this is the fact that macros get really confusing really fast if not used properly

2:23 and most of the time just plain functions are a better solution

2:23 oakwise: dnolen: am I wrong that om/build-all with a transforming :fn will always update all of the items because identity is changing? E.g. I've got a large list of titles that I want to live filter using a search input. The :fn does `(assoc item :hidden true)` when item is filtered out, which causes all hidden items to be updated at every update to the search input. Am I doing it wrong? Does the hidden attribute have to be part of the item's sta

2:23 for this to work correctly?

2:23 hydromet: TEttinger: Indeed, your suggestion of not needing to tackle macros as a newbie sounds wise, and in that video I think Rich mentioned that its probably not apt for a newcomer

2:23 Ember-: but when you really need macros then oh boy you're happy you are using clojure

2:23 TEttinger: yeah. to start with, hydromet, I'd recommend learning the core functional programming parts of the library: apply, map, reduce, filter.

2:23 Ember-: hydromet: I've so far written like 10 macros in total. Most of them just to fiddle around

2:23 clojurebot: It's greek to me.

2:24 Ember-: one or two are actually in real production code

2:24 TEttinger: also, 4clojure is excellent

2:24 Ember-: and at the same time I've written thousands of clojure functions

2:24 just to give some perspective here

2:24 hydromet: Ember: and TEttinger: thanks so very much for helping to clear this up ... I guess I got kind of hung up on the part about macros and Rich saying he's not Sun (in the comparison with Java)

2:24 TEttinger: heh

2:25 Ember-: hydromet: no problem, that's the reason #clojure exists :)

2:25 hydromet: My more recent programming has been in Ruby and I only briefly looked at Java in the late 1990s (before that it was Objective-C on NeXT machines)

2:25 Ember-: to help out fellow clojure programmers or those who want to become one

2:25 TEttinger: it's easy to get stuck on these talks, I have found myself confused by seemingly weird parts in a talk and I just can't think about the rest for a bit...

2:25 hydromet: The Clojure community rocks!

2:26 marcopolo`: )

2:26 hydromet: This is the most fun I've had learning a new program in a long time!

2:26 TEttinger: yep

2:26 Ember-: glad to have helped you out

2:26 now I need more coffee

2:26 TEttinger: it's a very expressive language.

2:26 hydromet: The first language I learned at the univ. was Fortran believe it or not (my background being geophysical sciences)

2:26 TEttinger: fortran 77?

2:26 I know there was a long gap without a new version

2:26 hydromet: So to see Clojure has roots to Lisp and Lisp roots to McCarthy and McCarthy was around when Fortran was created, is all quite cool!

2:26 arrdem: the only thing on earth faster than C....

2:27 TEttinger: is optimized C?

2:27 marcopolo`: is there a way to recompile classes within the repl?

2:27 alew: It's very liberating to have macros. Sometimes you run into these code structure patterns that you can't really put into a function but feel like they could be abstracted away. That's usually when macros become really useful

2:27 arrdem: TEttinger: is F77

2:27 TEttinger: (doc compile)

2:27 clojurebot: "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."

2:27 hydromet: TEttinger: I can't recall if it was Fortran 77 or not (forgot already!)

2:27 arrdem: hydromet: good. you don't want to be writing that stuff

2:28 hydromet: arrdem: believe it or not, a lot of hydrology and meteorology to this day in the year 2014 is still written and maintained in Fortran (like weather models)!

2:28 marcopolo`: thanks

2:28 arrdem: hydromet: I'm in the HPC community at $UNIVERSITY. Believe me I know how relivant f77 still is.

2:29 hydromet: I just never want to have to write/debug it :P

2:29 hydromet: arrdem: very cool that you're in HPC

2:30 arrdem: is there any chance traditional / legacy HPC stuff might be migrated away from F77 to Clojure? Imagine running a climate model on the JVM via Clojure!

2:31 arrdem: ugh......

2:31 the performance slowdown...

2:31 the pain...

2:31 TEttinger: hydromet, I think more likely is something like X10

2:31 it has IBM's backing and is really very close to HPC Scala

2:31 but no not for a long time

2:32 arrdem: hydromet: the issue with HPC codes is the development cycle on them

2:32 hydromet: arrdem: although for dynamical models (resolving at grid points, using finite differencing etc.) I suppose its hard to beat F77

2:32 arrdem: hydromet: your average HPC code has been handed down through four or five generations of grad students and is a total hairball

2:32 hydromet: TEttinger: interesting, I haven't heard of X10 and didn't realize there was is "HPC Scala"

2:32 arrdem: hydromet: F77 can write good code as can Perl the issue is that the users don't write good code

2:33 TEttinger: no, I mean

2:33 it's an HPC kind of language, but it's similar to Scala in features

2:33 hydromet: arrdem: hairball is a good description! I imagine there are similar issues in gov organizations with F77 code like NOAA

2:34 TEttinger: so it has stuff for locality when distributing code, but also some medium-strength functional programming features

2:34 hydromet: TEttinger: good point, its not always about the language itself but about who is writing the code!

2:34 arrdem: hydromet: that's me being polite in good company :P I'm on UT Austin's Student Cluster Competition team so I'm involved in building and running some of the gnarliest codes out there

2:34 hydromet: I've seen some shit man....

2:34 alew: choice of programming languages is more of a social one and legacy one than a technological one it seems

2:34 hydromet: TEttinger: can Clojure process large arrays of data fairly speedily? (like grids of data points)?

2:35 nones: is quil no longer developed?

2:35 arrdem: alew: mostly agreed... but F77 and C have Java numeric performance totally beat.

2:35 TEttinger: it's how prismatic works. take a look at hiphip, hydromet

2:35 arrdem: alew: when you really really do need to go fast you need different tools

2:35 marcopolo`: hydromet: it can be just as fast as java

2:35 arrdem: I do hope that changes, but it's the status quo

2:35 TEttinger: https://github.com/Prismatic/hiphip

2:35 alew: arrdem: yeah, but those situations are sooo sooo infrequent

2:36 hydromet: arrdem: Good grief, it sounds like you've got your hands full with that competition! Good luck!

2:36 arrdem: hydromet: we just won for the 2nd year in a row :D

2:36 hydromet: TEttinger: thanks, I wil take a look at both prismatic and hiphip

2:36 arrdem: hydromet: my hands are empty for eight more glorious months

2:36 hydromet: arrdem: congrats!

2:37 arrdem: so is your next project going to be clustering a boat load of the new Mac Pro towers and running some Clojure with OpenCL on those graphics cards (just kidding)

2:37 seriously_random: noob question: fn[...] in reduce can have more than two variables beside accumulator and element in a sequence, e.g. fn [acc x]?

2:37 TEttinger: hydromet, it only makes sense if you already know the equivalents in clojure's collections functions to what hiphip does to arrays

2:37 hydromet: macropolo`: do you run a lot of numerical stuff on Clojure?

2:38 arrdem: hydromet: if that's what you're up to let me know how you do it.. Clojure doesn't have a very well developed multi host parallelism toolkit that I know of

2:38 TEttinger: I would not recommend doing heavy math in clojure... yet. heavy, complex data transformations, oh god yes.

2:38 arrdem: (inc TEttinger)

2:38 lazybot: ⇒ 10

2:38 marcopolo`: hydromet: I have. bits and pieces of data analysis at work

2:39 hydromet: TEttinger: in the Python community apparently NumPy (Numerical Python) has been well received by some, is there anything like NumPy for Clojure?

2:39 TEttinger: that said, I do quite a bit of simple math in clojure for a non-really-real-time game. and it has needed some optimizing, but it runs quite well now.

2:39 marcopolo`: There's Incanter

2:39 TEttinger: numpy is a binding over BLAS right?

2:39 arrdem: seriously_random: not that I know of. The usual pattern is to use an accumulator map which contains multiple meaningful keys

2:39 marcopolo`: core.matrix, if you need to do things with matrices

2:40 arrdem: TEttinger: and appropriage python C extension hooks yes

2:40 marcopolo`: and if you really need to get performant with math, you can use https://github.com/ztellman/primitive-math

2:40 TEttinger: yeah, vectorz or the LAPACK binding for core.matrix would work

2:40 hydromet: marcopolo`: ah yes! I think had seen something a few weeks agoa bout core.matrix ... I should give it a try

2:40 marcopolo`: which makes sure to keep math as primitive types to make as fast as possible

2:40 honestly you should be able to get faster speeds in clojure than in python

2:41 arrdem: lol yes

2:41 hydromet: TEttinger: good question about NumPy, I'm not sure if its binding over BLAS but that could very well be the case

2:41 alew: always blows my mind that python is older than java

2:41 arrdem: marcopolo`: that's not saying much tho...

2:41 TEttinger: seriously_random, there are some good examples on the clojuredocs thing for reduce

2:41 logic_prog: https://gist.github.com/anonymous/8216063 <-- is there a more efficient way or writing this?

2:41 marcopolo`: hydromet: just remember mmul is to multiply matrices, that tripped me up for a while

2:42 arrdem: logic_prog: you don't need that or...

2:42 marcopolo`: arrdem: :) let me change that to faster runtime & faster dev time; that's a bit more impressive

2:42 arrdem: #(get symbol_map %1 %1)

2:42 logic_prog: arrdem: whoa, cool, default value ftw

2:42 arrdem: logic_prog: otherwise looks good

2:43 hydromet: marcopolo`: thank you for the heads up! A friend of mine (who is new to programming) and I are both learning Clojure together. He is an undergrad majoring both math and finance. His classmates learned Matlab but he's totally game to learn Clojure (but he also wants to do math-y stuff like matrix operations)

2:43 logic_prog: arrdem: that's disappointing -- there's no better way to do this?

2:43 arrdem: logic_prog: that's exactly how I'd do it at least...

2:43 marcopolo`: hydromet: where are you going to school?

2:43 logic_prog: hash-maps also work as fns

2:44 ,({:foo 3} :bar 4)

2:44 arrdem: logic_prog: you may be able to do an (into "") rather than (apply str) but the basic approach I think is not gonna change

2:44 hydromet: marcopolo`: Univ. of Hawaii (I'm not in school but my friend is ... I just do some guest lecturing)

2:44 clojurebot: 4

2:45 hydromet: marcopolo`: are you in school too? or do you teach?

2:45 alex_batsuev: Hi, could someone help me with ring-json and peridot?

2:45 trying to parse response from request

2:45 https://gist.github.com/batsuev/d8d1b28910f09e62a9dd

2:45 and got null :(

2:46 logic_prog: marcopolo` , arrdem: noted, thanks

2:46 marcopolo`: hydromet: nice! get them hooked on Clojure!

2:47 seriously_random: TEttinger, what if I want to change the rest of sequence at each loop? Is reduce not meant for this? http://pastebin.com/5nBdVja4

2:47 * arrdem curses the JVM's sign bit viciously

2:47 TEttinger: sure, you can do it. let me take a look

2:48 hydromet: marcopolo`: I really enjoyed watching one of Rich Hickey's presentations from a few years ago "The Value of Values" where he talks about the "PLOP" model being outdated!

2:49 marcopolo`: Is there something special I have to do to override a class's methods in gen-class?

2:49 hydromet: Yeah those are always great! there's a list here of his talks http://thechangelog.com/rich-hickeys-greatest-hits/

2:51 hydromet: Does anyone know when and where Clojure Conj 2014 will be held?

2:52 I didn't find anything about 2014 dates / places on the web

2:52 marcopolo`: hydromet: a bit too early to know for sure

2:52 TEttinger: it's 2014 already whaaaaa

2:52 hydromet: heh

2:52 marcopolo`: did you go to the last one?

2:53 hydromet: no, I've never attended a Clojure Conj but I want to attend the next one

2:53 arrdem: hydromet: word on the street is SF

2:53 hydromet: but there's nothing official at this point

2:53 hydromet: arrdem: that would be fun

2:54 marcopolo`: wouldn't that conflict with clojure/west?

2:55 hydromet: Is Clojurescript gaining some momentum lately, now that we've entered the Gregorian calendar year 2014?

2:59 marcopolo`: Does it look like I'm doing anything wrong w/ gen-class? https://www.refheap.com/22377

2:59 I'm adding socks proxy support to clj-http, but the ssl support is being really annoying

3:00 TEttinger: marcopolo`, a little

3:00 the java object is already mutable where you declare one *dynamic*

3:00 (InetSocketAddress. "localhost" 8118) is already a mutable object

3:02 marcopolo`: I'm planning on doing a binding for that so you can make per request based proxies

3:04 It doesn't seem like it's overridding the methods

3:04 It is definetely extending the class, but my methods like toString or the nil'ed connectSocket don't appear

3:19 From the docs: "SSLSocketFactory is deprecated, use SSLConnectionSocketFactory"

3:19 ...

4:11 sm0ke: ,java.util.Date.

4:11 clojurebot: #<CompilerException java.lang.ClassNotFoundException: java.util.Date., compiling:(NO_SOURCE_PATH:0:0)>

4:11 sm0ke: ,(java.util.Date.)

4:11 clojurebot: #inst "2014-01-02T09:09:45.869-00:00"

4:12 nones: is anyone use Nightcode?

4:12 sm0ke: ,(1000 / 10)

4:12 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

4:12 sm0ke: heh

4:12 ,(/ 100 10)

4:12 clojurebot: 10

4:17 TEttinger: nones, I looked at it.

4:17 I may have installed it

4:21 nones: TEttinger: I can't to build it from master

4:21 TEttinger: I didn't try, I'm not sure what it really does

4:21 that light table doesn't

4:24 nones: it can't load main java class

4:25 TEttinger: are you running the jar with -jar

4:25 nones: I running by `lein run`

4:25 from source code

4:26 TEttinger: ok... check the project.clj , is there a :main ns and the same ns listed under :aot

4:27 nones: :aot [clojure.main nightcode.core nightcode.leinv]

4:27 :main ^:skip-aot nightcode.Main

4:28 TEttinger: I went to their page, will download and try

4:28 nones: from jar it works, but from source code it don't want starting

4:32 roland: susp

4:32 TEttinger: ect

4:34 nones, try "lein javac" first

4:34 it has 5 java source files to compile

4:35 I didn't have any trouble

4:35 lein deps ; lein javac ; lein run

4:37 sm0ke: how do i set an atom to different value

4:37 is there a set! ?

4:38 nones: sm0ke: use reset!

4:38 arcatan: (reset! foo-atom nev-value)

4:39 sm0ke: ah!

4:39 nones: thanks

4:39 ,@(reset! (atom true) false)

4:39 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.util.concurrent.Future>

4:39 sm0ke: ,(reset! (atom true) false)

4:39 clojurebot: false

4:40 sm0ke: weird that there is no mention of reset! on this page http://clojure.org/atoms

4:41 TEttinger: woah sm0ke, that is weird

4:45 sm0ke: well its weird for me

4:45 ymmv

4:51 Cr8: ,(let [a (atom true)] (reset! a false) @a)

4:51 clojurebot: false

4:52 TEttinger: sm0ke, what's weird about it is most of the pages on the site have a listing of relevant fns. that has no listing

4:55 nones: TEttinger: thanks, it works now

4:56 TEttinger: hooray

5:52 sm0ke: does core.async works in android?

5:57 Cr8: no reason to think it shouldn't. Uses java.util.concurrent but android has an impl of that stuff

6:36 sm0ke: i have a let form in my namespace when i put that namepace in aot it is getting executed!

6:36 at compile time!

6:37 and it is obviously throwing stupid errors

6:53 jowag: sm0ke: all top level forms are evaluated when compiling

6:58 sm0ke: you should not perform I/O or any stateful stuff in top level forms, 'cause you'll never anticipate all cases where the namespace gets evaluated.

7:03 sm0ke: you should not perform I/O or any stateful stuff in top level forms, 'cause you'll never anticipate all cases where the namespace gets evaluated.

7:05 alex_batsuev: Hi, could you please tell me what am I doing wrong? :) trying to make simple json server with test using peridot and ring-json, but don't understand how to check response: https://gist.github.com/batsuev/d8d1b28910f09e62a9dd Thanks.

7:07 seriously_random: quick way to create a list of (1) n times? e.g. 3 times: ((1) (1) (1))

7:07 TEttinger: (repeat 3 '(1))

7:08 ,(repeat 3 '(1))

7:08 clojurebot: ((1) (1) (1))

7:24 seriously_random: TEttinger, I ended up rewriting the whole reduce thing. One problem remains with cons, stuff gets nested in the wrong way: http://pastebin.com/9vz7JXs1

7:26 sm0ke: hey guys anyone work with neko for android?

7:26 how the fk do i getApplicationCOntext?

7:27 TEttinger: neko?

7:27 like the haxe thing?

7:27 sm0ke: umm its helper lib for lein-droid

7:27 no

7:27 TEttinger: no, haven't heard of it

7:27 sm0ke: its wrapper around android api

7:27 hmm ok

7:28 xeqi: AlDev: compojure makes sure the response is a string. You'll need to clojure.edn/read it before you can use it as a map

7:28 or json read it

7:30 AlDev: (prn (:response res)) - #<json$wrap_json_response$fn__976 ring.middleware.json$wrap_json_response$fn__976@59b59452>

7:31 TEttinger: seriously_random, I need to get to bed, sorry I can't be of more help

7:32 seriously_random: TEttinger, np

7:32 jowag: seriously_random: if you want to append at the end, use vector instead of cons. If creating vector is too expensive, use concat which returns a lazy sequence

7:33 AlDev: it's not a string in peridot

7:37 xeqi: AlDev: you don't pass request to the (-> app-routes ...) chain

7:37 so its just returning the handler generated by the middleware

7:38 seriously_random: jowag, vector gives me nested lists, doesn't it? e.g. [[[...]...]...] Here is almost what I want: http://pastebin.com/rnBKVa5i

7:38 AlDev: hmm, what I need to change?

7:38 (def res (-> (session app)

7:38 (request "/test"

7:38 :request-method :post

7:38 :content-type "application/json"

7:38 :body (.getBytes "{'user': 'Vasya'}" "UTF-8"))))

7:38 app is (defn app [request] (-> app-routes wrap-json-params wrap-json-response))

7:38 xeqi: well, its not good to create a def inside the deftest. so first use a `let` there instead

7:39 AlDev: ooh, thx. just started to learn clojure

7:39 xeqi: but then change the definition of app to (def app (-> app-routes wrap-json-params wrap-json-response))

7:40 this will define app to be the resulting handler function, which already takes a request as a param

7:41 jowag: ,(map vector [1 2 3] [1 2 3] [1 2 3])

7:41 clojurebot: ([1 1 1] [2 2 2] [3 3 3])

7:41 xeqi: also you can remove the (use 'ring.middleware.json) line by changing the ns declaration, and having (:require [ring.middleware.json :refer :all)). Similar to the compojure line

7:41 jowag: seriously_random: you want to be able to do that ^^ ?

7:41 xeqi: AlDev: you probably also want wrap-json-body instead of wrap-json-params since you are sending the json in the :body

7:43 seriously_random: jowag, yes

7:43 jowag: seriously_random: without using 'map' function?

7:43 seriously_random: or what is your goal :)

7:44 seriously_random: jowag, I did it. "(concat acc (conj '() (apply f (nth-of-all-re x seqs))))" but I am not happy with using conj '(). Getting tired of it

7:45 jowag: seriously_random: Well you have to realize what kind of data structures there are and which function creates which data structure

7:46 AlDev: Thanks, it works!

7:47 jowag: seriously_random: cons creates Cons data structure, into which you can only prepend, not append. conj works with many data structures and it 'adds' new item into the data structure. Somethimes it appends, sometimes it prepends, it depends on the data structure you are conj-oining to.

7:49 seriously_random: '() creates a PersistentList data structure, which is similar to Cons but not the same. But as with Cons, you can only prepend to the List, with conj function.

7:53 seriously_random: and concat creates a LazySeq data structure which behaves as if it was a concatenation of two collections. But the flexibility comes with the price, you cannot conj-oin to the LazySeq.

8:21 xificurC: how can I change a function's ToString representation?

8:27 AlDev: xificurC: http://stackoverflow.com/questions/5306015/equivilent-of-javas-tostring-for-clojure-functions

8:27 xificurC: AlDev: just found it too, thanks a lot

8:37 AlDev: I see I misinterpreted the problem. I'm trying to solve http://www.4clojure.com/problem/113

8:40 so I guess its not about the function's tostring representation but about its results string representation

8:53 https://www.refheap.com/22385

8:55 Ember-: woah, reify with clojure.lang.IFn ?

8:55 why?

8:55 clojurebot: http://clojure.org/rationale

8:55 Ember-: ah, got it

8:55 :)

8:55 but seriously, what's wrong with plain ol' fn?

8:56 and considering your original question, you cannot get a proper seq out of string without somehow parsing it

8:58 Cr8: xificurC: implement Seqable?

8:58 has a method seq() which returns a seq

8:59 clojure.lang.Seqable (seq [this] res)

8:59 xificurC: Cr8: thanks

9:00 Ember-: i dont understand reify or any java interop too much yet so I really dont know what I'm doing

9:00 just trying to make things work and then understand why

9:00 Cr8: ,(seq (reify clojure.lang.Seqable (seq [this] (seq [1 2 3]))))

9:00 clojurebot: (1 2 3)

9:00 Ember-: no need for java interop there

9:03 xificurC: well I dont understand reify either

9:03 this worked https://www.refheap.com/22389

9:04 Cr8: reify is for making a single instance of an object that extends some interfaces or protocols

9:04 (reify SomeInterface (method-on-someinterface [this

9:05 (reify SomeInterface (method-on-someinterface [this arg1 arg2] body) (another-method-on-someinterface [this] body) OtherInterface (method-on-otherinterface [this] body))

9:05 so it's multiple sets of InterfaceName and method body

9:05 xificurC: so here we created a function that extends the Seqable interface?

9:05 Cr8: and you can additionally extend the methods of java.lang.Object anywhere, which is why toString works everywhere

9:05 or you can do that explicility

9:06 xificurC: not a function, just a 'thing'. a JVM object.

9:06 ,(str (reify Object (toString [_] "foo")))

9:06 clojurebot: "foo"

9:07 xificurC: Cr8: so the function returns an object which has the Seqable interface extended?

9:08 Cr8: yep

9:08 well, reify is probably more reasonably considered a special form than a function

9:08 xificurC: its hard to understand this stuff when I dont understand interfaces or protocols i guess

9:09 Ember-: anyway, saying reify clojure.lang.IFn is just a hard way to say fn

9:09 :P

9:09 xificurC: thanks I again understand a bit more than yesterday

9:10 Cr8: right, a function is an object that implements the IFn interface

9:10 which is how maps can be functions as well

9:10 ,({:a 1 :b 2} :a)

9:10 clojurebot: 1

9:11 Ember-: ,((reify clojure.lang.IFn (toString [_] "foo")))

9:11 clojurebot: #<AbstractMethodError java.lang.AbstractMethodError: sandbox$eval49$reify__50.invoke()Ljava/lang/Object;>

9:11 Cr8: ,(map {:a 1 :b 2} [:a :a :b :a :a])

9:11 clojurebot: (1 1 2 1 1)

9:11 Ember-: heh

9:11 I fail

9:11 Cr8: Ember-: actually need to define invoke()

9:11 Ember-: yeah, I understood after I wrote that

9:12 Cr8: ,((reify clojure.lang.IFn (invoke [_] :foo)))

9:12 clojurebot: :foo

9:12 Ember-: ,((fn [] :foo))

9:12 clojurebot: :foo

9:12 Ember-: like I said, a hard way to define fn :)

9:12 Cr8: yep

9:12 xificurC: heh

9:13 theres a lot to grasp in clojure

9:14 especially if you havent coded much before

9:14 Ember-: if you haven't done functional programming before, then definetly

9:14 xificurC: I coded a bit in a few languages but never really touched any concepts, be it functional or OO

9:24 lsdafjklsd: xificurC: clojure has been one of the most difficult, but eye opening languages I have ever tackled. But my background isn't imperative java, I went from ruby/rails -> javascript

9:27 xificurC: lsdafjklsd: my road is roughly (starting from school) pascal -> c++ -> matlab/mathematica/R -> VBA -> clojure -> python -> Common Lisp -> elisp -> clojure; you can count roughly half a year on each of the languages except VBA which I still (unfortunately) have to use at work

9:30 lsdafjklsd: xificurC: hehe, good stuff!

9:31 xificurC: lsdafjklsd: well the bad thing is I never stay with any language long enough to learn it decently

9:31 or the concepts of oo or functional programming

9:34 pyrtsa: Any idea why neither definterface nor defprotocol expose the possibility to extend existing Java interfaces (or Clojure protocols)?

9:42 Or in other words, why do I need to jump through hoops to define a protocol of my own so that the protocol also extends an existing interface, say, clojure.lang.IFn?

9:43 mdrogalis: pyrtsa: I think you need interface injection or something crazy to do that.

9:44 pyrtsa: Internally, both defprotocol and definterface use gen-interface, which allows to pass a list of extended interfaces (gen-interface ... :extends [interface ...]). But neither of them exposes this option.

9:45 That given, it doesn't seem like something crazy to me. It sounds like it was just -- intentionally or not -- left out. And I'd like to know why.

9:45 mdrogalis: Can't say I'm sure, pyrtsa.

9:45 Ask Clojure-dev?

9:45 Ember-: that is indeed a limitation and I see no reason for it

9:47 probably just something no one thought back when those were made

9:47 pyrtsa: I guess so

9:48 ToBeReplaced: what is the use case? I think the preferred method would be create a new protocol -- they really shouldn't be much bigger than one function most of the time anyway

9:52 pyrtsa: ToBeReplaced: Obviously, I'm doing Java interop here. Say, I create a function returning a Clojure object that happens to implement multiple Java interfaces in addition to some protocol(s) of my own. If my protocol implemented those interfaces, I could just type hint the return value as my type and the compiler could figure out the rest, I suppose.

9:52 Another reason: It feels somewhat silly I have to list all the interfaces separately wherever I do a reify.

9:53 But I might be just overlooking something obvious here.

9:55 Cr8: i think the thing is partially that types can be extended to protocols *after* those types are defined

9:56 so there isn't actually a way to make all the things that satisfy the protocol satisfy that interface

9:56 ToBeReplaced: pyrtsa: what are you type hinting the return value of? i don't see why that wouldn't work, but i haven't mix-and-matched interfaces and protocols before

9:57 pyrtsa: Cr8: I'm missing your point. I'm talking about interfaces here. Obviously, I'm defining an interface that includes the methods of an existing 3rd party interface. So any type implementing mine will (need to) implement them too.

9:57 ToBeReplaced: pyrtsa: i take it back, i see the problem... interesting

9:57 pyrtsa: ToBeReplaced: Internally, protocols are interfaces. That's what I mean.

9:58 gfredericks: protocols are partially interfaces

9:58 pyrtsa: Or that. ^

9:58 gfredericks: which is the difference Cr8 was talking about

9:58 Cr8: pyrtsa: right, but the *fact* that a type implements a protocol is defined outside of that type

9:58 pyrtsa: Better said this way: protocols *have* interfaces. :)

9:58 Cr8: so even though it has to implement the methods

9:58 you still can't actually use things of that type in places you can use things implementing that interface

9:59 pyrtsa: Cr8: Ah, that's a good point.

9:59 That said, my question is still open for definterface. :)

10:00 Cr8's point excludes protocols from this discussion. My mistake. But definterface should still provide the extends feature in my opinion.

10:05 Cr8: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L20-L36 is pretty short, you could lift-and-modify [assuming you're ok being infected with the EPL license]

10:06 pyrtsa: Yeah, that's what I'm planning to do. The source macro is one of my favorite tools. ;)

10:10 tarantulee: ,(print clojure.core/*clojure-version*)

10:10 clojurebot: {:interim true, :major 1, :minor 6, :incremental 0, :qualifier master}

10:11 pyrtsa: Cr8: Heh, the comment above "(defmacro definterface ..." reads "for now, built on gen-interface". Guess it wasn't done with a hammock. :)

10:12 UltimateEyePatch: Does apply ever give you TCO?

10:13 Or well, tail recursion I should say

10:16 gfredericks: UltimateEyePatch: tail calls are always via recur

10:17 so I don't know for sure what the context of your question is but the answer is almost certainly no

10:41 jonasen: Bronsa: Is there an easy way to know (in tools.analyzer) if a :fn-method is a loop target? Or do I need to search for the loop-id among the children?

10:43 Bronsa: jonasen: the latter; note that you don't have to walk all the children -- only the ones in :return position

10:43 jonasen: Bronsa: ok, I'll try that

10:48 TEttinger: bitemyapp: just had double-brewed aeropress coffee. one scoop to make coffee, mixed coffee with hot water, pressed through another one-scoop press. both were not labor-intensive or upper-body-intensive, and the coffee was strong but not bitter.

11:00 seubert: i paid $5 for a cortado this morning :V

11:02 jballanc: ok, so I obviously have not been paying enough attention to core.logic...what happened to defrel?

11:18 tarantulee: is there an equivalent to cond-> where the expr is threaded through both the test and the form?

11:20 jballanc: tarantulee: no, but you can combine as-> and cond-> to that effect

11:20 (not great, I know)

11:20 tarantulee: cool, cheers

11:44 justin_smith: ,(apply str (map (comp char dec int) "Hppe!Npsojoh!$dmpkvsf"))

11:44 clojurebot: "Good Morning #clojure"

11:47 mdrogalis: Morning :P

11:47 grzm: I remember hearing somewhere that there were some good examples of CSP patterns in some of the golang documentation. Anyone know off the top of their heads which (part of) the documentation in particular?

11:48 gdev: ,(apply str (map (comp char dec int) "qdcqtO"))

11:48 clojurebot: "pcbpsN"

11:49 gdev: doesn't work on my box

11:49 justin_smith: gdev: slightly more readable if inc'd

11:50 stuartsierra: grzm: try https://code.google.com/p/go-wiki/w/list

11:50 justin_smith: gdev: should that O have been a Q

11:50 ?

11:50 stuartsierra: There are HTTP examples, timeouts, rate limiting, etc.

11:50 gdev: ,(apply str (map (comp char dec inc) "qdcqtO"))

11:50 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number>

11:50 grzm: stuartsierra: cheers

11:50 justin_smith: gdev: you need the int cast

11:51 stuartsierra: grzm: There are also some videos of presentations, something like "Intro to Concurrency in Go"

11:51 Or "Concurrency Patterns in Go"

11:52 grzm: very nice. thanks!

11:52 stuartsierra: You're welcome.

11:52 gdev: justin_smith, I'll just take the bot to private chat until I work it out. My coffee kicked in me guess

11:53 justin_smith: ,,(apply str (map (comp char inc int) "qdcqtL"))

11:53 clojurebot: "redruM"

11:56 gdev: justin_smith, doing ROT-1 by hand is hard apparently

11:56 justin_smith: I am sure it just takes practice

11:57 more shift than rot, anyway (rot would be much more verbose)

12:04 gdev: upping the game a bit https://www.refheap.com/22397

12:06 funny, the raw html source actually has the same control characters that were in my emacs buffer, but of course they do not display properly in the browser at all

12:07 Cr8: hm

12:07 ,(let [charset (map char (range 97 123)) rot (concat (drop 13 charset) (take 13 charset)) rmap (zipmap charset rot) rotate (fn [c] (or (rmap c) c))] (apply str (map rotate "guvf vf ebg13")))

12:07 clojurebot: "this is rot13"

12:07 justin_smith: not bad!

12:08 rotate could be #(rmap % %) without too much loss of legibility

12:08 Cr8: oh yeah

12:09 forgot maps take a default

12:11 jowag: palindrome time!

12:12 ,(let [let - tel let - tel] tel)

12:12 clojurebot: #<core$_ clojure.core$_@5d1f>

12:14 justin_smith: ,((let [let * tel let * tel] tel))

12:14 clojurebot: 1

12:14 justin_smith: now can we do proper math in palindromes?

12:14 ddima: the hell is this? ;)

12:14 justin_smith: ddima: stupid clojure tricks, of course

12:15 ddima: ah, didnt know (*) returns 1

12:15 justin_smith: the multiplicative identity, of course

12:15 ddima: yeah, for some reason would have expected arity-exception

12:16 but makes more sense of course

12:16 justin_smith: ,(< Double/NaN)

12:16 clojurebot: true

12:16 justin_smith: it makes no sense at all, but is very practical

12:16 ddima: justin_smith: well, implementation-wise it makes sense ;)

12:16 justin_smith: exactly

12:18 andyf: justin_smith: Next version of Eastwood Clojure lint tool will warn about single-arg predicates like < > etc.

12:19 justin_smith: cool

12:19 ,((every-pred < > =) Double/NaN)

12:19 clojurebot: true

12:19 jowag: ,(fn nf [fn nf] fn nf)

12:19 clojurebot: #<sandbox$eval49$nf__50 sandbox$eval49$nf__50@110e291>

12:20 Cr8: here's a fun one to run at home

12:20 (pprint (filter #(<= 4 (count %)) (vals (group-by frequencies (clojure.string/split-lines (slurp "/usr/share/dict/words"))))))

12:21 justin_smith: jowag: I think (do .... od) could open up the potential of what a clojure palindrome could do a lot

12:27 bitemyapp: http://awelonblue.wordpress.com/2012/10/21/local-state-is-poison/

12:31 bbloom: bitemyapp: yup.

12:31 bitemyapp: the idea that "new" was a side effect equal to gensym was MIND BLOWING to me

12:34 bitemyapp: bbloom: also lobste.rs is several orders of magnitude better than HN

12:34 I've been watching it for awhile, it has grown nicely.

12:34 it used to be soooo quiet.

12:35 bbloom: got an invite for me?

12:35 bitemyapp: bbloom: sadly no, I would if I had one. I don't have an account yet.

12:35 bbloom: but aphyr and ztellman have accounts.

12:35 I haven't bothered to ask anybody for one yet.

12:35 bbloom: i'm in no rush to have a new distraction

12:36 bitemyapp: well, I'm not looking to get distracted, there are things I'd like to post to the site.

12:36 bbloom: but if anybody wants to bestow an invite upon me, i'll receive it willingly

12:36 bitemyapp: keep the content flowing.

12:36 jonasen: I think invite only is probably a good idea in the long run

12:37 bbloom: seems like they do something with the public invite tree

12:37 i'd like to see a full trust network graph at some point :-)

12:38 jonasen: bbloom: well, you can't create lots of troll accounts if the tree is public

12:38 bbloom: yeah, for sure, helps with that

12:38 bitemyapp: bbloom: the tags and filtering are really nice too.

12:40 bbloom: i just wish i had some way to keep track of people i trust & people i trust to trust other people :-P

12:40 bitemyapp: bbloom: web-of-trust based filtering could be really interesting.

12:40 bbloom: "show me content from this person and anybody within 3 removes of them, with nothing that has these tags..."

12:40 sounds like an excuse for graph nuts to have a ball.

12:41 justin_smith: (inc bitemyapp)

12:41 gdev: bbloom, lol that's what I was trying to get my team to make during clojure cup, but it is a hard problem to solve in 48 hours

12:41 lazybot: ⇒ 15

12:42 justin_smith: bitemyapp: that article was great, thanks

12:42 bbloom: at this point, i think we need an RFC for a distributed social graph + arbitrary annotation data protocol

12:42 bitemyapp: justin_smith: np.

12:42 justin_smith: really thought provoking

12:42 bitemyapp: justin_smith: matches a lot of the thoughts I had as I was shifting out of thinking in terms of Common Lisp and Python and into Clojure and Haskell.

12:42 ddima: bitemyapp: thanks for the lobste.rs reminder

12:43 bitemyapp: unnecessary state you can't track or control is a bigger problem than state itself ever was.

12:43 bbloom: bitemyapp: yeah i was just discussing dmbarbour w/ dnolen. i think dmbarbour is like a mad scientist. love the stuff he's working on, but i basically treat him as an upper bound on my crazy thoughts

12:43 bitemyapp: My complaint with globals (dumb defs at the top-level) is that they create unnecessary singletons, not the "global state"

12:43 if we defaulted to directories/trees so as to avoid the singleton problem I would bitch a lot less.

12:44 hiredman: bbloom: foaf it up

12:44 bitemyapp: but until people wise up to that pattern, I'll keep being cranky about configuration via (def config (atom {}))

12:44 justin_smith: bitemyapp: we need parameterized and versioned namespaces

12:44 bbloom: bitemyapp: i was stoked to see that his byte code & object language were concatenative: http://awelonblue.wordpress.com/2013/12/25/awelon-project-progress-report/

12:44 bitemyapp: justin_smith: well, there's always ML functors and typeclasses, but the best we can do is approximate them.

12:44 bbloom: hiredman: http://www.foaf-project.org/ this?

12:45 hiredman: yes, that is the foaf to which I was refering

12:45 justin_smith: bitemyapp: we can get pretty far with versioned defstructs and protocols I think?

12:46 sorry s/defstruct/defrecord

12:46 I keep doing that

12:47 bitemyapp: justin_smith: you can get pretty far with defrecords but they can still turn into local state run amok sometimes if you don't have some kind of handle to the app.

12:47 justin_smith: that's why I keep a short-circuit switch available globally to all my app instances and infrastructure.

12:47 justin_smith: if the global state behaved more like a log it wouldn't be as big of a deal, then you could see app init, state thereof, and shutdown as a history.

12:48 sritchie needs to stop bothering with twitter and just DM me.

12:49 lsdafjklsd: bitemyapp: what's your twitter handle?

12:49 bitemyapp: lsdafjklsd: you get two guesses.

12:49 lsdafjklsd: bitemyapp: lol, got it

12:50 justin_smith: bitemyapp: there is also (def config (atom [])) (def get-config #(pop @config)) (defn push-config [conf] (swap! config conj conf)) boom, history

12:51 bitemyapp: justin_smith: hum, I don't mean for config necessarily

12:51 justin_smith: I mean for app instances declaring their existence and providing handles for killing them off or fiddling with their behavior.

12:51 config should be part of, and attached to, an app instance

12:51 justin_smith: bitemyapp: that was re your above mention of your config atom gripe

12:51 bitemyapp: config shouldn't exist as a singleton or a log apart from the app, tho it could be logged *inside* of an instance.

12:52 justin_smith: ahh, I think I am starting to see that distinction

12:52 bitemyapp: justin_smith: well yes but the hard part isn't really the push/pop, it's getting people to rethink how their app components work.

12:52 justin_smith: right, it is the design that surrounds the config

12:53 bitemyapp: justin_smith: an app is made up of components, components are made up of namespaces with functions whose behavior can be configured by some kind of state.

12:53 justin_smith: ideally, instead of firing off threads into the clear blue, you should have some kind of global vision into everybody that's "up" or has been "up" in the past.

12:53 and that would ideally be more than just a kill-switch.

12:53 Cr8: prismatic is an interesting mix of crap that folks i follow on twitter tweeted about and stuff "nearby", but its not as picky as I'd like

12:54 bitemyapp: justin_smith: imagine procfs but in your application.

12:54 justin_smith: imagine how cool that would be.

12:54 procfs is just a "tree" of pids and various levels of state introspectable globally.

12:54 why can't instances of your app and their state be part of a tree with logged history?

12:55 could make hot-patching a lot safer, for example.

12:55 Cr8: or: erlang is great until someone uses ets

12:56 ddima: bitemyapp: probably not exactly what you are discussing, but I like how storm uses zookeeper for that

12:56 though not in the form of a log iirc

12:56 mdrogalis: Dire 0.5.2 is out with run-time removal of handlers. Shout at me angerily if you see problems.

12:57 bitemyapp: mdrogalis: noice. Thanks!

12:57 Cr8: or maybe i'm thinking of the process dictionary

12:57 yeah, that thing

12:57 mdrogalis: bitemyapp: Welcome. :)

12:57 bitemyapp: I don't like Erlang much but it has an outsized influence on how I structure my networked backend applications.

12:58 justin_smith: Raynes: refheap does weirdness if I paste a region from emacs that has control characters in it - I think there may be a way to scrub the paste on the elisp side

13:01 Cr8: incidentally I found out about `col` the other week

13:02 justin_smith: Cr8: not coll?

13:02 Cr8: not coll

13:02 col the unix utility

13:02 justin_smith: ahh

13:02 I meant coll?, the clojure function with a ? in the name

13:02 but now I get it

13:11 bitemyapp: I need to wake up in the morning more often. This is awesome.

13:16 zanes: I'm getting a UnsupportedClassVersionError when I try to reify an interface from an imported library and I'm a little confused as to how to debug it. I thought Leiningen was handling all the compilation, so how is it possible that I'd have a class compiled for a different version?

13:17 hiredman: zanes: that library you are using most likely has classes compiled for a later version of java than you are using

13:18 zanes: hiredman: So the thing to do is to target a later Java version, myself?

13:18 hiredman: zanes: sure

13:18 zanes: What's the best way to do that with Leiningen? I poked around a bit and it wasn't obvious to me.

13:19 hiredman: zanes: upgrade your installed java

13:19 lein version will tell you what version of java lein is using

13:20 seangrove: dnolen: We're working with om and ran into a pretty difficult-to-debug case where we were pulling out an IndexedSeq instead of a vector from a MapCursor. We expected to get back another cursor, but we got the plain cljs data structure instead. Looking at the code, it looks like IndexedSeq failed here https://github.com/swannodette/om/blob/master/src/om/core.cljs#L264

13:21 bitemyapp: yum. runtime type safety.

13:21 dnolen: seangrove: yes fix coming for this now, related to how simple leaf node values like numbers and strings should be handled

13:32 gvickers: I have a java object that I am using in a doto, what would be the most idiomatic way to call an instance method on each member of a vector?

13:33 justin_smith: (doseq [object object-list] (.method object))

13:33 probably

13:34 gvickers: justin_smith: thanks, i'll g ive that a try

13:34 justin_smith: if you want the same method called on every one, and don't need the resulting values that is

13:34 zerokarmaleft: provided the instance method has side-effects

13:35 justin_smith: right :)

13:35 make the doseq a for if you only want the return values, a (doall (for ...)) if you want side effects and return values

13:36 oakwise: dnolen: any hints on how to do an efficient live search of a big list of items with om/build-all? :fn with conditional `(assoc item :hidden true)` seems like it will trigger update for *all* hidden items rather than just those that changed, right? (sorry for the double ping…not sure if you were online late last night when I asked a similar question)

13:36 seangrove: dnolen: Heh, that and issue #37 were basically the head scratchers for most of yesterday and this morning

13:37 justin_smith: ,(for [s ["hello" "world"]] (.length s))

13:37 clojurebot: (5 5)

13:39 dnolen: seangrove: so master exposes some more knobs, you can implement IToCursor to handle types beyonds maps and vectors.

13:40 seangrove: dnolen: Brilliant, thank you

13:43 dnolen: seangrove: but you won't need to handle IndexedSeq yourself.

13:43 seangrove: I'm relaxing vector to indexed

13:44 seangrove: dnolen: Sounds good, we experimented with something similar briefly, before just converting our IndexedSeqs into vectors

13:45 dnolen: oakwise: that would be true in React too

13:45 oakwise: efficient search of a truly huge list of items needs to use a some type of clever windowing.

13:46 pcn: clever windowing... there should be a library for that

13:46 even simple windowing...

13:46 dnolen: oakwise: as pcn said, you could probably provide a generic windowing components that can compose the actual view components

13:47 oakwise: would be generally useful.

13:48 coventry: In om, why does to-cursor fail over to returning the object as is? It lead to some confusing behavior on an IndexedSeq.

13:49 Ah, I see dnolen and seangrove discussed this. :-) Still, would it make sense for to-cursor to give a warning in the default case?

13:50 dnolen: seangrove: default to-cursor implementation for all IIndexed instead of IVector

13:51 coventry: because you want to be able to get at the values easily

13:51 coventry: the problem is trying to build a component from a simple value

13:51 coventry: that's a hard error now

13:51 coventry: but I've exposed the knobs so you can still do that if you like.

13:52 seangrove: dnolen: Looks great

13:52 bitemyapp: awww yiss got followed by joey hess!

13:53 oakwise: dnolen: Thanks. Interesting. Right now I'm just trying to show/hide ~200 <li>s, each with about 5-10 dom elements per <li>.

13:53 dnolen: oakwise: yeah I don't think that will be all that slow

13:54 coventry: dnolen: Oh, throwing an error earlier in the process sounds good, too. Thanks. Om is a beautiful design, BTW.

13:54 dnolen: oakwise: we're already rendering on requestAnimationFrame

13:54 oakwise: if it turns out to be a problem let me know

13:55 coventry: it's getting there, it's a tradeoff, but I think you get a lot of value missing in other systems

13:55 oakwise: dnolen: roger thanks

14:01 zanes: hiredman: That did the trick. Thanks!

14:12 Clome_: Does anyone know if you can use Datomic Free in comercial applications?

14:13 mdrogalis: Correct me if I'm wrong anyone, but I believe you can.

14:14 bitemyapp: Clome_: you can use it in the backend of an application

14:14 Clome_: you cannot redistribute it.

14:14 stuartsierra: Clome_: Datomic Free is both free (as in beer) and redistributable

14:14 bitemyapp: oh I didn't know it was redistributable.

14:15 stuartsierra: is Pro Starter?

14:15 mdrogalis: Yeah, the Pro Starter can't be redistributed IIRC.

14:15 bitemyapp: Clome_: I would advise against using Datomic Free in a commerical application though, Pro Starter is a better idea from a technical standpoint.

14:15 stuartsierra: No, Pro Starter cannot be redistributed.

14:15 bitemyapp: Clome_: what kind of application are we talking about here?

14:16 stuartsierra: But commercial OEM licenses for Datomic Pro are available on request.

14:16 dnolen: huh wow craziness I guess now that CLJS has ICloneable

14:16 you can implement protocols on JS Values

14:17 so metadata for String & Number

14:17 Clome_: bitemyapp: none yet. I am just asking if it is possible, otherwise I wont waste time learning it.

14:18 stuartsierra: Clome_: For Datomic licensing questions, you're best off going to the source: #datomic or the Datomic mailing list.

14:18 bitemyapp: Clome_: Datomic Free and Pro Starter are perfectly suitable for learning and experimentation. I have a hard time countenancing a viewpoint that categorizes learning as "wasteful" though.

14:19 Clome_: I've done a fair bit of work with Datomic and I would have no problem using Pro Starter in a commercial application.

14:19 arrdem: what's toothpick?

14:20 Clome_: Well there is nothing new to learn. I would just waste time learning the api. I am looking for a lifghtweight clientside database. And datomic is perfect since it is coljure idiomatic and it uses logic programming. If it is not free I will go with JavaDB

14:20 Bronsa: dnolen: you mean (let [m (atom {})] (specify 1 IMeta (meta [_] @m) ..)) or something else?

14:20 arrdem: bitemyapp: http://github.com/arrdem/toothpick

14:20 gfredericks: dnolen: wat on earth

14:20 bitemyapp: arrdem: totes with you on the anamanaguchi.

14:21 arrdem: bitemyapp: iknowrite

14:21 dnolen: Bronsa: yes that could work

14:21 mdrogalis: ";; TODO write a badass demo" lolol

14:22 gfredericks: Bronsa: I have no idea what that code does

14:22 arrdem: mdrogalis: hey what do you want from me?

14:22 mdrogalis: arrdem: Hah

14:22 gfredericks: what does specify do?

14:22 dnolen: gfredericks: (let [m {}] (specify 1 IMeta (meta [_] m))) is enough

14:22 gfredericks: dnolen: is that effective for all 1's everywhere?

14:23 dnolen: gfredericks: no, only that particular instance

14:23 arrdem: mdrogalis: I now have a working and tested simulator which toothpick can kick out bytecode for, so now I _can_ write a demo :D

14:23 gfredericks: dnolen: is this some JS feature I don't know about?

14:23 dnolen: gfredericks: well a clone of it anyway

14:23 gfredericks: I don't know of anything in JS that would enable that

14:23 dnolen: new Number(n), new String(s) is all you need for the ICloneable implementations

14:24 gfredericks: new Number(n) gives you a first-class-object-number?

14:24 dnolen: gfredericks: yes

14:25 mdrogalis: arrdem: More entertaining to just leave that TODO in :P

14:25 arrdem: mdrogalis: I figure I'm pushing it with the song quote at the top...

14:25 mdrogalis: arrdem: Haha.

14:26 arrdem: mdrogalis: http://www.prometheus-music.com/audio/eternalflame.mp3

14:26 mdrogalis: arrdem: Who wouldn't love that?

14:26 arrdem: mdrogalis: idk man... it still gets me every time

14:27 bbloom: dnolen: seems like ICloneable is trivially the same for all deftypes....

14:28 dnolen: bbloom: yes, though I left seqs out of it for now and obviously no way for transients

14:28 bbloom: dnolen: i'm not sure how i feel about ICloneable....

14:29 dnolen: bbloom: it's required for specify, no other way for it to work

14:29 bbloom: dnolen: on one hand, it's a clear solution for achieving specify sanely & capitalizing on the platform's features, which is very clojure-y

14:29 mdrogalis: Nada and William's Conj talk just broke my brain.

14:29 bbloom: dnolen: but on the other hand, it's such a weird thing to clone an immutable structure :-P

14:29 dnolen: even if it's a shallow clone

14:30 dnolen: bbloom: I don't think it's weird at all.

14:31 gfredericks: bbloom: clojure does it all the time for handling metadata

14:31 (clj-jvm I mean)

14:32 bbloom: yeah, so what's really happening is that there is a hidden field: the type/prototype pointer

14:32 in java, that field is immutable. in javascript, it's mutable if you change the prototype on a single object, right?

14:33 like a ruby metaclass injection thing

14:33 dnolen: bbloom: yeah that's how JS works.

14:34 zerokarmaleft: mdrogalis: indeed, nada live-coding like a boss

14:34 bbloom: zerokarmaleft: her live coding was pretty damn impressive

14:34 dnolen: what things are you using specify for?

14:34 mdrogalis: zerokarmaleft: After a certain point, I had no idea what was going on. :P It's over my head.

14:35 zerokarmaleft: mdrogalis: they lost me after the typechecker...I'll have to revisit it at some point

14:35 mdrogalis: That's pretty far!

14:36 bbloom: don't worry about it if they lost you

14:36 they lost lots of smart folks :-P

14:36 dnolen: bbloom: I think it'll be useful when you want some value to satisfy some API w/o changing equality, it's kind of like become in OO systems

14:36 mdrogalis: bbloom: :)

14:36 bbloom: they are so far down their academic rabbit hole, that they set out to give a talk about how to understand academic stuff & then just went nuts

14:36 was enjoyable, but they failed at their stated goal

14:36 zerokarmaleft: mdrogalis: I loved the bit (paraphrased): "If you're Daniel you start by reading the axioms, if you're Oleg you start by reading the LaTeX." :D

14:36 bbloom: which is true of so much of academia ;-)

14:37 mdrogalis: zerokarmaleft: I lol'ed at work, everyone gave me a ??? look

14:37 dnolen: bbloom: it also avoids the need for wrappers for that use case which is big benefit in my opinion.

14:37 bbloom: dnolen: yeah, i know when it's useful & what it does & how it works. i'm asking what in particular you/others are planning to use it for

14:37 zerokarmaleft: mdrogalis: btw, I'm loving dire...thanks for that

14:37 dnolen: bbloom: as the universe of protocols expands, I'm sure people come up with lots of rocking ideas

14:37 bbloom: dnolen: i'm not anti-wrapper. in fact, i quite like wrappers in theory, if only we had a delegation system

14:38 dnolen: bbloom: I'm not anti-wrapper either - they're just a bear in Clojure(Script)

14:38 bbloom: dnolen: yes.

14:38 dnolen: factor's generic words, protocols, & delegation systems are worth studying

14:39 mdrogalis: zerokarmaleft: Anytime :) Just released 0.5.2

14:39 bbloom: dnolen: http://docs.factorcode.org/content/article-generic.html + http://docs.factorcode.org/content/article-delegate.html

14:48 bitemyapp: hmmm, yes.

14:48 time to write my own edn parser.

14:48 I've had enough.

14:50 dnolen: yep specify works a charm on JS numbers - https://gist.github.com/swannodette/8225403

14:51 stuartsierra: dnolen: How desirable is it to have metadata on host types in ClojureScript when Clojure does not / cannot support the same?

14:53 dnolen: stuartsierra: it was something Rich proposed and put on the todo list, probably because it solves a wart in Clojure.

14:53 gfredericks: there are other things CLJS can do that jvm-clj cannot, e.g. because core protocols are proper protocols

14:53 stuartsierra: dnolen: OK. Interesting.

14:53 gfredericks: extend IFn to regexes or numbers

14:54 dnolen: stuartsierra: we're not going into features here not proposed by the BDFL and are unlikely ever to :)

14:54 justin_smith: would a number as an IFn be (partial * this) or something?

14:55 gfredericks: justin_smith: whatever you want

14:55 stuartsierra: dnolen: OK. It was just a passing thought. I wouldn't want to see CLJS diverge too far from JVM Clojure.

14:55 gfredericks: justin_smith: maybe (partial repeat this)

14:58 mikerod: there *has* to be a way to get similar metadata behavior in JVM clj

15:00 dnolen: mikerod: I think the issue is not whether it can be done but whether it can be done efficiently. obviously JS engine have been optimizing this type of thing for well over a decade now. Not true for JVM.

15:00 mikerod: perhaps invokeDynamic will change that story eventually

15:02 mikerod: dnolen: that makes sense

15:02 bbloom: dnolen: i think that specify could also be implemented in terms of wrappers/delegation & JVMs should be able to optimize that quite well. decorator objects are quite common in java apps

15:03 dnolen: clj already relies on double virtual-call elimination for ever top-level var used as a function :-)

15:03 khaled: hi, all, is using gradle and pallet make sense?

15:04 dnolen: bbloom: yeah, I suspect that rhickey is not really a fan of delegation, probably because people tend to abuse it.

15:04 bbloom: which is why there's so little support for it

15:05 bbloom: dnolen: i'd be quite curious to hear his thoughts on it. wouldn't want to make guesses/assumptions about his perspective

15:06 dnolen: bbloom: yeah just guessing over here. I think recall Stuart Halloway saying to avoid delegation / wrappers at some point.

15:07 bbloom: but to be honest I don't mind, I'm glad I don't have to read code w/ wrappers and delegation that often in Clojure

15:07 it's a convenience to often misused

15:13 arrdem: clojurebot: ping

15:13 clojurebot: PONG!

15:20 koalallama: clojurebot: source

15:20 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

15:22 gvickers`: I asked this before but am still having trouble conceptually, I have a vector of objects, and in a "doto" I want to call the same instance method on each of the objects in the vector. Any idea how to do that? I tried using a map but it fails silently, but adding each element "first, last" works as expected.

15:23 arrdem: gvickers`: refheap paste? map should do what you want so long as you don't mind lazyness...

15:25 koalallama: gvickers`: doseq?

15:28 gvickers`: https://www.refheap.com/22403

15:28 koalallama: gvickers`: whatever you're working on, I want a piece of :)

15:28 gvickers`: Maybe there's something im missing, I understand clojure collections can mess with the type of java objects they contain, but i dont know if thats my problem

15:29 trptcolin: gvickers`: map is lazy. you want doseq, like koalallama says

15:29 gvickers`: snmp4j lib wrapper, thanks!

15:29 justin_smith: gvickers`: map does not fail silently, it is just lazy

15:29 gvickers`: thanks all, i'll give it a try

15:29 justin_smith: gvickers`: remember I recommended doseq, or (doall (for ...))

15:30 koalallama: gvickers`: cool, if open source, send me link. I use a lot of snmp4j, but mostly in Java so far

15:30 arrdem: gvickers`: yeah you definitely want doseq here.

15:30 gvickers`: yea I thought I had done a bad job asking the question, but now I understand what you mean

15:34 I will be reducing the library down a lot, not a huge fan of the way SNMP4J does things. Right now v1 and v2c traps can be captured pretty easily, you just supply a map with a callback function, usually I just give it a function that dumps the traps onto a channel, then you can easily use core.async for processing the stream of data. I am very new to clojure, and this library is only a couple days old.

15:34 https://github.com/gardnervickers/claptrap

15:37 justin_smith: thanks that worked beautifully! clojure's lazyness gets me once again...

15:40 koalallama: great, good luck

15:53 hiredman: win 19

16:02 joegallo: win 20

16:04 dnolen: k first awesome thing about specify, tree stuff with host values at the leaves where you want them to satisfy a protocol

16:10 jballanc: dnolen: hey, am I right in surmizing that pldb has completely supplanted defrel in core.logic?

16:11 dnolen: jballanc: that is correct

16:11 jballanc: cool

16:11 some of the docs/wiki pages are still referencing defrel...had me confused a bit

16:12 dnolen: jballanc: yes should be cleaned up, would love for somebody to help if they feel inclined

16:12 jballanc: heh...well, let's see what my boss thinks of this idea I have for core.logic...might be able to swing a few pull requests your way

16:13 I'm toying with the notion of using titan for storing/retrieving relations for use with core.logic

16:13 so, along the way I'm looking at that code anyway

16:13 dnolen: jballanc: sounds cool

16:14 jballanc: yeah, specifically titan's integration with elastic search for full-text indexing means the possibility of full-text goals

16:14 could be...interesting...

16:55 oakwise: dnolen: looks like that ~200 item list is taking ~500ms to update on every state change even with should-update on the item component always returning false, and it seems to grow/shrink with the number of pseudo-dom components in the item's render func (even though the render func isn't getting called)

16:58 dnolen: oakwise: sounds unlikely if the items are not re-rendering.

17:02 specify to make the bits of a JS 32bit integer accessible / seqable sounds funs.

17:05 trptcolin: what is a JS integer? ;) </trolololo>

17:06 bitemyapp: trptcolin: 1.2 | 0;

17:11 gfredericks: a JS integer is a special integer with gradual overflow

17:11 they can get quite big but they just start acting a little funny at some point

17:13 arrdem: bitemyapp: damnit man now I want to know how the JS sign bit behaves...

17:13 justin_smith: you can get integers via various html5 extensions like three.js

17:13 * arrdem grabs a js repl

17:13 justin_smith: like actual hardware integers that is

17:14 bitemyapp: twitter continues to be the best way to get software support.

17:14 (inc twitter_support)

17:14 lazybot: ⇒ 1

17:14 gfredericks: a hardware integer is a line of laptops each of which is either open (1) or closed(0)

17:14 bitemyapp: arrdem: read the spec and be horrified.

17:14 l1x: is there a way to fetch values belong to a string key from a hashmap the same way you can do it with a symbol? (-> {:test 1} :test) vs. (-> {"test" 1} ??)

17:14 justin_smith: gfredericks: lol

17:14 arrdem: js> -1 | 1<<31 => -1


17:14 WAT

17:14 WAI

17:15 justin_smith: l1x: get-in

17:15 ,(get-in {"test" 1} ["test"])

17:15 clojurebot: 1

17:15 justin_smith: it does nesting like you can do with ->

17:15 ,(get-in {"test" {"one" 2}} ["test" "one"])

17:15 clojurebot: 2

17:16 TimMc: arrdem: Try `-1 | "hello"`

17:17 (This is not the operator you are looking for.)

17:17 arrdem: TimMc: I had a lurking suspicion that was the case...

17:18 TimMc: ... no that's what I wanted...

17:18 TimMc: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators

17:19 TimMc: Ugh, right, I'm thinking of ||

17:19 "foo" | "bar" ;= 0

17:19 Wat 2: Return of the Wat

17:20 arrdem: (dec javascript)

17:20 lazybot: ⇒ -2

17:21 arrdem: I see I'm not the first person with this idea

17:21 justin_smith: wat boogaloo strikes back, the wat-ening

17:21 bitemyapp: (dec javascript)

17:21 lazybot: ⇒ -3

17:22 TimMc: Hmm, isn't two's complement for -1 all ones?

17:22 That would always OR to -1.

17:22 Final Wat XI

17:23 oakwise: dnolen: yeah seems weird… I'll try and put together a minimal example later today. But unless I'm doing something crazy, render on the item component (correctly) doesn't get called, but the more components within it still increase the whole app update time. Here's a quick flame graph: http://i.imgur.com/sK4X0Wh.png

17:23 arrdem: TimMc: yes. ~0 == -1

17:23 ,(bit-xor (bit-not 0) -1)

17:23 clojurebot: 0

17:23 arrdem: :D

17:24 ,(bit-xor (bit-not 0) -2)

17:24 clojurebot: 1

17:24 arrdem: :P

17:24 no need to multiply with -1, just xor with ~0 :D

17:24 and add 1...

17:26 gfredericks: toos compliment

17:27 TimMc: Wat resolved.

17:27 rads: dnolen: I was taking a look at the counters example that uses om/join. the join thing seems like a bad idea to me because it means the component has to know about the structure of the entire app state

17:28 dnolen: I made a small fork to show an alternative example where you just add the extra cursor to an existing cursor: https://github.com/rads/om/compare/counters

17:28 justin_smith: ,(apply str (first (last (take 32 (iterate (fn [[bits left]] [(conj bits (bit-and left 1)) (bit-shift-right left 1)]) [() -1])))))

17:28 clojurebot: "1111111111111111111111111111111"

17:28 justin_smith: in retrospect "remaining" is a better name than left, in context

17:30 rads: dnolen: the (allow-reads (not= ...)) thing might not be the best implementation, but the advantage of doing it this way is that it's straightforward to pass in the parts of the app state that you need, and each component only has to know about a flat map of cursors that get passed in

17:30 arrdem: justin_smith: what is this sorcery

17:31 justin_smith: arrdem: showing the bits in a long, of course

17:31 well, 32 of them

17:31 arrdem: justin_smith: &&(clojure.pprint/cl-format nil "~b" 5)

17:31 * arrdem prays to lazybot

17:31 arrdem: ~botsmack

17:31 clojurebot: Owww!

17:32 hyPiRion: ##'&

17:32 lazybot: ⇒ &

17:32 arrdem: ,&&(clojure.pprint/cl-format nil "~b" 5)

17:32 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: && in this context, compiling:(NO_SOURCE_PATH:0:0)>

17:32 arrdem: gerd dermert

17:32 ,(clojure.pprint/cl-format nil "~b" 5)

17:32 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint>

17:32 hyPiRion: heh

17:32 * arrdem throws in the towel

17:32 hyPiRion: ,(require 'clojure.pprint)

17:32 clojurebot: nil

17:32 hyPiRion: try now

17:33 arrdem: ,(clojure.pprint/cl-format nil "~b" 5)

17:33 clojurebot: "101"

17:33 arrdem: (inc hyPiRion)

17:33 lazybot: ⇒ 27

17:33 TimMc: ,(clojure.pprint/cl-format nil "~b" -1)

17:33 clojurebot: "-1"

17:33 marissagrove: ,(+ 6 7)

17:33 clojurebot: 13

17:33 arrdem: TimMc: yeah it does that. kinda silly.

17:34 hyPiRion: TimMc: it's a nice little cheating guy

17:34 arrdem: TimMc: the issue is that the JVM doesn't really have a sign bit...

17:34 TimMc: arrdem: Nah, that behavior of cl-format seems fine.

17:34 hyPiRion: That's more about the cl format spec

17:34 Hei igjen,

17:34 arrdem: ,(bit-and (int -1) (int (bit-shift-left 1 31)))

17:34 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for int: 2147483648>

17:34 arrdem: hyPiRion: explain that then.

17:34 justin_smith: so I am vindicated!

17:35 hyPiRion: Oh dang, wrong window

17:35 arrdem: I meant "~b" -> -1 is according to the cl format spec

17:35 arrdem: hyPiRion: ah. ok. I didn't see that when I read the hyperspec last night then.

17:35 justin_smith: I mean there is probably an easier version than what I did, but at least mine works :P

17:37 seangrove: bitemyapp: What problems have you run into re: datomic from python?

17:37 Specifically, what could be so bad you'd write your own edn parser? :P

17:37 bitemyapp: seangrove: I am somewhere in atomic rage territory on this subject.

17:37 seangrove: let me find the gif that perfectly illustrates my current status.

17:39 seangrove: http://i.imgur.com/tKu6wrM.gif

17:39 boom. Perfect.

17:39 octagon: is it possible to write a function #'eval-in-ns such that (eval-in-ns 'foo '(prn *ns*)) => #<Namespace foo>? Assume the 'foo namespace exists and has clojure.core refer'd in.

17:39 seangrove: I find myself reciting that exact mantra from time to time

17:39 bitemyapp: octagon: yes.

17:39 seangrove: bitemyapp: Isn't there a clojure meetup tonight?

17:40 bitemyapp: seangrove: news to me. Maybe I can cry salty tears into a beer while listening to people talk about writing Clojure whilst I'm writing a parser in Python of all things.

17:40 hiredman: octagon: it is, but I find the desire for such a thing tends to result from misunderstanding the nature of clojure's namespaces

17:40 bitemyapp: seangrove: so there is!

17:40 octagon: bitemyapp: i am having a hard time understanding how eval and namespaces interact. i saw the #'with-ns macro in contrib, but it resolves things at compile time

17:40 bitemyapp: octagon: http://www.infoq.com/presentations/Clojure-Namespaces-Vars-Symbols

17:40 ~contrib

17:41 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

17:41 octagon: hiredman: i want to be able to eval expressions entered by the user in a separate namespace at runtime

17:41 bitemyapp: octagon: Contrib is dead yo. ^^

17:41 octagon: bitemyapp: i know :/ i just found the macro there and was trying to understand it

17:41 hiredman: octagon: `(do (in-ns ...) user-expression)

17:41 bitemyapp: octagon: watch the presentation I linked.

17:41 Andera's explanation is among the best I've ever seen.

17:41 rads: dnolen: I just realized you can also just use (to-cursor) to create a new cursor from a map of existing cursors. with the change to componentShouldUpdate I linked to in my fork, these on-the-fly cursors will not update unless their child cursors change, which seems like a nice advantage over the existing implementation

17:41 octagon: bitemyapp: ok thank yo

17:42 *you

17:42 bitemyapp: seangrove: mmmm pushdown automata

17:42 this makes me feel like me, but 10 years ago.

17:43 crunchy and primitive. like a hippie drinking raw milk. I can feel the botulism now.

17:43 hiredman: the easiest thing to do is just ignore it and call eval, let your users writing clojure use ns or in-ns to pick what namespace they want

17:44 bitemyapp: octagon: ^^ take the easy way out :P

17:44 reifying namespaces to separate data probably isn't worth it unless you're doing something incredibly sophisticated and bad.

17:44 octagon: bitemyapp: i will write a file and then #'load-file if i need to :)

17:45 * arrdem reaches for popcorn and awaits bitemyapp's response

17:45 bitemyapp: octagon: do whatever your nihilistic heart desires my friend.

17:45 octagon: bitemyapp: i kid, i kid

17:45 but seriously i might

17:45 bitemyapp: arrdem: it's a dynamically typed Lisp. Being morally deficient comes with the territory, all bets are off here.

17:46 octagon: my application uses clojure as a scripting language basically, which means i need to eval the user code separately to avoid confusion with things that exist in the evaluator namespace

17:46 arrdem: $google clojure sandbox

17:46 lazybot: [How can I sandbox Clojure? - Stack Overflow] http://stackoverflow.com/questions/5258038/how-can-i-sandbox-clojure

17:46 bitemyapp: $google clojail

17:46 lazybot: [flatland/clojail · GitHub] https://github.com/flatland/clojail

17:47 arrdem: yeah. that one.

17:47 bitemyapp: $google Linux jail

17:47 lazybot: [chroot - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Chroot

17:47 bitemyapp: $google application isolation

17:47 lazybot: [Application Isolation: Basics and Directions | Symantec Connect ...] http://www.symantec.com/connect/articles/application-isolation-basics-and-directions

17:47 bitemyapp: ...wut

17:47 fucking corporate SEO.

17:47 hiredman: octagon: but namespaces doesn't work like that

17:47 arrdem: bitemyapp: one of my Plan 9 friends has this awesome proposal where mount becomes a devfile not a program

17:47 * bitemyapp scribbles note about burning Symantec marketing department with the communist uprising begins

17:47 bitemyapp: arrdem: <3

17:48 arrdem: bitemyapp: if you chroot /dev/mount out, you've totally sandboxed yourself, because you can't mess with the FS anymore!

17:48 hiredman: if you define a function F in the namespace N, the value of *ns* when F is called may or may not be N

17:48 octagon: hiredman: it's especially confusing for me because some things work in the repl but not in the application

17:48 hiredman: out side of the repl the value of *ns* is alsomost always clojure.core

17:48 namespaces are a compilation environment

17:49 almost

17:50 octagon: hiredman: but they are also dynamic, in that you can add names to them at runtime, right?

17:50 justin_smith: octagon: I think it is likely more that you don't understand what the repl or application is doing. Inside a namespace or in a repl, the clojure compiler behaves the same way with very few exceptions.

17:51 octagon: i guess my confusion may be conflating adding names to namespaces and evaluation of forms

17:51 bitemyapp: octagon: perhaps it would help if you watched Andera's presentation?

17:51 octagon: bitemyapp: yes, i will do that. i'm tethering on my phone at the moment, but thanks i will

17:52 hiredman: octagon: sure but adding names, namespaces are basically a map that is consulted to look up vars during compilation

17:52 you can looking values from the them in a more dynamic way, but that is how clojure uses them

17:52 they are a compilation environment

17:53 not a runtime environment (although they do exist at runtime and can be fiddled with because this is lisp and the difference between runtime and compilation time can be rather small in the repl)

17:55 octagon: hiredman: perhaps i could do what the repl is doing in my application

17:56 TimMc: arrdem: In JS: ~~1<<35 == 8

17:56 hiredman: the repl doesn't do much in fact, I think it initial sets the namespace to user, and after that it is hands off, and it is user code that changes the value of *ns* afterwards via in-ns or ns

17:56 justin_smith: octagon: if you are tempted to define something in one ns from another, that makes me think you have a poorly resolved dependency loop

17:57 llasram: justin_smith: I think they're just writing a REPL/equivalent

17:58 octagon: thanks everyone, bitemyapp, hiredman i think i know how to proceed now

17:59 bitemyapp: ^^ confidence I wish I had.

18:08 andyf_: Bronsa: ping

18:08 Bronsa: andyf_: pong

18:08 bitemyapp: andyf_: dong

18:09 celwell: what's wrong? (fn [n] ((let [arr nil])

18:09 (dotimes [i n]

18:09 (conj arr i))

18:09 arr))

18:10 bars0: Hi all. I am on linux. Where leiningen puts downloaded jars?

18:10 amalloy: celwell: everything there is wrong. values are not mutable, and you have too many open-parens before that let

18:10 andyf_: Bronsa: Your recent tools.analyzer.jvm "better error messages" changes removed the :ast key from the ex-data of exceptions thrown due to bad tags. Was that data considered unreliable, or difficult to provide longer-term? It might be useful in error messages in Eastwood.

18:10 bitemyapp: celwell: that's not how Clojure works.

18:10 amalloy: that's just (range n)

18:10 hyPiRion: bars0: in the ~/.m2/ directory

18:11 bitemyapp: celwell: conj'ing a vector in Clojure returns a new vector with the value provided added to the vector, it does not mutate the original vector.

18:11 bars0: hyPiRion: thanks

18:11 bitemyapp: ,(let [x [:a] y (conj x :b)] (println x y))

18:11 clojurebot: [:a] [:a :b]\n

18:11 bitemyapp: celwell: ^^

18:11 celwell: did x change?

18:11 celwell: what is y?

18:12 celwell: I'm very new to clojure. Trying to do this: "Create an array of N integers, where N is specified as input. "

18:13 justin_smith: ,(repeat 4 42)

18:13 clojurebot: (42 42 42 42)

18:14 justin_smith: celwell: one of the most important things about clojure is the basic types are immutible, conj does not change the input, it returns a copy that is added to

18:14 CaptainLex: celwell: It would be harder to specify N than simply enter all N integers. Are they random integers or user-supplied?

18:14 celwell: N is just a numebr that says the length of the created array

18:15 the contents of each element is ignored

18:15 CaptainLex: celwell: In that case, justin_smith's example is definitely adequate

18:15 Bronsa: andyf_: mostly because the ast at that point is not guaranteed to be valid so I prefered to remove it, but if it's actually needed I'm sorry, I can bring it back.

18:15 CaptainLex: celwell: What are you getting this problem from?

18:16 andyf_: Bronsa: I wouldn't go so far as to say "needed", but it is convenient, and provides some context information that isn't available in the :form key

18:16 Bronsa: Let me experiment with a one-liner change to see if it brings back everything desired by Eastwood, and I can submit a patch if it works

18:16 celwell: hackerrank.com

18:16 justin_smith: celwell: taking a closer look, it seems you were trying to write range

18:16 octagon: ,(loop [x 0, xs []] (if (< x 10) (recur (inc x) (conj xs x)) xs))

18:16 clojurebot: [0 1 2 3 4 ...]

18:16 justin_smith: ,(range 4)

18:16 clojurebot: (0 1 2 3)

18:17 octagon: ^^ looping to construct an array

18:17 Bronsa: andyf_: fair enough -- in case, don't attach the ast directly but `(prewalk ast cleanup)` so we don't end up printing :namespaces

18:18 andyf_: Bronsa: Thanks for the tip. I was already working around their huge size by explicitly avoiding printing them out, but better to be surgical about it.

18:19 justin_smith: ,(first (last (take 5 (iterate (fn [[arr n]] [(conj arr n) (inc n)]) [[] 0])))); also doable as iterate

18:19 clojurebot: [0 1 2 3]

18:19 celwell: legitimate question: why is it so complicated to something that should seem to be simple?

18:20 bitemyapp: celwell: you don't know what you're doing.

18:20 justin_smith: ,(range 5) ; celwell: it is simple

18:20 clojurebot: (0 1 2 3 4)

18:20 octagon: celwell: it's sort of a loaded question, because you'd never do that. you'd do (range n)

18:21 celwell: but there are many ways to construct sequences of things, and they're very powerful.

18:22 celwell: ok, what's the threshold I should hold out for for seeing the benefits of clojure? (coming from php (sorry) and js/coffee)

18:22 so far, everything seems overly confusing to me...

18:22 octagon: ,(take 5 (map #(* 4 %) (range)))

18:22 clojurebot: (0 4 8 12 16)

18:22 celwell: maybe I should stick with it for a week, or what?

18:22 CaptainLex: celwell: Coming from PHP to clojure is definitely going to be jerring

18:23 bitemyapp: celwell: if your ROI time-horizon is limited to a week, you should quit programming.

18:23 CaptainLex: celwell: It will seem pretty confusing at first

18:23 octagon: celwell: ^^ that maybe illustrates better how clojure can help you

18:23 justin_smith: celwell: it will take much longer than that to get fp, but it is worth it

18:23 CaptainLex: but hopefully, when you've stuck with it a bit, PHP will seem confusing when you go back ;)

18:23 bitemyapp: celwell: learning a functional language will pay off huge over the long run but you're not going to unlearn the garbage PHP and JS taught you in a single week.

18:25 celwell: ok, these are things I'm hearing (especially with the trend of clojure this year). but, concretely, what is the single most important benefit in functional programming (over PHP e.g.)?

18:25 bitemyapp: celwell: there is no single most important benefit.

18:25 celwell: taken as a whole, functional programming means working faster, thinking faster, and fewer bugs.

18:25 hyPiRion: celwell: You'll be a better programmer :)

18:25 CaptainLex: celwell: The single most important benefit is in how you think about the software you write

18:26 bitemyapp: celwell: the foundation of it is in referential transparency, functions that are like mathematical functions and return consistent results for the same arguments.

18:26 andyf_: celwell: I'd give it at least a week of hobby time, if you can spare it. I'd also recommend getting a book on Clojure, if the cost isn't prohibitive for you, e.g. the O'Reilly book on Clojure. Functional style programming can feel somewhat foreign to you at first (and sometimes even after a while, but less so)

18:26 bitemyapp: celwell: FP makes you a better programmer but until you are that better programmer you're not going to understand waht you're missing.

18:26 seangrove: celwell: The second most important concrete benefit is that bitemyapp will love you and give you lots of hugs.

18:26 bitemyapp: celwell: http://www.paulgraham.com/avg.html

18:26 celwell: seangrove is only half right. Instead of hugs, you Haskell lessons and free beer.

18:27 celwell: by "hugs" he meant the Haskell repl.

18:27 you get*

18:27 octagon: celwell: i also used to do PHP. i find that it is extremely difficult for even a real pro PHP programmer to write robust large programs. but clojure is very well designed so you don't have to be such a pro to create programs that are at least maintainable

18:27 seangrove: Haha, well played

18:28 celwell: i'll stick with it, thanks

18:29 octagon: celwell: my company moved from php/js to clojure/clojurescript

18:30 celwell: interesting, was it hard to find devs?

18:30 octagon: celwell: we have like 120K lines of PHP, so it's a difficult process to disentangle ourselves

18:30 but everyone can learn it, all of the php guys are learning it and they love it

18:31 bitemyapp: Python people at my company have had zero trouble learning Clojure, despite getting their lessons from a total prick.

18:31 octagon: and the clojure code is orders of magnitude more maintainable and understandable

18:32 justin_smith: oh man my iterate example above was so silly

18:32 ,(take 5 (iterate inc 0))

18:32 clojurebot: (0 1 2 3 4)

18:32 justin_smith: *that* is how to do it with iterate

18:32 bitemyapp: I was going to say.

18:32 justin_smith: you should have!

18:32 bitemyapp: I didn't know if you were being weird on purpose or not.

18:32 it's hard to tell sometimes.

18:32 justin_smith: fair enough :P

18:32 CaptainLex: Does anyone have any experience with shoreleave?

18:32 celwell: is there a recommended subset of the core I should memorize to get started (i find myself not knowing enough functions to get anywhere in my learning)

18:33 octagon: celwell: with PHP there is a lot of knowledge you need to have just to not shoot yourself in the foot when you are building a complex application, so the programmer needs years of experience and skill

18:33 bitemyapp: celwell: don't memorize...learn.

18:33 it's not a quiz. just read and code.

18:33 octagon: celwell: clojure does not have the quirks and pitfalls of PHP, which is a huge productivity boost right off the bat

18:33 CaptainLex: celwell: A lot of the core fniness of clojure is abstracted away when you right practical applications

18:34 celwell: So instead of taking a standardized tutorial, maybe work on some small app in the a domain you're used to

18:34 celwell: i agree, but still... maybe I should I look some good simple code examples

18:34 CaptainLex: use Google to find libs to help

18:34 celwell: any suggestions on github

18:34 CaptainLex: s/right/write

18:34 Someone has a clojure koans repo, right?

18:34 bitemyapp: they exist.

18:34 justin_smith: yeah, clojure koans isn't bad for starters

18:35 CaptainLex: This is a popular place to start: https://github.com/functional-koans/clojure-koans

18:35 andyf_: celwell: Some people have found the cheatsheet helpful: http://jafingerhut.github.io/cheatsheet-clj-1.3/cheatsheet-tiptip-cdocs-summary.html

18:35 octagon: also maybe SICP? that really helped me when i first discovered lisp

18:35 celwell: i've seen koans, any real world example though?

18:35 that you would suggest

18:35 CaptainLex: Hmmm

18:35 How real world? Do you mean

18:35 interesting math, or a web server?

18:35 celwell: not math

18:36 a simple game or web app

18:36 bitemyapp: celwell: have you done the koans?

18:36 CaptainLex: So probably not a 99 problems repo, then. Hmmm

18:36 bitemyapp: looking at Ring isn't going to do a lot for you.

18:36 celwell: no : koans

18:36 bitemyapp: celwell: do the koans.

18:36 celwell: don't be lazy.

18:36 you can be lazy after you know what you're doing.

18:36 celwell: ill try it

18:37 CaptainLex: celwell: Honestly, my recommendation for getting into functional programming is to start with the Structure and Interpretation of Computer Programs

18:37 bitemyapp: celwell: don't try, just do the koans.

18:37 CaptainLex: no. stop.

18:37 celwell: don't do SICP. Just do the Clojure Koans.

18:37 CaptainLex: :'(

18:37 bitemyapp: CaptainLex: I'm tapping you out. Take a break.

18:37 celwell: if you get stuck, take a break, then get back to it.

18:37 celwell: I started watch mit video lectues of sicp from the 80's

18:37 bitemyapp: celwell: do not stop until you complete the Clojure Koans.

18:37 CaptainLex: bitemyapp: I wouldn't recommend the whole thing, just the first chapter. Nonetheless, I'll poke around over here

18:38 * CaptainLex pokes around over her

18:38 bitemyapp: celwell: I watched Sesame Street in the 80s.

18:38 Cr8: I was dead in the 80s

18:38 octagon: SICP was really fun for me when i was starting

18:38 bitemyapp: interesting definition of dead.

18:38 Cr8: well

18:38 not alive

18:38 bitemyapp: octagon: Clojure Koans were really fun for me when I was starting.

18:38 rads: celwell: I think the best way to learn anything is to figure out something you think would be fun to make, and start making it one step at a time

18:39 bitemyapp: celwell: do that, but do the koans first.

18:39 celwell: rads: i agree, but i find myself too stuck to do that

18:39 bitemyapp: celwell: that's because you don't know what you were doing. You know what helps with that?

18:39 celwell: I give you two guesses.

18:39 octagon: bitemyapp: different strokes, right?

18:39 bitemyapp: octagon: different strokes is too often used as a cover for laziness.

18:39 octagon: bitemyapp: you got me there. i'm the laziest dude ever

18:40 celwell: bitemyapp: koans?

18:40 bitemyapp: octagon: I've taught too many people programming in many languages to really believe it makes a damn difference. You have to do some kind of exercises.

18:40 celwell: correctamunde. Hop to it.

18:40 octagon: they can be bad koans, they can be good koans, but you have to interactively hammer in how things work or it'll never stick.

18:40 octagon: blindly groping around a 'practical' project before you know what's going on takes longer than just doing koans.

18:41 it's also less profound and more subject to cargo culting.

18:41 octagon: bitemyapp: i didn't get into clojure until like a year after reading and rereading SICP. i was just enjoying thinking about it, cause the idea of lisp was new to me

18:41 i didn't even do much scheming really, just thinking about it

18:41 * bitemyapp blinks languidly at octagon

18:42 * CaptainLex blinks also

18:42 octagon: my day job was not computing at the time

18:42 celwell: one more question: are there any habits I should avoid as I start to develop my clojure 'technique'?

18:42 bitemyapp: celwell: don't cargo cult.

18:42 celwell: if you think X is true, don't just minimally prove X is true - try to break the assumption with code that you think would demonstrate the opposite.

18:42 celwell: use the REPL, interactively poke around

18:43 celwell: the biggest thing that will prevent you from learning Clojure is being in IRC asking questions instead of doing koans.

18:43 celwell: that leads to 90%++ of failures to actually learn Clojure.

18:43 CaptainLex: Hahahaha

18:43 Cr8: get a REPL

18:43 *play*

18:43 bitemyapp: Cr8: the koans will take care of that.

18:43 or should, anyway.

18:43 I would hope. :|

18:44 celwell: thanks for the advice, ciao

18:44 justin_smith: well the koan interface isn't directly a repl though, it is a good reminder to also play in the repl as you go

18:45 CaptainLex: Good luck celwell!

18:45 akhudek: hmm, I guess core.matrix has no support for float matrices

18:45 bitemyapp: eggscellent. The empire spreads!

18:46 hiredman: akhudek: what do you mean by that?

18:46 bitemyapp: akhudek: does it matter if you have a 64-bit machine?

18:46 I think that's why nobody bothers.

18:46 akhudek: hiredman: e.g. versus double, mostly for memory saving reasons

18:46 exclusively for memory saving reasons

18:46 bitemyapp: oh, so it's not for throughput.

18:47 weird use-case.

18:47 hiredman: akhudek: sure, but what do you mean by no support?

18:47 akhudek: hiredman: all the implementations only support double data type

18:47 justin_smith: akhudek: clojure uses 64 bit numerics by preference, but you should be able to put floats in a vector and use that with core.matrix

18:48 bitemyapp: (inc justin_smith)

18:48 lazybot: ⇒ 25

18:48 akhudek: justin_smith: I might try that, thanks.

18:49 hiredman: justin_smith: clojure vectors box, so you if the intent is to avoid memory pressure by using 32bit numbers I doubt you want boxing

18:50 akhudek: hiredman: good point. I should have remembered that I ran into that at one point.

18:51 hiredman: there are primitive vectors (that can hold primitive values) but they are not often used, and I imagine most code that just assumes clojure's regular vectors will break / convert the specialized vectors to regular vectors

18:51 bitemyapp: must be irish if they box so prolifically.

18:51 justin_smith: hiredman: true, but can't the libs use floats? or are they typehinted everywhere for doubles only?

18:51 hiredman: justin_smith: I don't know

18:52 justin_smith: I imagine they are just going with clojure's flow

18:52 bitemyapp: justin_smith: I think it's pretty hard to keep Clojure from messing with 'em.

18:52 hiredman: the 64bit types are just better supported

18:53 bitemyapp: akhudek: probably cost less to buy RAM.

18:53 thirdy: is there a channel for lighttable?

18:54 #lighttable?

18:54 akhudek: bitemyapp: debatable with our hosting provider :-)

18:54 I can probably make do with 64-bit for now though

18:54 we'll see

18:55 mullr: vectorz-clj, one of the core.matrix backends, doesn't appear to use boxed primitives. (fwiw)

18:56 justin_smith: mullr: yeah, but can it use unboxed floats? I would assume all the core.matrix libs would at least have the option of unboxed doubles

18:56 akhudek: vectorz is double only

18:56 mullr: alasa

18:56 * alas

18:57 akhudek: the core.matrix code mentioned an ndarray-float implementation, but it claimed it was missing when I tried to access it

18:57 justin_smith: akhudek: how much of core.matrix do you need? maybe you could get by with hiphip?

18:58 akhudek: justin_smith: I'm not doing much at this point, I may just write some custom routines to use a float array

18:58 justin_smith: akhudek: well, hiphip does low level unboxed arrays of arbitrary types, and would likely be a head start with something like that

18:59 https://github.com/prismatic/hiphip

19:00 akhudek: hiphip is worth a try too

19:00 bitemyapp: abara

19:00 dammit

19:00 justin_smith: bitemyapp: wow, hiphip does "parameterized modules" by defining a type variable followed by load-file

19:01 lol

19:04 bitemyapp: justin_smith: looking at it now. That's hilarious.

19:04 justin_smith: for the lack of functors!

19:07 akurilin: seancorfield: just saw your reply from a month ago about using straight sql for migrations. Glad to find out I'm not the only one not to use a clj library to handle that.

19:07 actually using ruby's standalone_migrations, worked fine for the past half year.

19:09 seancorfield: akurilin: well, we started off with plain SQL migrations and a non-Clojure process for running them (via Ant!)

19:09 bitemyapp: justin_smith: if you want to go down the rabbit-hole: http://donsbot.wordpress.com/2009/10/11/self-optimizing-data-structures-using-types-to-make-lists-faster/ http://lpaste.net/71651

19:09 akurilin: I use a clj library, but it's processing .sql files.

19:09 seancorfield: So moving to a Clojure process to run the same SQL migrations was just a logical step for us.

19:09 philed: justin_smith: Sorry if this is naive --- I haven't read the code --- but why would you need functors in a dynamically typed language? Just use functions from dictionaries or something?

19:10 justin_smith: philed: the code uses type declarations to create unboxed collections

19:10 bitemyapp: philed: it's not about need, it's about scaling up your programming when you need to and abstracting away details.

19:10 akurilin: seancorfield, bitemyapp so essentially no DSL, just something running SQL against your target DB,right?

19:10 justin_smith: it redefines the type to declare, then redefines everything in a new ns

19:10 bitemyapp: for functors in general.

19:10 akurilin: in my case, yes.

19:10 philed: justin_smith: Ah, it's typed.

19:10 seancorfield: akurilin: correct.

19:11 akurilin: bitemyapp: in your case, does clj just manage sql table with migration ids in it, or something of that sort?

19:11 *a sql table

19:11 bitemyapp: akurilin: just look at Migratus.

19:12 seancorfield: akurilin: we have a table with a "db level" in it and that selects which migrations need to run (and then we update it)

19:12 bitemyapp: akurilin: be aware, I stopped using SQL databases for the most part.

19:12 akurilin: you don't want a single monotonic db level if you can avoid it - Migratus lets you avoid that and not implement anything yourself.

19:12 justin_smith: philed: also, functors are an alternative to what we do with protocols / multimethods, which are less about defining classes and more about using functional composition to create new implementations of operations on existing types

19:13 bitemyapp: philed: in particular, functors are part of a much larger family of algebraic constructs that can be used to abstract your programs.

19:13 philed: functors, applicative functors, monoids, monads, foldables, traversables, arrows, etc...

19:13 akurilin: bitemyapp, seancorfield interesting, I've never dealt with this issue. So you have a tree-like migration path of sorts rather than one line?

19:13 bitemyapp: akurilin: look at Migratus.

19:13 philed: Oh, you mean functors as in Haskell, not Ocaml.

19:14 bitemyapp: akurilin: there's no point in my saying anything that Migratus' documentation would more accurately explain.

19:14 or source.

19:14 akurilin: bitemyapp: fine fine :P

19:14 bitemyapp: akurilin: I stopped using SQL databases. when I last used one, I used Migratus.

19:14 akurilin: there's a reason I haven't touched Korma in awhile.

19:14 philed: what distinction do you suppose you're making here?

19:16 philed: bitemyapp: Parameterised modules versus endofunctors on your type system.

19:16 bitemyapp: philed: do you think functors in OCaml are somehow not endofunctors?

19:16 alew:  besides parametization, what's wrong with clojure namespaces?

19:17 bitemyapp: philed: what do you think is more likely? That there is a schism in PLT and category theory, or that two different languages are using a VERY general category theoretic construct in two different ways?

19:17 philed: a functor is a functor.

19:17 philed: bitemyapp: I could be persuaded :) But no, I tend to think of functors as functions of modules, and modules not being Ocaml types.

19:18 akurilin: bitemyapp: that's fair.

19:18 bitemyapp: philed: this is partly why I recommend people learn Haskell instead of OCaml, it lets to them believing fewe things that are silly.

19:18 hiredman: the load-string hiphop does is kind of gross, I would have used a macro

19:19 bitemyapp: philed: Functors in OCaml are about abstracting types. Functors in Haskell are about abstracting types.

19:19 hiredman: sounds like a micro-library waiting to happen.

19:20 philed: bitemyapp: Abstracting types?

19:20 bitemyapp: philed: http://caml.inria.fr/pub/distrib/ocaml-4.01/ocaml-4.01-refman.html#sec20 what does the first line say there?

19:20 philed: it's the same exact thing in Haskell, they're just being reified to the compiler and used in a weird way in OCaml.

19:20 philed: Functors are functions from structures to structures. In other words, parameterised modules, as I said.

19:21 bitemyapp: philed: that the structure they're parameterizing is a reified module thingy is an implementation detail.

19:21 philed: it doesn't make them not-Functors.

19:21 philed: They have totally different use-cases.

19:21 bitemyapp: philed: really?

19:22 because AFAICT, the Haskell community uses them in the same way, just in a more general way that isn't reified to the compiler for the module system.

19:23 hiredman: https://gist.github.com/8230036

19:23 philed: I'm happy to compare Ocaml functor with Haskell type-classes, since those are often used in the same way. But I wouldn't compare Ocaml functors to the Haskell type-class Functor.

19:23 bitemyapp: it doesn't become "not a functor" just because you're narrowing down the scope of how it's used to a single one-off use-case

19:24 philed: I'd write an Ocaml functor to implement the equivalent of Haskell's Functor type-class.

19:24 bitemyapp: philed: hum, that's getting closer to protocols and the like, yeah.

19:24 philed: but the functor isn't why you get to do that.

19:24 philed: it's the parameterized module.

19:24 that they're functors is a bit of a "gimme"

19:25 philed: I'm not sure what you're saying.

19:25 bitemyapp: it's like saying, "but our product is built by programmers that suck air!"

19:25 well yeah, sure, but that's a bit of a facile and meaningless point to make about a product.

19:25 functors are so general that a lot of programmatic patterns can be modeled as one.

19:25 philed: If you want to talk about formal translations between the two concepts, I'm all ears.

19:25 bitemyapp: philed: SPJ has thoroughly covered that territory IIRC.

19:26 philed: he's been soliciting feedback on a similar module system for Haskell.

19:27 philed: bitemyapp: In the Isabelle theorem prover, you have type-classes and an ML style module system. They play nicely together, but they have different uses.

19:27 bitemyapp: but seriously, think about it. (a -> b) -> f a -> f b could be virtually anything.

19:27 philed: I stay in Haskell land, so if I did anything with proofs it'd be in Agda or Idris.

19:27 philed: Otherwise, they wouldn't have bothered adding in the type-classes.

19:27 Isabelle has Haskabelle!

19:28 bitemyapp: philed: yeah uh, after seeing Coq's "Haskell" support, I'll pass.

19:28 philed: It's pretty good at verifying Haskell programs, though it isn't going for Curry Howard.

19:28 * bitemyapp twitches

19:28 bitemyapp: philed: I think you misunderstood what I was saying.

19:29 noncom: i use the lein "checkouts" feature and there is a problem. if the project i am in does not enlist all the dependencies of the project i am referring to, it fails to find them. I assume, it must take it from the referred project but it does not. Is this the intended behavior?

19:29 bitemyapp: It wasn't an assertion of complete equivalence at the practical level.

19:29 philed: I was addressing a question that was originally about functors in the abstract.

19:29 philed: you dove into something that you seem to have misconstrued as being specifically about particular programming languages.

19:30 noncom: technomancy: ping

19:31 philed: bitemyapp: Not sure. justin_smith was referring to parameterized modules when he used the term "functor." That sounds quite specifically like the Ocaml sense of functor.

19:34 alew: What's the best intro to category theory?

19:34 philed: alew: Depends on your background.

19:34 It's a classic bootstrapping problem.

19:36 bbloom: bitemyapp: justin_smith: dammit! i missed a modules/functors discussion :-P

19:36 i've felt the need for those myself a few times

19:36 philed: I've found that most cat theory texts start out by saying: hey, to understand monads, just think about homotopy theory! And I go: what the f**k is homotopy theory?

19:36 bbloom: a protocol just doesn't cut it

19:37 philed: bbloom: I'll bite! Why do you want modules/functors?

19:37 alew: philed: what backgrounds matter?

19:39 noncom: what's wrong with monads definition here? https://en.wikipedia.org/wiki/Monad_(functional_programming)

19:40 bbloom: philed: i was just trying to explain, but realized i'd need to explain one of the projects i ran in to the problem with, etc

19:40 philed: the hiphip use case is an obvious one for dealing with unboxed values, but there are other times too

19:40 bitemyapp: bbloom: look at hiredman's paste and the prismatic/hiphip code.

19:40 oh, you've seen it then.

19:41 noncom: seems okay.

19:41 philed: bbloom: Are there any cases where you're not dealing with type annotations (as I assume you are talking about unboxed values)?

19:41 technomancy: noncom: hi

19:42 bbloom: philed: yeah, so there are a number of OOP patterns that are better served by modules

19:42 bitemyapp: philed: cat theory and homotopy theory are complementary, IMO.

19:42 noncom: technomancy: hi! please read above ^^

19:42 technomancy: the behaviour you describe is intentional

19:42 noncom: so i just have to include all deps in the present project, right?

19:42 bbloom: philed: the difference is subtle... it's kinda like ruby style metaprogramming vs macros

19:42 bitemyapp: bbloom: or functors. or monoids. or monads. or applicatives, etc etc etc

19:42 technomancy: noncom: yes, :dependencies must be complete

19:43 bbloom: bitemyapp: i'm talking specifically about ML style parameterized modules. not any category notion of functors

19:43 KeithPM: Good day all. I would like someone to review a function I wrote for creating permutations. I am having an issue of inability to convert a java.lang.Long to Object[]. https://www.refheap.com/22414 (Warning) I may have transgressed by creating a function to append an item to the end of a sequence :) Bear with me, it's an academic exercise in recursion at this point

19:43 bitemyapp: bbloom: my point was about ditching OOP for more principled concepts.

19:43 noncom: technomancy: i see, thanks!

19:43 bitemyapp: bbloom: but yeah, parameterized modules are nice.

19:43 bbloom: h ok

19:43 ah* ok

19:43 bitemyapp: bbloom: but a more general notion of how to model algebraic concepts and their associated laws in your language is better.

19:44 justin_smith: we should be able to make these work in clojure right? I have wanted them for a while

19:44 bbloom: philed: anywhere you'd do heavyweight dependency injection in java land, is a case a module might make more sense

19:44 bitemyapp: Pimp Thy Compiler is not exactly principled.

19:45 arrdem: bitemyapp: hey now... unprincipled sure but durn effective

19:45 noncom: KeithPM: could you update the reafheap with instructions on how you cal the functons, so we could call them too, like you do?

19:46 KeithPM: :noncom OK will do...

19:46 bbloom: philed: for example, i had an interpreter-like-thing and then wanted to create a compiler-like-thing, but wanted to be able to have the interpreter around still to test with. unfortunately i had to either A) have two *separate* code bases B) create lots of protocols or C) do what hiphip did and cheat with something like load-string

19:46 bitemyapp: arrdem: sorta? OCaml isn't really playing with a full deck.

19:46 philed: bitemyapp: Ah, I think modules are great for that. Haskell style type-classes force you to choose a canonical model, and other models be damned.

19:46 bitemyapp: arrdem: if by durn effective you mean, "ghetto with one and only one thing anybody wants to steal from it"

19:46 hiredman: we have macros, load-string is gross!!!

19:47 bitemyapp: philed: that is a pretty poor mischaracterization of the differences.

19:47 arrdem: every time I see eval() in another language... the rage...

19:47 justin_smith: hiredman: they mention in the hiphip comments "it's either this one load or a huge pile of macros"

19:47 philed: bbloom: You want protocols to allow you to write generic code?

19:47 bbloom: hiredman: i put your macro in the same category as C

19:47 philed: no, i don't. but that's what you need to do in java, for example

19:47 we have macros, so we can do static metaprogramming

19:47 hiredman: justin_smith: I doubt they are doing what I am thinking of

19:48 if you see by last gist, it is one macro

19:48 bitemyapp: philed: how much Haskell have you done exactly and is your name Robert Harper?

19:48 bbloom: bitemyapp: i disagree with so much shit robert harper says :-P

19:48 hiredman: thinking about it would be best to add something that pushed the namespaces in to loaded-libs

19:48 philed: bitemyapp: I do love Robert Harper. But I've done plenty of Haskell and Ocaml.

19:49 justin_smith: hiredman: ahh, I missed that, much nicer

19:49 bbloom: bitemyapp: either that, or he's just unable to communicate with mortals & i perceive disagreement

19:49 bitemyapp: philed: You should drink a little less Harper kool-aid.

19:49 KeithPM: OK updated https://www.refheap.com/22414

19:49 philed: What makes you think I've drunk any?

19:49 bitemyapp: bbloom: he's an authority on PLT and TT, but he's such an extremist that if his interests had been in politics, he'd have been a terrorist.

19:50 bbloom: heh

19:50 bitemyapp: bbloom: a violent one.

19:50 KeithPM: :noncom I have updated https://www.refheap.com/22414

19:50 bitemyapp: bbloom: he has a hard time imagining that there might be countervailing concerns in PL design.

19:50 and he has a hard time understanding why others might have their priorities configured differently.

19:52 philed: the components of what people use ML functors for are, in Clojure parlance, more "decomplected" in Haskell.

19:52 philed: you cannot obsess over comparing ML functors to typeclasses alone and get the whole picture.

19:52 philed: bbloom: Ack. I'm not sure what to make of what you've said. You've got compiler-like thing and interpret-like thing. What do you want in terms of modules?

19:52 bitemyapp: philed: the power-to-weight ratio that results is better.

19:52 and easier to understand in isolation.

19:52 philed: bitemyapp: Not sure what you're talking about.

19:53 bbloom: philed: i'm saying that i had two implementations of some library that had a common interface, but that interface did not all have a nice friendly THE-SYSTEM as the first argument to dispatch on

19:53 bitemyapp: philed: ML functors aren't that great and there are better ways to solve the constellation of problems it tries to address all at once.

19:53 bbloom: so if i were to use protocols to make it polymorphic, i'd have to a factory protocol & then various protocols for all the dispatched args in that interface

19:53 and then thread through a factory pointer everywhere

19:53 it woulda just been java

19:53 lol

19:53 bitemyapp: I'm starting to see why Sierra's approach makes people mad.

19:54 philed: bitemyapp: I'm not enamored by ML functors.

19:54 bbloom: there are two interesting papers on functors & type classes

19:54 bitemyapp: bbloom: do tell.

19:54 bbloom: one that creates two transformations, one in each direction

19:54 and another that talks about adding "implict" to modules to approximate type classes

19:55 let me dig them up

19:55 philed: bitemyapp: I've got an Ocaml monad library in OPAM, and I found the syntax of ML modules so horrendous, that I suspect they'd never have been discovered in ML.

19:55 bbloom: http://lambda-the-ultimate.org/node/1558

19:55 www.mpi-sws.org/~dreyer/papers/mtc/main-long.pdf‎

19:55 bitemyapp: philed: at least Async shows one way to make reasonably sensible use of monads.

19:56 bbloom: thanks, now I have something to read during the Clojure meetup.

19:56 noncom: KeithPM: hmmmm...

19:56 bbloom: bitemyapp: async uses monads only b/c i got to tim too late to convince him to use a concatenative DSL in place of his state monad :-P

19:57 philed: bbloom: I'm just not sure how parameterised modules would help. This might sound naive, but if you want parameterised modules in Clojure, just turn modules to dictionaries and have those dictionaries as the first argument to functions representing functors. The syntax will only be as horrible as ML.

19:57 bbloom: philed: that's a dynamic technique, i want a static one

19:57 arrdem: Bronsa: do you have docs somewhere of the AST format that tools.analyzer(.*) emits?

19:57 bbloom: see also http://docs.racket-lang.org/reference/mzlib_unit.html

19:57 KeithPM: noncom: Headache?

19:57 bitemyapp: philed: I'm with bbloom, I'd want a static one.

19:57 bbloom: which is a modules-like construct in a scheme

19:58 guide is a better doc page for this: http://docs.racket-lang.org/guide/units.html

19:58 bitemyapp: bbloom: I don't like arbitrary DSLs. They don't compose like monads.

19:58 noncom: ,(vec 3)

19:58 clojurebot: #<RuntimeException java.lang.RuntimeException: Unable to convert: class java.lang.Long to Object[]>

19:58 noncom: see

19:58 KeithPM: noncom: OK...

19:58 bbloom: "A unit resembles a procedure in that both are first-class values that are used for abstraction. While procedures abstract over values in expressions, units abstract over names in collections of definitions."

19:58 noncom: you do (map vec a-seq)

19:58 which maps (vec) over longs

19:58 bbloom: unit==module, but racket already fucked up & called it's namespaces modules :-P

19:58 bitemyapp: bbloom: nutty.

19:58 KeithPM: Yes.. I was worried about that, but I was 'hoping' that I would always receive a sequence... OK... I will double check

19:59 philed: bitemyapp: You mean async in Ocaml?

19:59 noncom: ,(vec [3])

19:59 clojurebot: [3]

19:59 philed: I've only ever played with lwt.

19:59 noncom: ,(vec (seq 3))

19:59 clojurebot: #<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: java.lang.Long {:instance 3}>

19:59 bbloom: bitemyapp: you wouldn't have recognized it as DSL

19:59 KeithPM: noncom: Thanks... Will fix it :)

19:59 noncom: yeah

19:59 bbloom: bitemyapp: it would basically just be a reduce over a lazy seq of "instructions"

19:59 like Fipp is :-)

19:59 * bitemyapp cringes and squints eyes

20:00 bitemyapp: bbloom: there is a reason people are moving towards monadic GLL parser combinators :|

20:00 hyPiRion: uh eh, not sure how parameterized modules in Clojure would make nasty syntax

20:02 philed: hyPiRion: If you want to write generic code in Ocaml, you end up having to wrap all your code in a parameterised module that has arguments for all the modules that are defining your interfaces. It's pretty horrible. OO is more lightweight, and makes sense with multiple dispatch.

20:03 bbloom: OO & dispatch don't make any kind of sense at all :-P

20:03 philed: You still lose if you want to write functions that return generic values.

20:04 bitemyapp: which Haskell accomplishes just fine.

20:04 Having generic functions that participate in parameterized typeclasses, that is.

20:05 hyPiRion: philed: yeah, but that's not necessarily how it needs to be done in Clojure

20:05 noncom: KeithPM: idk if you've fixed it, but using "vector" instead of "vec" does it

20:05 hyPiRion: You could probably make it like Erlang's parameterized modules, granted with a slight performance penalty

20:06 KeithPM: noncom: OK... I was trying to convert sequence but I will use try vector instead

20:17 bitemyapp: philed: bbloom - http://www.haskell.org/haskellwiki/Polymorphism#Ad-hoc_polymorphism this bit is important.

20:17 to me, anyway.

20:17 audaxion: can anyone point me to a good podcast for learning clojure?

20:19 pdurbin: audaxion: http://feeds.feedburner.com/thinkrelevance/podcast

20:19 audaxion: pdurbin, thanks

20:20 bitemyapp: it really worries me that Bing is faster to use to get directions than Google Maps these days.

20:22 bbloom: bitemyapp: agreed. was literally just talking w/ dnolen about delegation earlier, which is basically the dynamic version of newtype + auto deriving

20:23 bitemyapp: bbloom: you can't do generalized newtype deriving in a sound way.

20:23 bbloom: you can make it work in cases that'll make a demo go smoothly, but you can't rely on it.

20:23 bbloom: bitemyapp: good thing i could care less about soundness :-P

20:23 bitemyapp: couldn't*

20:24 bbloom: i couldn't care less what the correct expression is

20:24 bitemyapp: bbloom: I have varying degrees of "give a fuck"-ness about soundness, but I'm serious, you can make incorrect programs from generalized newtype derivation.

20:24 there are times with violating soundness does and does not matter. This isn't one of those cases I'd happily ignore.

20:24 times when*

20:24 Bronsa: arrdem: not yet, sorry, that's something that I need to do :/

20:25 arrdem: Bronsa: nbd. I'm just hacking together the IR for an assembler suite and I'd like it's representation to match yours for obvious reasons.

20:25 bitemyapp: bbloom: if your program isn't correct, you can't get very far with the fancy toys at your disposable - and worse - if you use pimp things out too much you won't even know which bad idea is responsible for the fuckery.

20:25 bbloom: bitemyapp: sure, but the point is that newtype == a wrapper in a dynamic context, which we can trivially create with (deftype Wrapper [wrapped]) but then you have the new problem of how to make it 90% like the wrapped thing, since that's what you usually want

20:26 bitemyapp: yeah, but most folks can't be trusted w/ deftype and defrecord right now anyway, so it's just an extension of that problem :-P

20:26 bitemyapp: It's more than that.

20:26 GNTD can fuck anybody, not just clueless people.

20:27 bbloom: *shrug* i haven't fully internalized the benefits & pitfalls yet, just starting to think more about this stuff

20:28 bitemyapp: bbloom: hacking Haskell is a good way to get a direct handle on it.

20:28 bbloom: bitemyapp: i know enough haskell to know that i disagree w/ a few fundamental things that have a major impact down the line on these things too. we've talked about some of that stuff before

20:29 eg i think return type polymorphism is a bad idea :-P

20:29 bitemyapp: bbloom: there's a way to make GND sound and safe.

20:30 but you have to go further down the types rabbit-hole.

20:30 bbloom: bitemyapp: i have some ideas about going further down the dynamic rabbit-hole :-P

20:30 peregrin_: anyone have good/bad experiences using korma?

20:31 bbloom: bitemyapp: in short, i think that staging is better than typing

20:31 bitemyapp: bbloom: sigh, there's nothing unique or special about "dynamic", you're going to have to learn how to do it right from a type-theoretic point of view.

20:32 bbloom: you're being foolish, you're better than that. Look here for the current state of making GND safe: https://ghc.haskell.org/trac/ghc/wiki/Roles

20:32 bbloom: bitemyapp: you're assuming you understand my entire perspective from two sentences in IRC, note that you expect i'm better than that, then still call me foolish?

20:33 bitemyapp: because it's not about ego.

20:33 bbloom: you're going to have to drop the uni-type fetishism if you want to at least reach parity with the current body of understanding on PLT - such as how to attack problems like GND.

20:34 KeithPM: noncom: I think I actually need vec. Vector doesn't convert the inner sequences to vector, it just wraps a vector around the sequence. I will probably have to ensure that I don't get to an integer... Stop at singleton or something... I'll take a look. Thanks

20:34 dnolen: bitemyapp: "current body of understanding on PLT" eye roll

20:34 bbloom: bitemyapp: i'll drop the uni-type fetish when the PLT community drops the uni-type-system fetish

20:34 bitemyapp: dnolen: http://ro-che.info/ccc/17

20:35 bbloom: bitemyapp: i won't claim to be a professional with type theory, but i certainly know it a whole hell of a lot better than most dynamic typing proponents. i'm firmly in that red/green spot

20:36 bitemyapp: type theory in uni-typed languages is like removing the clutch from a vehicle and marvelling at how "fast" your car goes when you rev it to 9,000 RPM

20:36 akhudek: peregrin_: not my preferred sql lib. Feel it bundles too much and doesn't have clean escape hatches to raw jdbc.

20:37 bbloom: bitemyapp: "uni-typed" is rhetoric. it's not a useful descriptor of anything

20:37 bitemyapp: it's clearly a good idea to design a language that is highly amenable to static analysis, especially formal analysis, such as by modern type systems

20:38 bitemyapp: but to call such a language uni-typed b/c it enforces types at runtime is just plain silly

20:38 bitemyapp: peregrin_: if you want the opinion of a Korma maintainer, you might be better off with HoneySQL unless you're interested in working on a Korma refactor.

20:38 peregrin_: akhudek Honey will have to be it, korma seems to be dead or dying :/

20:39 bitemyapp: peregrin_: it's not dead, we're just waiting for somebody to give enough of a fuck to actually do something about it.

20:39 one of the maintainers doesn't use SQL databases much anymore and doesn't have time to dump into a library nobody else will contribute to.

20:39 bbloom: bitemyapp: since we were linking to dmbarbour's mad scientist ravings earlier: http://awelonblue.wordpress.com/2013/09/04/staging-is-simpler-than-type-checking/

20:39 peregrin_: bitemyapp sounds like the definition of death to me..

20:40 akhudek: bitemyapp: what would you want beyond what honeysql gives?

20:40 peregrin_: akhudek bitemyapp not everyone is in love with manually writing yet another insert/update/parse results function

20:41 bitemyapp: akhudek: schema-awareness.

20:41 akhudek: honeySQL is pretty spare. It's really just a SQL generator.

20:41 peregrin_: extremely spare

20:41 just a SLIGHTLY better way to write sql in clojure

20:42 bitemyapp: bbloom: you might be misconstruing what he's talking about here.

20:42 bbloom: bitemyapp: i am not

20:42 akhudek: bitemyapp: I mocked up the start of a schema aware lib the other day, though not sure where to go with it. Found that I could easily pull a schema from an sql database into clojure and then use it for some light sql generation + checks for things like column name typos.

20:42 bitemyapp: bbloom: preference for statically verified type systems does not mean the disinclusion of libraries with uni-typed APIs/objects.

20:43 bbloom: preference for uni-typed languages almost always means you cannot and will not design a sane or safe type system for verifying your programs.

20:43 peregrin_: akhudek thats what ruby/sequel does. it works pretty great

20:44 bbloom: bitemyapp: uni-typed is already an insufficiently defined phrase, you're making an insufficiently substantiated generalization, and then attributing that position to me

20:46 akhudek: peregrin_: the main problem I see in many sql generating libraries is that they try to be the sole interface to the database + completely hide it under some abstraction layer.

20:46 I see the value in generating sql for common use case patterns though

20:47 peregrin_: akhudek look at Sequel for ruby, it does a really good job of abstracting SQL into ruby syntax but then giving you super simple prepared statements that returns hashes.

20:49 i mean you can go super deal and use it like active record. or you can use it like honeysql. or you can use it just to make pstatements. I seen absolutely nothing like this in clojure...

20:49 deal/deep i/i've

20:50 bbloom: bitemyapp: i think it is perfectly reasonable/acceptable to design a language that has provably safe runtime behavior, but programs in that language can not be proven free of certain common classes of errors, as long as approximate reasoning is generally free of common classes of errors

20:50 bitemyapp: see also http://www.cse.chalmers.se/~nad/publications/danielsson-et-al-popl2006.html

20:52 approximate reasoning == it's A-OK to create a logical system that abstracts over some details and fails to validate some subset of useful programs or fails to detect some subset of erroneous programs

20:52 seangrove: bbloom: I've very much come around to the idea that programs should be amenable to static analysis, whatever that means. I think types are a good idea, but maybe not the only one.

20:52 akhudek: peregrin_: interesting, thanks for the link

20:53 seangrove: peregrin_: https://twitter.com/peregrine ?

20:53 peregrin_: seangrove yes :) how you doing man?

20:53 bbloom: seangrove: agreed. hence my stance on optional type systems

20:53 and my lack of caring for soundness

20:53 :-P

20:54 seangrove: peregrin_: Doing well, cool to see you hacking with clojure!

20:54 peregrin_: akhudek it makes me life really hard whenever I'm like "clojure looks cool I know I'll write my next api in it"

20:54 seangrove been wanting to forever. Backing off elixir cause its pretty green

20:55 seangrove: Well, the om/react, core.async. core.typed, cljs ecosystem is pretty lovely

20:55 Possibly throw in datomic there as well, but I haven't had a chance to properly play with it

20:56 peregrin_: seangrove yea cljs is a ton more exciting than clojure proper to me :) I wish they would decide to actually launch it

20:56 seangrove: bbloom: I guess I missed your stance on optional typing systems - they're not worth it, or they're an amenable approach?

20:56 peregrin_: seangrove I mean how long has it been "alpha"?

20:57 seangrove: peregrin_: Well, hack on it. We have two apps in production (well, one in production, one in alpha), and it's easy to get patches in

20:57 And it's fun to hack on anyway

20:57 bbloom: seangrove: my firm and clear stance is that your language's observable semantics should not depend on your type system

20:57 peregrin_: seangrove yea, hard to sell to a client "going to use this alpha software" gotta use it on my own projects

20:57 bbloom: seangrove: however, my design criteria for a new language, should i design one, would include co-development of a modern type system, as to ensure the language is highly amenable to such reasoning

20:58 seangrove: peregrin_: I don't know exactly what the hold up is, I think dnolen has a few things he wants to get done before a 1.0

20:58 UltimateEyePatch: bbloom, are you an expert on clojure?

20:58 seangrove: UltimateEyePatch: If anyone is....

20:58 UltimateEyePatch: Excellent

20:58 bbloom, you can't combine recur with apply can you?

20:59 arrdem: UltimateEyePatch: correct. recur is a special form not a function.

20:59 bbloom: seangrove: aw, thanks :-P

20:59 peregrin_: seangrove yea it seems easy enough to use with cljsbuild and I ran into zero front end bugs using it

20:59 bbloom: UltimateEyePatch: you can address the whole room with that question

20:59 seangrove: bbloom: It's an interesting problem designing a language meant to be consumed by tools with enough metadata to soundly reason about it

20:59 peregrin_: with a demo app*

20:59 UltimateEyePatch: arrdem, is there any way to recur variadically?

20:59 bbloom, but I'd rather address you...

20:59 You re my special favourite

20:59 arrdem: UltimateEyePatch: how would a vardic return make any sense?

21:00 UltimateEyePatch: arrdem, well ehh

21:00 like, reduce in clojure

21:00 fold-left

21:00 Is not variadic, or is it?

21:00 bbloom: seangrove: tools already deal with this sort of thing. most transformations IntelliJ does, for example, have reaaaaallly esoteric edge cases. turns out that they just cover the majority of realistic things that realistic programs do & then have check-as-you-go UI plus some log output with warnings, if a non-provably-correct refactoring occurs

21:00 arrdem: UltimateEyePatch: nope. fold left isn't.

21:00 UltimateEyePatch: Can it be made variadic and still be tail recursive?

21:01 Maybe some kind of double reduce?

21:01 arrdem: UltimateEyePatch: not really...

21:02 seangrove: bbloom: Yeah, but it's quite a lot of effort in java to provide enough meta-information for tools to ready - repeated types, public/private, etc.

21:02 UltimateEyePatch: So you have to make reduce, reduce2, reduce3, reduce4 etc for allt he cases yu might need?

21:02 Or grow stack space

21:02 bbloom: seangrove: oh yeah, for sure, better language design w/ toolability in mind is a big deal. agreed. my point was just that approximate reasoning is OK :-)

21:02 seangrove: bbloom: Ah, I see. I'm hesitant, but it's probably true.

21:03 arrdem: UltimateEyePatch: what you propose is silly. What problem are you trying to adress here? refheap preferred.

21:03 bbloom: seangrove: like LINQ choosign to use `from x select y` instead of `select y from x` so that you can autocomplete when you type y

21:03 seangrove: bbloom: Ah, you mean as a language design?

21:04 (of LINQ)

21:04 UltimateEyePatch: arrdem, well, sometimes you need to fold/reduce 2 lists at once.

21:04 So, you can then just define a reduce2 function for that and no problem

21:04 Sometimes 3, so you make reduce3 and so fourth

21:04 bbloom: seangrove: yeah, linq was carefully designed to be familiar to people who know SQL, but much more friendly to Visual Studio users :-)

21:04 arrdem: UltimateEyePatch: stock reduce provides that behavior unless I miss my mark..

21:04 UltimateEyePatch: It'd just be cleaner if these were all one function

21:04 arrdem, I've just been told that reduce can only reduce 1 list

21:05 arrdem: ,(doc reduce)

21:05 clojurebot: "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i...

21:05 bbloom: UltimateEyePatch: arrdem: reduce over a (map vector ...)

21:05 seangrove: Clever

21:05 arrdem: UltimateEyePatch: yep that's the pattern.

21:05 bbloom: (reduce (fn [acc [x y]] ...) (map vector xs ys))

21:06 bitemyapp: bbloom: No thanks.

21:06 bbloom: I'm okay with allowing some possibly invalid programs, but soundly typed programs are a sensible default.

21:06 bbloom: static analysis is good for many things, type checking is only one of them.

21:06 arrdem: UltimateEyePatch: you could define a macro or wrapper fns, but you'd just be wrapping that pattern.

21:07 bbloom: bitemyapp: um, that's what i've been saying

21:07 bitemyapp: bbloom: but what I'm saying is that you should start with a static/strong/functional/non-strict language and only step outside of that paradigm strictly when necessary on a case-by-case basis.

21:07 UltimateEyePatch: Wait, (vector list) returns a vector with all of the elements of list right?

21:07 It doesn't return a vector which only contains list and stuff

21:08 bitemyapp: ,(vector '(1 2 3))

21:08 clojurebot: [(1 2 3)]

21:08 bitemyapp: ,(vec '(1 2 3))

21:08 clojurebot: [1 2 3]

21:08 UltimateEyePatch: Ahhh

21:08 bitemyapp: bbloom: ^^ these things are easier to understand if you had a type signature for vector and vec.

21:08 alas. :|

21:08 UltimateEyePatch: Well, then then I don't it, then (map vector xs xys) basically contains a list of 2-size vectors right?

21:09 seangrove: bitemyapp: Yeah, I had to check that earlier today too

21:09 bitemyapp: type-checking could've told him they were using the wrong function.

21:09 UltimateEyePatch: don't get it*

21:09 bitemyapp: UltimateEyePatch: basically a zipper.

21:09 er, sorry, zip.

21:09 not a zipper as such.

21:09 UltimateEyePatch: map can take multiple iterables.

21:09 bbloom: bitemyapp: i'm not sure why we're arguing, since you seem to agree with my point of view lol

21:09 bitemyapp: UltimateEyePatch: it walks them in sequential lock-step, ending on the shortest one.

21:09 bbloom: then *why* are you using Clojure?

21:10 UltimateEyePatch: Yeah, so the function will then just use that vector as argument?

21:10 THat makes kind of sense I guess

21:10 seangrove: peregrin_: Let me know if you'd like to hack on any side projects in Clojure from time to time. I often work on small things with people for fun a few hours a week.

21:10 arrdem: bitemyapp: says the pot to the kettle...

21:10 bitemyapp: UltimateEyePatch: vector is the function applied to the results.

21:10 peregrin_: nice

21:10 seangrove sounds good man. I'll let you know

21:10 bitemyapp: arrdem: how much Clojure do you think I've written outside of the day job in the last couple months?

21:11 arrdem: or even six months?

21:11 arrdem: Brambling was during my 9-5.

21:11 arrdem: bitemyapp: I don't care. you still lurk here.

21:11 bitemyapp: arrdem: that's because cool people like you reside.

21:11 bbloom: bitemyapp: i don't know why i try to exchange perspectives with you, you always get so combative

21:11 arrdem: bitemyapp: lol. my point stands.

21:11 bitemyapp: #python has no such dilemma for me.

21:11 bbloom: I didn't *feel* combative.

21:12 bbloom: I just resolve incompatible models of the universe aggressively.

21:12 bbloom: bitemyapp: arrdem's pot/kettle comment suggests to me that i'm not the only one who perceived combativeness :-P

21:12 bitemyapp: bbloom: I feel happy we had that conversation. :)

21:12 t3soro: Hey guys, I am trying to use extend-type, but it's not making sense to me

21:12 bitemyapp: 80% of why I use Clojure has to do with Datomic. If not more.

21:12 I don't exactly have a choice.

21:12 t3soro: Here is a minimized example, if anyone can see what's going wrong? http://pastebin.com/EL010ryZ

21:13 arrdem: bbloom: just pick your battles and tune the rest out :P

21:14 bitemyapp: arrdem: but we agreed?

21:14 arrdem: bitemyapp: just because I agree with you doesn't require that I pay attention when you start :P

21:15 bitemyapp: arrdem: mayhaps.

21:15 arrdem: I'm at a Clojure meetup. I don't think there's a planned talk. Considering using it as an opportunity to teach some Haskell.

21:15 arrdem: bitemyapp: haha go for it. I need to put together a lightning talk on core.typed ... :/

21:16 bitemyapp: Ouch.

21:16 arrdem: do what I do. Step 1: Know what you're talking about (kinda) Step 2: Wing it.

21:16 ryanf: t3soro: I believe you want (hello "world"), not (.hello "world")

21:17 I could be wrong though

21:17 t3soro: hey thanks ryanf i actually just tried that, and you're right, that works.

21:19 arrdem: bitemyapp: yep. I suspect it's gonna come down to a "here's c.c.t, here's the semantics of a signature, here's the workflow, here are some failure modes I've encountered."

21:19 t3soro: I was under the impression that all protocol methods had to be called with .

21:19 arrdem: t3soro: nope!

21:20 t3soro: time to clean that out of a dozen namespaces now lol

21:20 * arrdem kicks on the phantomk and swears to come up with a better AST

21:23 Denommus: what version of leiningen should I install?

21:24 peregrin_: latest?

21:24 clojurebot: latest is forget latest

21:24 peregrin_: thanks clojurebot

21:25 saclark: Clojure noob here. My repl complains that it cannot resolve `seqable?` but everywhere I look online says that should be in core. Do I have require something to use it?

21:28 peregrin_: ,(doc seqable?)

21:28 clojurebot: Pardon?

21:28 peregrin_: could try seq?

21:29 oh looks like seqable is in clojure.contrib.core but maybe seq? would work the same?

21:29 ,(doc seq?)

21:29 clojurebot: "([x]); Return true if x implements ISeq"

21:30 bbloom: peregrin_: nope, that's seq? not can-be-made-in-to-a-seq

21:30 saclark: try coll? which is close enough

21:32 Denommus: clojurescript looks complicate to setup

21:32 peregrin_: Denommus this should help a ton https://github.com/emezeske/lein-cljsbuild

21:36 rads: Denommus: http://swannodette.github.io/2013/10/27/the-essence-of-clojurescript/

21:36 saclark: Thanks guys, I think I'll just use `seq?` it should be good enough in my case

21:36 Denommus: I was thinking about using ClojureScript in a Qt HTML5 application

21:40 but I could just... implement it in ClojureScript and then put the generated sources in Qt later :-)

21:54 bitemyapp: arrdem: yeah, going to give a talk on Haskell.

21:54 What is good in life? Trolling Clojure meetups with Haskell.

21:54 arrdem: the failures part of your talk could be particularly interesting.

21:55 arrdem: tell them an angry tribal deity strikes them with a lightning bolt if the type of their function is Any * -> Any *

21:56 arrdem: bitemyapp: angry tribal deities aren't the only ones who wage war with lightning bolts...

21:57 bitemyapp: arrdem: "I'm your god too!"

21:59 rovar: writeup on DayZ on Hackernews

22:00 indigo: Trolololo types

22:00 arrdem: rovar: oh god why

22:01 rovar: it is relevant to their interests?

22:01 indigo: HN is a major circlejerk

22:01 rovar: https://news.ycombinator.com/item?id=7003821

22:01 indigo: I feel like the more I read it the less productive I am :|

22:02 rovar: I recommend reading it not more than once a day, purely for productivity reasons

22:02 ironically, the only highly popular forum that isn't a circlejerk is /r/circlejerk

22:02 indigo: rovar: I believe there was that one HN by email service

22:03 It would send you the top articles from HN over a week by email

22:03 rovar: sounds like an RMS-esque solution

22:03 indigo: Haha

22:03 Who knows

22:04 RMS is probably more productive than all of us because he spends less time reading "how I built 30 apps last year"

22:05 rovar: perhaps he should be a little less productive.

22:05 https://www.youtube.com/watch?v=9sJUDx7iEJw

22:05 that's all I have to say on that topic

22:06 tarantulee: Someone get the link for him eating some stuff off his foot

22:06 arrdem: ah RMS....

22:06 indigo: Heh

22:06 rovar: I thought you'd be linking the foot video

22:06 He is definitely an eccentric

22:06 rovar: somehow I think that this one is more tragic than eating foot particles

22:07 its slow and hard to watch, but just keeps going.. not unlike a train wrock

22:07 wreck

22:07 arrdem: rovar: I love the comparison

22:08 rovar: man I hate being sick and having way too much stuff to do.

22:33 bbloom: common lisp has attribute lists on symbols... but other than that... does any other well known language have something akin to clojure's metadata?

22:33 arrdem: bbloom: runtime symbol metadata?

22:33 /value metadata

22:33 not that I know of.

22:33 bbloom: either, both, whatever :-P

22:34 arrdem: usually you'd make the metadata explicitly part of the data...

22:34 which is why Clojure has seperate metadata :D

22:34 bbloom: i assume that rich's inspiration was lisp's symbol attributes, but was wondering if there was something else to study too

22:39 http://reference.wolfram.com/mathematica/ref/Annotation.html :-)

22:42 seems like Annotation[5, "foo"] prints as just 5, but + isn't overloaded for annotations sadly :-P

23:26 seangrove: Interesting, haven't heard much about pigpen http://techblog.netflix.com/2014/01/introducing-pigpen-map-reduce-for.html

23:26 I would have expected a bit more noise on twitter, at least

23:31 bbloom: neat

23:40 Denommus: so Clojure's ~ is like Common Lisp's ,

23:41 bbloom: Denommus: yes, and ~@ is like ,@

23:41 Denommus: commas are whitespace in clojure

23:42 Denommus: bbloom: clojure is hygienic, right?

23:43 arrdem: Denommus: no. macros can leak symbols and refer to symbols which are not bound in the macro or macro definition environment.

23:43 bbloom: Denommus: clojure encourages hygiene with automatic symbol qualification and gensym unification, but clojure allows you to be easily defeat those mechanisms with ~'

23:44 arrdem: ,(macoexpand `(~'foo))

23:44 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: macoexpand in this context, compiling:(NO_SOURCE_PATH:0:0)>

23:44 arrdem: ,(macroexpand `(~'foo))

23:44 clojurebot: (foo)

23:44 technomancy: it's easy to be unhygenic but difficult to do it by accident

23:44 Denommus: I expected it, somehow

23:49 thirdy: From the book Programming Clojure: true? tests whether a value is actually true, not whether the value evaluates to true in a boolean context. The only thing that is true? is true itself

23:49 confusing

23:49 technomancy: clojure.core/true? is not a useful function

23:50 bbloom: technomancy: i've used it :-P

23:50 thirdy: (true? (= 1 1)) evalues to true

23:50 Denommus: (def a true) (true? a) evaluates to true, too

23:50 thirdy: what does it my mean by 'in a boolean context'?

23:51 bbloom: ,(map (juxt identity true? false? boolean) [0 5 {} [] "foo" :bar 'baz true false nil])

23:51 clojurebot: ([0 false false true] [5 false false true] [{} false false true] [[] false false true] ["foo" false false true] ...)

23:51 arrdem: (inc bbloom)

23:51 thirdy: from my understanding: it's telling me that true? will only work with the literal true e.g. (true? true), nothing more

23:52 bbloom: thirdy: a boolean context is anywhere an object is coerced to a boolean, which is basically only in 'if or things built out of 'if

23:52 Denommus: thirdy: for example, (if "a" "b" "c") evaluates to "b", but (if (true? "a") "b" "c") evaluates to "c"

23:53 bbloom: thirdy: try that (map (juxt ...)) expression i entered in your local repl & think on it for a bit :-)

23:53 Denommus: thirdy: that is, (true? a) is mostly the same thing as (= true a)

23:53 bbloom: ,(map (juxt identity true? false? boolean #(if % :then :else)) [0 5 {} [] "foo" :bar 'baz true false nil])

23:53 clojurebot: ([0 false false true :then] [5 false false true :then] [{} false false true :then] [[] false false true :then] ["foo" false false true :then] ...)

23:54 Denommus: I need to sleep

23:55 arrdem: ,(defn sleep? [& m0ar] true)

23:55 clojurebot: #'sandbox/sleep?

23:55 bbloom: ,(sleep?)

23:55 clojurebot: true

23:56 bbloom: you can def things in clojurebot? wut?

23:56 (def wtf "!?")

23:56 ,(def wtf "!?")

23:56 clojurebot: #'sandbox/wtf

23:56 bbloom: ,wtf?

23:56 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: wtf? in this context, compiling:(NO_SOURCE_PATH:0:0)>

23:56 bbloom: ,wtf

23:56 clojurebot: "!?"

23:56 arrdem: lol

23:56 bbloom: I think they get undef'd after some time window but yes we can now use def.

23:56 bbloom: ,(def inc dec)

23:56 clojurebot: #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>

23:56 arrdem: hahahaha

23:57 bbloom: ,(defn inc [x] (dec x))

23:57 clojurebot: #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>

23:57 marcopolo`: ,(def foo 1)

23:57 clojurebot: #'sandbox/foo

23:59 hiredman: clojurebot: oh clojurebot, wait have you done?

23:59 clojurebot: Huh?

23:59 thirdy: ,(= true a)

23:59 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)>

Logging service provided by n01se.net