#clojure log - Feb 07 2016

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

0:16 mercwithamouth: so i compulsively bought ANSI Common Lisp...noticing that it was written by Paul Graham and his name pops up a lot. Is there much to gain in reading about/learning other dialects of lisp to further growth in clojure?

0:16 i assume in general it's just good to read/learn as much as possible from different 'smart guys' and add it to your toolbox.

2:10 oracle: hi

2:11 I am using https://github.com/semperos/clj-webdriver, and there is a taxi api, but I can't find the file of taxi.clj. Do you know whether to find it ?

8:13 Somelauw: Inside a macro I'm trying to get the name of a function to be printed. Let's say I write (def f +). Now I want to turn f into '+'.

8:14 (name f) doesn't work because f is not clojure.lang.Named

8:16 `(name ~f) comes closest so far

8:33 kwladyka: how parameter should look in function like (fn [foo bar] ... ) to know it is a map, vector or list? Especially map? Any common rules?

8:39 qsys: kwladyka: parameters can be of any type, it's your decision

8:52 Somelauw: kwladyka: mostly just m for m, v for vector, coll for collection I think

8:54 mmeix: helpful: https://github.com/bbatsov/clojure-style-guide#naming

8:55 "Follow clojure.core's example for idiomatic names..." etc

9:04 kwladyka: qsys yes but for example i want my parameter to be map, it is my decision. But how to say about that in name of parameter?

9:05 i am looking some common solution

9:06 mmeix: kwladyka you can hint by naming the parameter m

9:06 qsys: kwladyka: see mmeix: https://github.com/bbatsov/clojure-style-guide#naming

9:06 mmeix: kwladyka or use an understandable docstring for your function (which is a good idead anyway)

9:08 qsys: I hardly every hint the type in the name

9:08 it's too much of a hassle when the 'type' changes

9:09 mmeix: I think if a function has to many parameters, so it becomes unclear which does what, i would be better to split into more functions and compose

9:10 kwladyka: hmm so maybe i should do (fn [m-foo] ... )

9:10 qsys: especially when it's a concrete type, like map, vector, ... no need to hint on the type on them

9:11 mmeix: I haven't seen anything like m-foo ...

9:11 qsys: knowing whether it's sequential or countable or ..., might(!) be interesting

9:11 never saw something like m-foo either

9:11 kwladyka: if not m-now what is your proposition?

9:11 *m-foo

9:12 mmeix: what is the content of your "foo" parameter?

9:12 (not the type)

9:12 kwladyka: for example values for database to insert

9:12 so it can be m-values

9:13 mmeix: I would just use "values" then

9:14 you could write into the docstring: "... expects a map <values> ..."

9:14 if you need guarantees, then you would check for the type, or use something like Schema

9:15 I guess

9:15 kwladyka: just i am thinking about some standards in architecture and i am doing some experiments

9:17 mmeix: "There are only two hard things in Computer Science: cache invalidation and naming things." :-)

9:17 j-pb_: and off by one errors

9:17 kwladyka: mmeix ;)

9:17 mmeix: There's a variation I just found:

9:18 "There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery"

9:18 :-)

9:18 but clojure helps with that ...

9:18 kwladyka: the biggest problem is always state... remember it and do something things depend on this

9:19 mmeix: there are good solutions for this (one and only one source of truth, Om, Re-frame)

9:20 (if in web app)

9:20 kwladyka: even in Om you have state. At that moment i am using Rum in work and i am not very happy with that, because of some limitations but maybe i am doing this wrong.

9:21 mmeix: of course there is state, but in a immjtable world it's relatively easy to think and plan with it, I find

9:21 immutable*

9:39 dysfun: hrm, is there a clojurescript analogue of find-var ?

9:45 kwladyka: dysfun i don't think so

9:56 mmeix: kwladyka wouldn't https://github.com/plumatic/schema help with your plannings?

9:57 kwladyka: mmeix no it makes me feel like OOP :)

9:57 mmeix: ok

9:57 kwladyka: i am just doing experiments in architecture and compare some things

9:57 mmeix: understood

10:01 Somelauw: Inside a macro I'm trying to get the name of a function to be printed. Let's say I write (def f +). Now I want to turn f into '+'. How to do this?

10:59 benjyz1: in Clojurescript i request JSON from a server

10:59 its delivered as {"time" 1454860967241}

10:59 server delivers proper JSON, but I can't parse the data ?

11:00 justin_smith: benjyz1: is that the actual string?

11:00 because that's valid edn, but not valid json

11:00 benjyz1: I'm testing with a tool, which says its valid json

11:00 justin_smith: anyway, if the string is valid json, use js/JSON.parse

11:01 benjyz1: a chrome extension tool

11:02 ok, trying. I'm working with catacumba on the backend... github.com/funcool/catacumba

11:05 frafrafra: ciao

11:05 !list

11:08 mmeix: I worked through the Om Next Tutorial, but I'm not sure about the advantages over re-frame - could it be, that Om Next has it's biggest strength for large and complex apps? Thinking in re-frame seems to be just more straightforward ...

11:09 (ah, should have posted this in clojurescript ...)

11:09 justin_smith: mmeix: I think the main benefit with om next is the data query model

11:09 mmeix: this I understood

11:09 but there is very much complexity upfront, I find

11:10 justin_smith: is managing your data manually and using re-frame simpler?

11:10 mmeix: time will tell, I guess

11:11 right now, backend just delivers simple datasets, main work is in the client

11:11 ok, maybe I should dive deeper into Datalog etc.

11:14 thanks for thoughts

11:18 but I cannot tell how much Parinfer did for a better coding experience for me :-)

11:55 benjyz1: hmmm. js/JSON.parse should work?

11:55 I'm getting back a persistent arraymap, although its an array. weird

11:56 justin_smith: benjyz1: why are you getting a cljs type at all?

11:57 benjyz1: you'right, that's my mistkae. I'm using ajax.core

12:04 python476: hi, I'm reading cljs github wiki, looking for documentation about the (vanilla?) dom interface (object like js/console, js/document, (.-xxx ) form) and am a bit lazy, can anyone link me to a page ?

12:05 justin_smith: python476: it's the js dom interface. You use it with interop syntax, but it's just the dom.

12:05 python476: best docs are the mozdev ones

12:06 python476: unless it's the interop syntax itself you are asking about - Obj.prop becomes (.-prop obj) Obj.method(x) becomes (.method Obj x)

12:06 python476: justin_smith: the interop syntax is probably what I need

12:07 and how many objects are prefixed with js/ ?

12:07 anything in the global scope is the js ns ?

12:07 justin_smith: also the -> macro helps a lot here - o.prop1.prop2 becomes (-> o .-prop1 .-prop2) o.method(x).prop becomes (-> o (.method x) .-prop)

12:08 python476: js/window is usually the global scope

12:08 but yeah, there's js/JSON etc.

12:08 python476: yeah, I have to glue -> usage in my fingers, I often think about it 1min too late

12:09 thanks justin

12:09 justin_smith: np

12:09 python476: just knowing the 'syntax interop' term helps me finding articles from google

12:09 justin_smith: great

12:16 python476: justin_smith: powdertoy gift https://www.youtube.com/watch?v=h4eHgnLFk9k

12:35 terakilobyte: friend piqued my interest in clojure. Still trying to get used to lisp syntax but not finding it ridiculous? Plan on using Clojure for the Brave and True and Web Development with Clojure as my two main resources

12:35 any other good ones I should know about?

12:35 python476: there's no `flip` function in clojure ?

12:36 justin_smith: python476: there's one in eg. flatland/useful and it is easy to write

12:36 terakilobyte: sorry, didn't mean to put a ? after my syntax statement

12:36 python476: yeah I guess it's so easy

12:37 dysfun: #(foo %2 %)

12:37 almost as short as 'flip'

12:37 python476: yeah good point

12:38 justin_smith: (fn [f] #(apply f (shuffly %&)))

12:38 dysfun: you also won't need curry/uncurry because of destructuring

12:40 mmastic: Paul Graham wrote that the codebase for Viaweb was 20%-25% macros. Can anyone resonate with something like that? or maybe such a high percentage doesn't come up anymore these days for some reason?

12:40 dysfun: it's rare for that much of a clojure codebase to be macros

12:41 pg was using common lisp which is a different animal

12:41 python476: mmastic: CL was a bit less regular than more recent lisps and had less abstractions maybe ? leading to more macro-fu than needed today

12:41 (less regular or more complex... don't wanna sound firey)

12:41 dysfun: if you listen to CL fans speak, they'd say it was more regular

12:42 but it's a very verbose language compared to scheme or clojure, and there is definitely more need

12:42 but then again CL is a language where reader macros are commonplace :)

12:42 mmastic: Oh I see. I was a bit surprised because I found myself not really resorting to macros, pretty much at all :P (even when abstracting). So that's normal, I suppose, yeah?

12:42 python476: the side of lisps that scared me the most is the sub-cons-cell values

12:43 a symbol could have many bindings somehow

12:43 justin_smith: python476: like our metadata!

12:43 probably the first metadata system in programming history actually

12:44 python476: good point but it's mentally separated as metadata, not first class programming idiom

12:44 justin_smith: python476: yes, the concept has matured

12:44 they were in the early days, where it was tempting to use it for *everything*

12:44 python476: unless you'd specify function arguments through metadata

12:44 dysfun: clojure is quite refined feeling compared to ma

12:45 most* lisps

12:45 python476: one fact I miss from old lisps is .. lack of literals

12:45 dysfun: you mean that edn supports e.g. sets?

12:45 kwladyka: how to convert using clojure.jdbc uuid string like "d263381c-9a90-4494-8759-c56f6f56a7f0" to uuid in postrges during select? I get Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.

12:45 python476: I'm not at the edn point in my clojure experience

12:46 [] and {} aren't making me feel happy visually or mentall

12:46 y

12:46 dysfun: edn is the syntax clojure uses

12:46 i quite like [] and {} as it happens

12:46 and i don't think i'm alone

12:46 python476: I like my parens in whole bags :D

12:47 dysfun: well common lisp and scheme are that-a-way

12:47 python476: it's backed by a sane principle, which I lauded when Hickey talked about it

12:47 but .. I can't explain I like (vector ... ) and all ((... ((( ))))( ( )))

12:48 dysfun: well clojure has been designed to minimise need for parens, so it's not surprising you don't like it

12:48 personally i like my code with minimal parens

12:48 python476: heh, my parens-avoidance reflex is to run sml

12:49 dysfun: similarly i have c++

12:49 python476: that's for code with maximal ;

12:50 dysfun: yeah, it's quite a different language

12:50 python476: indeed

12:50 and changing a lot since c++11

12:50 dysfun: but i can switch between clojure and c++ pretty seamlessly these days

12:50 oh yeah, c++ before 11 was a clusterfuck

12:50 python476: horizontal gene transfer is hot from fp to mainstream

12:50 dysfun: c++14 is bordering on 'nice' and c++17 if they actually deliver it all will be ace

12:51 python476: some c++ guys aren't fond of it.. I don't understand

12:51 dysfun: somenoe built a clojure-like transducers library for modern c++, which made me laugh

12:51 python476: you get small, readable, typed and native ..what's not to like

12:51 kwladyka: i solve my problem... just add #uuid before...

12:51 python476: laugh ? the steal factor or the quality?

12:52 dysfun: well it seems an odd language to steal bits for c++ from

12:53 python476: transducers are such a nice pattern though

12:53 I wonder what's the next step .. full deforestation and partial evaluation ~_ ?

12:54 dysfun: dif this free wifi weren't so shit i'd share the link

12:54 ah got it http://vitiy.info/cpp14-how-to-implement-transducers/

12:56 python476: odd, (macroexpand '(<macro> ...)) yields (<macro> ...) ~_~

12:56 but with `(when ...)` I get the expanded expr

12:56 (defmacro wait! [b] `(do (js/alert) ~b))

