Fork me on GitHub
#beginners
<
2017-05-21
>
matan02:05:23

Thanks for the defrecord discussion 👍

matan02:05:54

How do you direct a http://clojure.io writer to a given path, in an OS agnostic way? I couldn't find a way with clojure.csv

matan02:05:19

Looks like one has to go all the way down to Java libs 🙂

vitruvia14:05:54

is there any tutorial on developing AI with clojure?

john14:05:09

Not generally, but Giga Squid has a number of good AI related articles.

vitruvia14:05:42

really? Isn't clojure one of the most used AI languages?

john14:05:12

Negative. Perhaps one of the more "expected to do well"

john14:05:44

Perhaps you're thinking of incanter

john14:05:06

Which provides an R-like statistical environment

john14:05:44

A tool for data scientists, which is pretty popular. But I wouldn't say Clojure is yet "one of the most used AI languages" People are building the tools now.

vitruvia14:05:58

I was just looking for a language to start learning AI and I saw some articles mention lisps were one of the best choices

vitruvia14:05:10

and I saw some mention that clojure might be a good idea

vitruvia14:05:50

I know some python and I know it is very popular with AI, but I don't know. I'm really enjoying clojure xD

john14:05:13

they're good choices for playing. And Clojure is a good idea for playing. All the big stuff is built in python though. On top of high performance bindings.

john14:05:26

I know right 🙂

john14:05:39

def check out that article I linked

john14:05:48

and Incanter, for data sciencey stuff

vitruvia14:05:21

I really love python, too, so if I have to start learning AI with that I don't mind, but if there was some good tutorial on clojure I would have used it. I'll check the article and Incanter, thanks!

john14:05:22

Depends on what you mean by "tutorial on AI." It's a diverse field. Carin has made tutorials on a number of topics.

john14:05:53

She made a genetic evolution example with clojure spec, which ended up being pretty rad.

john14:05:29

And cortex is looking pretty promising

vitruvia14:05:58

Well I'm just looking to learn the basics for now

john14:05:12

And if by AI you mean data science, there are bunch of older tutorials on that, I believe.

john14:05:40

If you're super excited about the deep learning trend, you'll want to jump into cortex. It's a super fresh project, with some rough edges. But Carin showed it performing decently in Kaggle, in that article I linked, I believe.

vitruvia14:05:43

I just finished reading the article and I realize I still need to learn more clojure basics

vitruvia14:05:52

but I will keep an eye on cortex

vitruvia14:05:10

I think I might take in intro to AI course on MIT OCW or EdX too before I try this

john14:05:32

naaah, you got this bro 🙂

john14:05:10

I'm kidding

john14:05:25

def take all the classes you can on it. It's fun stuff

john14:05:48

There's not enough written in Clojure yet for you to properly "learn AI" anyway

john14:05:06

But I think most of AI is still "R" like data science, and not just neural networks. So you might be able to get a lot of traction with tutorials on Incanter. And translating examples over from R.

john14:05:45

I believe a number of those MOOCs use R and python for their "AI" courses.

john14:05:47

Also join #data-science as it's been getting some traffic recently

vitruvia14:05:22

Cool. Yeah I'll take it slow. I feel like I still need to know the basics well and I've started with clojure what... 3 weeks ago? I'll definitely keep an eye out for the things you mentioned, though.

john15:05:44

Another reason you may have thought that clojure was one of "the most used AI languages" is because it is one of the best "data oriented" languages and it is used for wrestling data in a lot of places. So everyone expects it to do well in data science. Just needs to penetrate academia more.

john15:05:48

Yup, good luck!

lepistane16:05:52

anyone here good at sql?

akiroz16:05:52

define "good" 🙃 (just ask away~ maybe someone will answer)

dpsutton17:05:28

@vitruvia check out peter norvig's classic http://norvig.com/paip.html which is AI in common lisp. this is a symbolic version of AI which as i understand is far from what modern trends are doing however

dpsutton17:05:10

modern AI is statistics and machine learning rather than the previous symbolic and logic version, but i have lay person's understanding and am not an expert by any means

vitruvia19:05:32

@dpsutton thanks! I suppose there are different techniques on AI, shouldn't hurt to study some of the older ones

lilactown20:05:09