12:56 did I noobed ?

12:57 oops, bodiless

12:59 the c++ transducers reminds me of my early java days trying to bend the syntax to not program in java ~_~

13:58 justin_smith: but transducers are not a syntax, they are an algorithmic building block, which c++ lacked

13:59 perhaps they didn't need because they just use mutable data anyway

14:05 python476: justin_smith: yes, but c++ idioms still aren't really tailored to functional programming and that makes for a bit of a twisted source to look at

14:06 I believe that somehow c/c++ made people do all this in their head and flatten it a large scopes with nested loops

14:06 a lot of c code appear to me as lazy list programming projected onto a register machine mindset

14:06 maybe I'm trying to retrofit a functional hammer ..

14:07 I investigated zippers yesterday, is it commonly used ?

14:08 justin_smith: python476: not sure, I bet searching clojure.zip on http://crossclj.info would be informative

14:08 Bronsa: I wouldn't say zippers are commonly used

14:12 justin_smith: OK, I wonder which is used less, refs or zippers

14:12 I guess there are refs in core, dunno if that skews results

14:24 python476: thanks both of you

14:25 these clojure websites (conj.io, crossclj) etc are pretty nice, are they listed in a central place ?

14:26 oh /r/clojure has many

14:26 justin_smith: python476: those two, github, and clojars, are what I use. There's probably more, I'd like to see that link too.

14:26 oh (checks)

14:26 mmeix: the cheat sheet!

14:26 http://clojure.org/api/cheatsheet

14:27 justin_smith: yeah, conj.io is a fork of that

14:27 r/clojure does have a good set of links

14:28 Somelauw: What is the best way to write out complex formulae without infix notation?

14:28 python476: it's just that I remember urls more than title (conj.io rather than grimoire)

14:29 justin_smith: Somelauw: probably not using clojure... - is the issue the likelihood of making mistakes in translating to prefix, or that you just don't think it looks as nice?

14:30 Somelauw: oh sorry, misread - I typically do it inside-out based on the implicit parens

14:30 mmeix: or maybe threading macros -> and ->> ? (or do I misunderstand...)

14:30 justin_smith: so I translate tightest bindings first (explicit function call, exponentiation), then move out

14:30 Somelauw: justin_smith: In python it looks like this def solve(a, b):

14:30 (a.T @ a).I @ (a.T @ b)

14:31 In clojure like this (defn solve [a b]

14:31 (mmul (inverse (mmul (transpose a) a))

14:31 (mmul (transpose a) b)))

14:31 python476: nods

14:32 justin_smith: Somelauw: there's box infix and postfix (of methods) to translate there, yeah

14:33 mercwithamouth: would i get anything out of reading ANSI Common Lisp that would help with clojure(lisp in general?)