i'm having trouble with core.async and a channel that outputs another channel

lilactown20:05:29

i'm using https://github.com/jarohen/chord in clojurescript to create a websocket connection, and the initial ws-ch function returns a channel, that once connected outputs another channel, that you can then receive messages from

lilactown20:05:19

I want to essentially pass around that message channel so I can potentially merge it/filter it/etc., however it's trapped in the go block that creates the initial connection

noisesmith21:05:51

lilactown: I don't understand what you mean by trapped here

lilactown21:05:10

mm yeah, so in the example you helped me with yesterdya:

(defn create-stream
  [handler]
  (let [poison (chan)]
    (go (let [messages (<! (create-ws-connection "url"))]
      (loop []
        (let [[{:keys [message] :as m}] (alts! [messages poison])]
          (when m
            (handler message)
           (recur))))))
  poison)

lilactown21:05:07

^ that's pretty much my current code, but I want to be able to return a channel that outputs the messages instead of using a callback

lilactown21:05:56

does that make sense?

noisesmith21:05:30

then replace the when block with (if message (>! out message) (close! out))

noisesmith21:05:42

then make sure consumers of out do the right thing if it closes

lilactown21:05:50

but I have to keep the poison channel around too, right?

lilactown21:05:13

like I think I could just use pipe, except that I want the consumer to be able to close the websocket

noisesmith21:05:53

right - you can just return both channels - or, better yet, have the consumer pass the out channel in

noisesmith21:05:05

then they can decide what buffering they need or transducer etc.

lilactown21:05:57

oh that's better 😅

lilactown21:05:10

I like that, it feels much cleaner than returning two channels. thanks!

lilactown20:05:23

the solution I've come up with thus far is to create a proxy channel, but I'm not sure how to then be able to close the message channel without having another channel lying around that acts as a poison channel

vitruvia20:05:22

How do you map a two argument function? I have to check if a book has all the awards in a list of awards, I already have a has-award? function that checks for a single award, but (map (fn [x] has-award? lord-of-light x) [:hugo :world-fantasy]) doesn't work as intended

lilactown20:05:01

has-award? takes two arguments?

vitruvia20:05:24

yes book and award

vitruvia20:05:39

but I want to test a list of awards on the same book (which is still an argument because it must work for different books)

lilactown20:05:47

(map (fn [x] (has-award? lord-of-light x)) [:hugo :world-fantasy])?

lilactown21:05:15

your function body wasn't wrapped in parens

vitruvia21:05:30

still messing those up

lilactown21:05:30

you can also, if you want, write has-award? to return a function that checks for a specific book

john21:05:16

You can partition the input stream into doubles

lilactown21:05:47

@john what do you mean?

john21:05:10

If you want to consume a sequence in groups of 2, I mean

john21:05:44

Maybe not what you need. You probably don't have [thing1 thing2 thing1 thing2 thing1 thing2]

john21:05:08

But if you do, and thing 1 and thing 2 were book and award, and you need to process each in pairs, you could (partition 2 [1 2 3 4 5]) => ((1 2) (3 4) (5)))

vitruvia21:05:41

in this case

vitruvia21:05:49

I have just 1 book and a list of awards

vitruvia21:05:56

but this 1 book could be anything that the tests requests

vitruvia21:05:01

So i have to take it as a variable

vitruvia21:05:11

@lilactown I'm not sure what you mean. This is my has-award? function:

(defn has-award? [book award]
  (let [aw (:awards book)]
    (contains? aw award)))

lilactown21:05:46

(defn has-award? [book]
  (let [aw (:awards book)]
    (fn [award] (contains? aw award)))

lilactown21:05:44

^ has-award? now returns a function to check the awards specifically for book

vitruvia21:05:52

oh I think that is actually closer to what the exercise wants

vitruvia21:05:13

that's interesting

lilactown21:05:04

e.g. (has-award? lord-of-light) returns a function that will return true for any award you pass in that lord-of-light has

lilactown21:05:26

that's what's great about passing around functions as values 😄

lilactown21:05:29

you can then use it in map like so: (map (has-award? lord-of-light) [:hugo :world-fantasy])

vitruvia21:05:56

clojure is crazy

vitruvia21:05:03

in a good way

vitruvia21:05:07

thanks again