14:33 i'm aware that common lisp isn't strictly functional...but i'd think there would be something good to take away just from the author

14:35 arkh: Somelauw: (-> (transpose a) (mmul) (inverse) (mmul))

14:35 python476: obj.meth == (meth obj)

14:35 mmeix: arkh that's what I meant ...

14:36 justin_smith: missed mmul's second arg both times

14:36 but that's the general idea, yeah

14:37 Somelauw: another issue, I don't know about python, but in clojure if you have (transpose a) in two places in the same function, a is transposed twice, and you might want to use a let block for optimization

14:37 Somelauw: If I haven't made any mistakes it becomes (-> (a transpose (mmul a) inverse) (-> a transpose (mmul b)))

14:38 justin_smith: some extra parens

14:38 (-> a transpose ...)

14:38 what you have there is a noop (-> f) is just f

14:39 unless you wanted (-> (-> a transpose ....) ...)

14:39 Somelauw: justin_smith: not completely sure, but I think in python tranpose is O(1) because it can just change the view of the array

14:40 justin_smith: Somelauw: oh, it's not something that uses CPU? makes sense I guess

14:40 Somelauw: if its O(1) with a low constant, go for it

14:40 mercwithamouth: would i get anything out of reading ANSI Common Lisp that would help with clojure(lisp in general?)

14:41 justin_smith: mercwithamouth: according to the people who wrote ansi common lisp, ansi common lisp is the only "lisp in general"

14:41 I don't recall there being much about immutable / functional programming, but I could be forgetting

14:43 mercwithamouth: justin_smith: yeah common list doesn't really deal with immutability or fp(though you could...to a degree) clojure would most likely be my go to language but lately i've been picking up books related to scheme and CL as well just to see

14:43 if i can even just pick up a few good ideas from it then cool....it was only $8

14:44 Somelauw: justin_smith: just tested it and mutating a-t in python, mutates a too

14:44 justin_smith: Somelauw: cool

14:44 Somelauw: and threading does make the syntax look a bit nicer

14:46 spuz: I'm trying to solve a clojure exercise that asks for a value with the mutable field 'name'. What is the best way to implement this?

14:46 as far as I can tell, all clojure objects are immutable

14:47 justin_smith: spuz: probably wants deftype with a volatile-mutable or something field

14:47 ,(doc deftypes)

14:47 python476: spuz: is it a public clojure website exercise ?

14:47 clojurebot: Titim gan éirí ort.

14:47 justin_smith: ,(doc deftype)

14:47 clojurebot: "([name [& fields] & opts+specs]); (deftype name [fields*] options* specs*) Options are expressed as sequential keywords and arguments (in any order). Supported options: :load-ns - if true, importing the record class will cause the namespace in which the record was defined to be loaded. Defaults to false. Each spec consists of a protocol or interface name followed by zero or more method bodies: pr...

14:48 spuz: yeah it's this one: http://exercism.io/exercises/clojure/robot-name/readme

14:48 see in the test where it calls a function 'reset-name' which it seems it expects to mutate the input argument

14:48 justin_smith: spuz: anyway, full doc string for deftype describes how to make mutable fields

14:49 spuz: justin_smith, thanks, I saw deftype just wasn't sure it was the best way as it warns "Note well that mutable fields are extremely difficult to use correctly"

14:49 and "They are for experts only"

14:49 justin_smith: spuz: now that I look again - they provide tests but no source right?

14:50 spuz: justin_smith, correct

14:50 justin_smith: spuz: if so, you don't need to use a mutable field on a deftype, you could just use an atom or ref or agent, and functions that manipulate that. It would probably have a hash-map in it

14:50 ,(def h (atom {:name "joe"}))

14:50 clojurebot: #'sandbox/h

14:51 justin_smith: ,(swap! h assoc :name "bill")

14:51 clojurebot: {:name "bill"}

14:51 justin_smith: ,@h

14:51 clojurebot: {:name "bill"}

14:51 spuz: ah yeah atoms...

14:51 thanks

14:51 justin_smith: that should be enough to pass their test

14:51 spuz: how do you decide whether to use atoms or deftypes?

14:51 justin_smith: spuz: do I need methods on an object because the lib I use wants to call methods and mutate values

14:52 if yes, deftype might be a good idea, if no, just use a container with a hash-map

14:52 spuz: right so deftype is a bit more like "I need to build a class"

14:52 rhg135: If the deftype will never be shared it's safe

14:52 justin_smith: across threads? sure

14:53 rhg135: But now we have volatile for that

14:53 python476: spuz: nice set of exercices !

14:53 rhg135: So just if you need a named type

14:56 spuz: python476, yeah they are nice. you can see everyone else's solution to a problem after you've submitted yours and comment on/receive comments from others

14:56 and so far they are pretty much just the right level of stupidly simple for me to be able to progress with them

14:56 python476: lots of languages too, Ocaml, even elisp :)

14:57 mmeix: I learned much at 4clojure.com

14:57 python476: spuz: indeed, they're mostly no stress, good to enjoy and stay zen

14:57 mmeix: starts easy, gets really hard gradually

14:57 python476: I don't remember how much of 4clojure I did

15:21 ha, this cheatsheet has a bit of js interop in it http://cljs.info/cheatsheet/

15:22 mmeix: ah, that's additional value ... bookmarked!

15:22 python476: found here : http://swannodette.github.io/2015/12/23/year-in-review/

15:22 it's from the author of parinfer

15:22 (which is still as cute as when it first popped)

15:24 justin_smith: move blocks semantically - we might as well describe the letter to print on the screen instead of the bits representing its pixels

15:24 virmundi: hello. I’m having a hard time idomatically invoking a function on a deftype. The deftype implements a protocol named CRUD. CRUD has a function of (read-by-example [this conn example]). Whenever I try to invoke via (read-by-example instance conn example). This fails with CompilerException java.lang.RuntimeException: Unable to resolve symbol: read-by-example in this context,

15:24 compiling:(/private/var/folders/st/sgtzb_8n213254gzfwtn6t9h0000gn/T/form-init6058469801129634139.clj:1:1)

15:25 If I append a period to read-by-example, it works fine.

15:56 yuung: hey, clojure/lein noob here: i'd like to make a new directory and file in my src/namespace directory. how do i require that file in my src/namespace/core.clj?

15:57 justin_smith: yuung: you can use the :require clause of the ns macro

15:57 yuung: for example, i'd have src/namespace/new_dir/new_file.clj, and i'd like to use that file in core.clj

15:58 justin_smith: (ns namespace.core (:require [namespace.new-dir.new-file :as whatever] ...)

15:58 )

15:58 yuung: justin_smith i see, i'll try that! thanks

15:59 justin_smith, could I accomplish the same with a use statement?

15:59 benjyz1: hi. Datomic has its own query language. what is it called again?

15:59 justin_smith: yuung: this also means taht namespace/new_dir/new_file.clj starts with (ns namespace.new-dir.new-file)

15:59 hfaafb: Datalog!

15:59 justin_smith: yuung: yeah, but we usually prefer to utilize require instead of use

16:00 yuung: justin_smith, i see i see

16:00 benjyz1: oh.. didn't know the language was around since 1977 https://en.wikipedia.org/wiki/Datalog

16:00 this is the same one, right?

16:01 justin_smith: benjyz1: it's a variant, yeah - most things in the clojure world come from a long time ago, but sometimes they are obscure

16:02 benjyz1: just found somebody implement an in-memory databse for the browser which can speak datalog

16:02 justin_smith: om next does that

16:02 also the datomic db uses datalog

16:03 qsys: datascript

16:03 https://github.com/tonsky/datascript

16:03 benjyz1: yes, I was referring to datascript. does om next use datascript?

16:04 justin_smith: benjyz1: I don't think so, but it uses pull notation derived from datalog to bind data to widgets

16:04 benjyz1: AFAIK nobody has really done a kind of clojure/clojurescript framework which operates on data only

16:04 qsys: dunno if om next implements it, or so...

16:05 benjyz1: yes, that's a great idea. I've worked with Meteor which is pure JS.. pretty terrible

16:05 qsys: I'm using rum, which can do om-like things

16:05 and more

16:05 benjyz1: but they have the idea of the same language on client/server. that's very useful

16:05 qsys: unopiniated when it comes to storing state

16:05 benjyz1: instead of sending HTML around, one sends data and the client renders

16:06 didn't know rum..

16:06 qsys: same author of datascript, pretty basic - much more basic than om

16:07 benjyz1: qsys: interesting, thx.

16:07 qsys: this means: more work for you... (but more flexibility)

16:09 yuung: justin_smith if i wanted to load that new file into the repl, what should I do? `(require '[namespace.new_dir.new_file :as new])` returns nil, but (new) throws an error

16:09 justin_smith unable to resolve symbol error*

16:09 justin_smith: yuung: (new/foo) where foo is something defined in that ns

16:10 yuung: justin_smith ahhhh i see

16:10 justin_smith thanks a lot

16:10 justin_smith: there's other tools in the repl too

16:10 (dir foo)

16:10 (ns-publics foo) to get at the actual data

16:11 yuung: justin_smith, ah, nice

16:11 justin_smith: (ns-refers 'foo) and (ns-interns 'foo) to get its full scope (and it's (ns-publics 'foo))

16:13 yuung: justin_smith, if i wanted to create a new namespace within a directory, and have each of the files in that directory start with (ns namespace.new-dir), would that be possible?

16:13 justin_smith: yuung: no, the ns has to match the file name

16:13 yuung: justin_smith ah okay

16:13 justin_smith: for require to work at least

16:13 there's also load-file

16:14 but best to use require and have a compatible layout unless you have a good reason to do something weird like load-file

16:15 yuung: justin_smith gotcha

16:15 justin_smith thanks! you've helped a bunch.

16:15 justin_smith: np

16:16 benjyz1: justin_smith: have you been doing LISP before clojure?

16:17 (if I may ask ;)

16:17 justin_smith: benjyz1: yeah, I did some common lisp, and some scheme. ocaml too which is very relevant because ml uses immutable data

16:17 this was all hobby level only

16:17 benjyz1: I remember very distinctly I wanted to learn LISP

16:17 justin_smith: clojure was my first/only professional lisp

16:17 benjyz1: and read Paul Graham's essays

16:17 justin_smith: benjyz1: I read them too, yes

16:18 and some of his books are good too :)

16:18 benjyz1: but it seemed so obsure, and I knew nobody he knew the lagnuage

16:19 2 years ago I decide I have to bite the bullet, or otherwise I'll just programming forever ^^

16:19 *hate

16:20 I wonder why it took so long for a LISP to break through. I've never heard of anyone using CL in an enterprise e.g.

16:20 justin_smith: benjyz1: libraries and tooling - having such easy access to all of java is huge

16:20 TEttinger: NASA, yeah, but not much enterprise use until Clojure

16:21 justin_smith: I mean most java stuff is easier to use in clojure than it is in java

16:21 TEttinger: that's what I always say too :)

16:21 mgaare: benjyz1: perhaps the most prominent example was ITA

16:21 TEttinger: mgaare: are they still in business?

16:21 mgaare: TEttinger: acquired by Google

16:21 justin_smith: benjyz1: even just pragmatically, you can swap out one java library for a clojure library in a java ecosystem, and the enterprise are all using java

16:21 TEttinger: I don't know the name

16:21 deepmind people?

16:22 mgaare: Their stuff powers google's flight search now, I believe

16:22 clojurebot: excusez-moi

16:22 benjyz1: Tettinger: deepmind uses Lua

16:22 justin_smith: benjyz1: by comparison sneaking common lisp into an app is much harder (unless you are doing microservices I guess)

16:22 mgaare: TEttinger: ITA was also (still is? not sure) the backing engine for Orbitz

16:23 benjyz1: justin_smith: I'm trying to solve some quite hard problems and Clojure is really the only option

16:23 TEttinger: s/Orbitz/everyone

16:23 used by travel companies such as Bing Travel, Cape Air, CheapTickets, Kayak.com, and Orbitz, and by airlines such as Alitalia, American, ANA, United Airlines, US Airways, and Virgin Atlantic.

16:23 benjyz1: but it took a while to get there. I've been trying to use ZeroMQ as a kind of distributed system thing

16:24 TEttinger: benjyz1: woah really?

16:24 mgaare: I thought ZeroMQ was for IPC, not so good for distributed?

16:24 TEttinger: the lua thing surprises me

16:25 mgaare: (other than that sub-class of "distributed" that runs on a single machine)

16:25 justin_smith: mgaare: "Carries messages across inproc, IPC, TCP, TIPC, multicast."

16:26 benjyz1: mgaare: I honestly don't know what's good for ^^ it promises a lot of performance for default use-cases. highly optimized, but from language perspective not sound

16:26 its used by stock exchanges to distribute data e.g.

16:26 TEttinger: Google's competitor Facebook has also been working on their own Go-playing system darkforest, based on combining machine learning and tree search.[18][14] Although a strong player against other computer Go programs, as of early 2016, it had not yet defeated a professional human player.[19]

16:27 benjyz1: Tettinger: https://github.com/kuz/DeepMind-Atari-Deep-Q-Learner/blob/master/dqn/NeuralQLearner.lua

16:27 TEttinger: that's kinda sad

16:27 mgaare: Ok, I must have been thinking of some specific use case I read

16:27 TEttinger: oh cool

16:27 justin_smith: benjyz1: what does "from a language perspective not sound" mean? there are versions written in java and c# and c++, bindings for python, java, php, ruby, c, c++, c#, Erlang, Perl...

16:28 TEttinger: ahhh it uses Torch benjyz1

16:28 amalloy: IME it usually means "i personally don't like it"

16:28 TEttinger: Torch7 is a big thing now I guess, I knew it had GPU-based neural network stuff

16:28 benjyz1: justin_smith: what I mean is this.... it enforces really a C/C++ programming model

16:29 justin_smith: oh, so regardless of language from which it's used, it's an imperative api?

16:29 benjyz1: and impossible to change things under the hood. you get a big binary which you can't change

16:29 I guess the idea you have these messaging patterns and then connect different components

16:30 justin_smith: benjyz1: callback based, or?

16:30 benjyz1: but clojure/async is much more powerful

16:30 Request-Reply, Publish-Subscribe, Router-Dealer

16:31 and each use-case is optimized

16:31 its really weird. e.g. it hides IP addresses from user-space

16:31 so basically only for internal networks not internet.. anyway, I'm glad I moved away from it

16:34 what I found also that actors and scheme were related. ZeroMQ is an attempt at doing actors

16:35 justin_smith: benjyz1: as in actors were notably implemented in scheme?

16:36 benjyz1: "Gerald Sussman and Guy Steele then took an interest in Actors and published a paper on their Scheme interpreter in which they concluded "we discovered that the 'actors' and the lambda expressions were identical in implementation."

16:36 https://en.wikipedia.org/wiki/History_of_the_Actor_model#Scheme

16:36 Bronsa: mpc

16:37 justin_smith: benjyz1: man, the late '70s was a time when "we discovered x are equivalent to foo" for all foo was published

16:37 wait sorry, lambdas for all x err... nevermind

16:37 benjyz1: lol. to young for that. these days its like all computer science before 1990 is forgotten

16:38 so Javascript rocks!!?!

16:38 which is a language written in 10 days

16:38 justin_smith: benjyz1: smart kids read papers from before they were born, even in CS

16:38 late '70s was when I was born

16:39 I still have things to learn from papers of that era

16:39 python476: I'd like to grasp continuation and cont-based backtracking

16:40 benjyz1: I think what you say applies a lot to 1900-1930 too

16:40 Russell, Frege, Whitehead

16:40 justin_smith: benjyz1: oh, absolutely

16:40 benjyz1: not strictly computer science though.

16:41 justin_smith: even Norbert Wiener, Claude Shannon...

16:59 DynamicMetaFlow: What would be some good papers to read from that era?

17:04 benjyz1: I recently read some works of Shannon

17:05 A mathematical theory of communication.

17:05 Turing on computable numbers

17:05 very worth reading original papers IMO

17:10 justin_smith: DynamicMetaFlow: there's a list on github "papers we love", https://github.com/papers-we-love/papers-we-love

17:12 DynamicMetaFlow: but I agree, some of those original papers from the early history are great

17:12 shannon's mathematical theory of communication being just an example

18:40 python476: I think I'ma use clojure repl to live test Java code ~_~

18:45 it's already proving useful

18:45 justin_smith: python476: yeah, clojure is a great lib for using java

18:46 python476: it's a Java 'only' MOOC

18:46 clojure java interop comes to mind in a clojure project

18:47 but now I just clicked

18:48 doesn't make my code less buggy though <o/

18:56 Somelauw: hmm, why is there no transient 'update!' like there is 'assoc!'?

19:02 DynamicMetaFlow: Thank you

19:04 justin_smith: Somelauw: because nested transients aren't really a usable thing

19:04 oh, but update not update-in...

19:05 Somelauw: yep, I was surprised update! is missing

19:15 justin_smith: Somelauw: given the source of update, update! should be easy to write

19:19 Somelauw: I just saw the source. I used to hope update would avoid the double key-lookup.

19:20 justin_smith: ,(defn update! [m k f &args] (assoc! m k (apply f (get m k) args)))

19:20 clojurebot: #error {\n :cause "Unable to resolve symbol: args in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: args in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: args in this co...

19:21 justin_smith: ,(defn update! [m k f & args] (assoc! m k (apply f (get m k) args)))

19:21 clojurebot: #'sandbox/update!

19:21 justin_smith: ,(-> {} transient (update! :a assoc :b :c) persistent!)

19:21 clojurebot: {:a {:b :c}}

19:22 Somelauw: (persistent! (update! :a (fnil inc 0) (transient {})))

19:22 ,(persistent! (update! :a (fnil inc 0) (transient {})))

19:22 clojurebot: #error {\n :cause "clojure.lang.Keyword cannot be cast to clojure.lang.ITransientAssociative"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to clojure.lang.ITransientAssociative"\n :at [clojure.core$assoc_BANG_ invokeStatic "core.clj" 3259]}]\n :trace\n [[clojure.core$assoc_BANG_ invokeStatic "core.clj" 3259]\n [clojure.core$assoc_BANG_ invoke "...

19:22 justin_smith: Somelauw: missing the main arg

19:23 or wait, just in the wrong order

19:23 Somelauw: ,(persistent! (update! (transient {}) :a (fnil inc 0)))

19:23 clojurebot: {:a 1}

19:26 Somelauw: ,(persistent! (update! (transient {}) :a fnil inc 0))

19:26 clojurebot: {:a #object[clojure.core$fnil$fn__5727 0x4e893b51 "clojure.core$fnil$fn__5727@4e893b51"]}

19:28 justin_smith: Somelauw: (fnil nil inc 0) ; this defines a function

19:30 Somelauw: I see. It looked so tempting.

19:31 python476: is there a (doto-n <init> <f> ... <h>) that returns the result of (h <init'>) ?

19:32 I need a blend of doto and ->

19:33 justin_smith: (-> init (doto f ...) h)

19:33 python476: I must have messed something up, I tried this earlier :)

19:55 lode-mooner: Let's say I'm working on a copyrighted closed-source project with leiningen. What am I supposed to put in my project.clj file under :license?

19:57 justin_smith: lode-mooner: you can leave the key out, or specify "Copyright Me 2016 all rights reserved"

19:57 no automatic license

21:55 slester: hi there! lein repl is choking when I have :main set... any idea what I'm doing wrong? "Could not locate main__init.class or main.clj on classpath."

21:55 justin_smith: slester: well, what's your :main setting?

21:56 slester: lein run, however, does work. lein repl works when I comment out the :main

21:56 justin_smith, it's boring, `:main amiss.core/main`

21:56 justin_smith: slester: it should point at a namespace, not a function

21:57 slester: I assume lein run is working because there are top level side effects in amis.core

21:57 slester: oh, is that new or did I mis-copypasta from somewhere

21:57 it's not actually calling main ever in core.clj

21:57 so I should call the main function myself?

21:57 in core.clj?

22:01 justin_smith: slester: you specify :main amis.core and then lein run will call amis.core/-main

22:01 sounds like maybe you just have top level side effects in amis.core?

22:04 slester: justin_smith, ah, I actually didn't have the - in front of main. Thanks, all fixed up :)

22:05 justin_smith: slester: yeah, it's picky about that

22:06 slester: but yeah, if you put amiss.core/main into :main, lein will happily run it, but repl chokes (which makes sense now)

22:47 tolstoy: Huh. Using Electron seems neat. Build for OSX and you get a .app file with everything you need.

22:47 For windows, you get a directory with lots of stuff and an exe which isn't stand-alone.

22:51 lockdown: .app are directories

22:55 tolstoy: Yes. Handy. I was hoping that somehow all the "node.dll" stuff would be bundled into a single exe file. Yes. Ignorant of windows.

22:57 I suppose the assumtion is that you'd never install just an EXE. It's always an installer.

23:26 slester: is there a more idiomatic way of doing (update-in state [:player 2] #(partial apply conj) '(1 2))?

23:29 justin_smith: (update-in state [:player 2] conj 1 2)

23:32 slester: justin_smith, the thing coming in is a list, that was just an example :(

23:33 justin_smith: slester: my thing does what yours does

23:33 oh you mean the '(1 2) is the form you get?

23:33 slester: yeah

23:33 justin_smith: (update-in state [:player 2] into l)

23:34 into is basically an optimized apply conj

23:34 slester: justin_smith, yesss, thanks

23:49 tolstoy: Interesting. Using CLJS with Electron to build a tiny cross platform network diagnostics tool. Works well.

23:50 BUT, when I run it on windows, it works the first time, when all tests (socket connects, basically) timeout any subsequent time.

23:50 If I copy the same bits over the top of the old bits and start it up, it works again.

23:51 Sometimes just re-starting it makes it work. Maybe something's not "resetting" on Windows. Oy.

23:51 Regardless, using CLJS with Electron is a pleasure. ;)

23:52 justin_smith: tolstoy: perhaps it's about some child process that isn't exiting properly - on a *nix child processes are reaped but not on win

23:53 tolstoy: justin_smith: Even using node? Yeah, it's weird.

23:53 Maybe it's these VMs I downloaded from MS for IE/Edge testing.

23:53 justin_smith: tolstoy: I'm just talking about the OS level behavior, that's a big win/nix difference

23:54 the other big ones being you need something else other than pipes (and there could be a bug there) and file locking is implicit

23:54 tolstoy: Surely node and Electron aren't that janky....

23:55 justin_smith: on nix you can use an unlinked file, it's perfectly legit to use until the last program that has a handle to it exits. You can also remove a file some app is using, and the app will keep using it.

23:55 tolstoy: just citing known differences, I clearly have nowhere near enough info to identify the real problem

23:55 tolstoy: I hear you.

23:56 Could be the way I'm invoking it, too.

23:56 I've got a directory filled with DLLs, resources (the JS code), and an EXE. I click on the EXE and presume it's loading in the DLLs as necessary.

23:56 justin_smith: tolstoy: I am not surprised to hear of any dev-centric tooling being totally bizarre on windows, since relatively few devs use windows any more

23:57 compared to the recent past

23:57 tolstoy: justin_smith: Supposedly this is the same thing Atom is using. But who knows.

Logging service provided by n01se.net