Fork me on GitHub
#clojure
<
2016-11-29
>
rmuslimov00:11:34

May I get an advice of application design? I have few defrecord types as client for stateful integrations (stateful means I have to count requests were made, store session token, etc. on my side). My first naive implementation have all this fields as fields of defrecord and each time I made request to external system I returned new instance of this defrecord. Problem here, that I have to care about it, it looks like ;; main atom (def sessions (atom {})) ;; init client session (swap! session assoc :session-key (new-sabre-client)) ;; run request to external system (let [{:keys [client response] (invoke (get @sessions :session-key) {:param :param})}] (swap! session assoc :session-key client) response) I want to use simple interface like: ;; Difference here is that defrecord is not changing (let [session (new-sabre-session)] (invoke session {:param :param}) (invoke session {:param :param})) So, here is the question: is managing state in external atom like structure is good idea?

rmuslimov00:11:47

or may be using deftype with mutation, will be good idea, just update session-info after each call

rmuslimov01:11:55

Joy of clojure says: “We won’t go into it here because using such classes is almost never the right solution"

iku00088801:11:32

I think the trend of managing stateful resource is using things like Component/Mount over atoms (Of course I am blindly assuming you don't know them... Sorry if you know already...)

rmuslimov01:11:57

Yea, I know about them however I can’t imagine how use them here. My problem is that calling method of some defrecord shoud return some value, and it also changes defrecord at same time

rmuslimov01:11:31

so, return map with two items (new defrecord and value of method) seems too ugly for me

rmuslimov01:11:55

because I need to replace old defrecord with new one, after each function execution

iku00088801:11:40

That was my suspicion... Definitely a hard problem

rmuslimov01:11:59

I think it should be simple, I believe my experience just not enough

iku00088801:11:41

So in other words, you want that defrecord to take care of updating itself?

iku00088801:11:09

Based on the result of invoke?

rmuslimov01:11:39

I just want to store somewhere inside of defrecord and don't expose outside of it

iku00088801:11:12

Oh, like lexical closures, perhaps?

iku00088801:11:57

Guy sitting next to me (Expert) says Atoms are a good idea, (should start/stop with component, however) so I guess you are on the right track on that part...

iku00088801:11:11

So just need to figure out how to make the defrecord update itself, I think?

rmuslimov01:11:15

so, let’s suppose we have an atom, we generate session-key there as key and consider it as defrecord

rmuslimov01:11:57

each time I call invoke I have to swap! session-key with new state of my connection

rmuslimov01:11:46

defrecord will be as constant, but whole state will live in atom associated with session-key

iku00088801:11:33

Keeping all the state in the atom sounds sane.

iku00088801:11:24

(And yeah, sorry for not being much helpful...)

Thomas C Lindsey01:11:19

@rmuslimov : can you create a function that returns a function that closes over the atom?

donaldball01:11:15

@fiddlerwoaroof: I cobbled together something to auth against google using openid recently. Friend and buddy are clojure libraries that want to help with that, but I found that using open(id|auth|connect) requires such integration with your web routing and persistence layers that it’s both easier and simpler to roll your own. Failing that, you might also consider auth0 or a similar service.

rmuslimov01:11:38

@tlindsey I didn’t get the idea,

Thomas C Lindsey01:11:56

@rmuslimov : If I were approaching the problem my first pass would be creating a function that is bound to lexically closed over atom. In that way there is no real global state you can point to, you just have a function that updates the closed over atom.

rmuslimov02:11:14

that’s may be a good idea

rmuslimov02:11:14

the lack of this approach, is that I limited to functions I can implement

rmuslimov02:11:32

let’s say I’d like to implement invoke2

Thomas C Lindsey02:11:25

@rmuslimov : it should still work, finding the right boundaries for function composition might take a few refactors. In the good old days of CLISP this type of solution was quite common.

rmuslimov02:11:47

thanks, appreciate your help

Thomas C Lindsey02:11:22

yw — I hope you find a solution that works for you. Good Luck.

hl2zip03:11:37

Hi, I am getting started with Boot and I was curious if there is a way to create new project with boot similar to lein. Thanks!

olslash04:11:06

wondering if someone can help me correct my mental model about records

olslash04:11:25

is there a reason to use a record over a plain map if you're not supplying any implementations: like (defrecord Foo [a b c])... because if i use the nonpositional map->Foo it doesn't enforce that keys have to exist or that extra keys can't exist

olslash04:11:37

is there another construct that gives you a guaranteed keyset and ignores keys not in the set?

olslash04:11:54

ive hacked something like this to strip extra keys

(defn make-image [image-map]
  (-> image-map
      (select-keys (map keyword (Image/getBasis)))))

olslash04:11:19

records ive used in ie immutableJS just ignored nonspecified keys

dpsutton04:11:44

@olslash I've done an implementation like this to ensure all keys are present

olslash04:11:54

cool, that seems like the other half

olslash04:11:27

i guess a record is still the correct construct

olslash04:11:54

maybe a defrecordstrict

seancorfield04:11:59

@olslash This blog post (and flowchart) helps fill in the motivation for different Clojure types https://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

olslash04:11:45

oh this is really good thanks

lmergen05:11:26

what would be the way to test whether a string is "printable" in clojure ? as in, whether it contains only ascii/utf-8 characters ?

lmergen05:11:01

i was thinking that maybe parsing the input as utf-8 would suffice

pastafari05:11:21

@lmergen wouldn’t a string be “printable” if theres a typeface that knows how to print it?! Are you trying to figure out if it only contains “English” chars?

lmergen05:11:01

@pastafari i'm trying to do http request/response body logging, but i do not want to log binary data

pastafari05:11:53

@lmergen ah ok, and the shape of the data is not known ahead of time?

lmergen05:11:02

not necessarily no

lmergen05:11:19

i could check for a gazillion of content types, but i'd rather just have a simple predicate

pastafari05:11:19

hmm, so perhaps a regex is the way to go?

lmergen05:11:35

hmm yeah, but that might fail on valid utf-8 or chinese or whatever

lmergen05:11:57

i guess using that utf-8 parsing strategy is a valid approach, though

lmergen05:11:46

ah wait, i can probably use a fancy string lib like funcool/cuerdas for a useful predicate

pastafari05:11:12

there’s some useful character classes in there

pastafari05:11:49

and i always re-read Joel Spolskys blog when dealing with strings: http://www.joelonsoftware.com/articles/Unicode.html

lmergen05:11:06

haha yeah, this is exactly why i wanted a better way to distinguish "real" binary data from readable text in some weird character encoding set

lmergen05:11:24

guess probing the content type is the best way to go

roelofw06:11:33

One question. I m trying to make a program which reads data from 3 external urls. The last two depends on numbers(ids) I read from the first url. Is it wise to store the data in a record. And how to a update a record with the new data I recieved from the last two urls

jrheard06:11:09

here’s a sketch:

(let [foo (ids-from-url url-1)
    bar (fetch-url (url-2-from-ids foo))
    baz (fetch-url (url-3-from-ids foo))]
    ; do something - perhaps return a map like {:foo foo :bar bar :baz baz}, or something else
)

jrheard06:11:52

i don’t know if a record is necessary - you can certainly use one if you want but i’d personally store them in a vector, like [an-id another-id a-third-id], because that seems simpler to me

jrheard06:11:36

i may have misinterpreted what you meant by “the data” - on rereading your question, i think you meant all of the data, not just the ids from the first url

jrheard06:11:00

in which case sure, use a record or a map or whatever you like

roelofw06:11:39

I need for every painting this data : id, title, description, date, collection, colors and a url where a image can be found

jrheard06:11:44

i think i follow - if it were me, i’d use a map and clojure.spec, but you could also use a record - if you wait to create the record until you’ve got all of the necessary data, it should be pretty straightforward

jrheard06:11:04

i don’t use records often, so i don’t have a good answer for your question of how to update a partial record with new data, sorry!

roelofw06:11:53

@jrheard no problem, thanks for thinking with me

seancorfield07:11:00

That gives you good advice on whether a record is necessary (from what you've described, I'd say "no" in your case).

roelofw07:11:16

Sorry . I missed it . Thanks for posting again @seancorfield

roelofw07:11:41

@seancorfield oke, from that it seems I need a map

roelofw07:11:30

I would be then a map of map or a vector of maps

roelofw07:11:36

so I think It would be somethlng like this ( { id: 1 { :title "my own painting :date 21-01-2010 ,,, } id : 2 { .... } }) and so on

roelofw07:11:51

@seancorfield is this a right idea ?

seancorfield08:11:10

@roelofw: map of map is good if you're looking things up by a specific key, vector of map is good if you're filtering by some predicate.

roelofw08:11:28

I think I need the last for the output

seancorfield08:11:31

If you mostly just need a collection of paintings then vector of map is probably sufficient. You can always build a map of map from it if you need key-based lookup as well.

seancorfield08:11:11

Past my bedtime but I'll be around tomorrow to answer questions :)

roelofw08:11:13

Then I have to think how I can update the map if new data is known

roelofw08:11:22

Good night

creese09:11:40

Do plugins have access to namespaces in the project they are required? I want to create a plugin to output JSON from a var defined in the project.

creese09:11:12

I think the answer might be "No" because I get java.lang.Exception: No namespace: foo found for ns-resolve when run as plugin. It works when run as a lib.

creese10:11:31

I've created a sketch of what I want to accomplish: https://github.com/creese/lein-avro-compose

fabrao13:11:31

Hello all, is there any way to use eval passing local variable ?

(let [variable "string"] (eval (read-string "(println variable)"))) 
?

ayato_p13:11:10

@fabrao

(let [v "string"] (eval `(println ~v)))
?

fabrao13:11:57

@ayato_p if I want to change println to be dynamic?

fabrao13:11:30

that´s because I use it from string

rauh13:11:05

@fabrao There is other people here who know the glory details as to why, but: You can't access those local bindings (created with let), but you can access vars, so you could use with-local-vars

roelofw14:11:20

Why do I see here a object :

thegeez14:11:50

The treading macro ->> is misplaced within the anonymous function #(...), try making a function (defn read-single-painting [id] .. get http req ..) and use that within read-daata_painting. That way you an check that read-single-painting works, before putting it in the map

agile_geek14:11:54

Also you are mapping the result of (println ....) which is nil over no collection (thus resulting in a transducer) and simply returning id_list as your parens are in the wrong place.

yenda16:11:57

did anyone tried to have round-trip of keywords as value in a map while serializing/deserializing json with cheshire ?

pesterhazy17:11:40

@yenda, the problem to watch out for is that keywords can contain spaces, but keyword literals (`:my-keyword`) do not

pesterhazy17:11:52

but your use case doesn't sound like it would be affected by that

pesterhazy17:11:49

also when keywordizing values (as opposed to keys), you usually don't want to keywordize all values, e.g. there may be a name or description attribute that should always be a string

yenda17:11:58

I used a custom encoder to keep the semi-colon when encoding keywords but there doesn't seem to be a way to do the same to decode strings

hiredman17:11:00

json doesn't have keywords

yenda17:11:07

yes but youcan consider strings starting with : as keywords

baptiste-from-paris17:11:37

Hello guys, does anyone have this two information concerning Stuart Halloway core.async youtube video => 1) Where are the slides ? 2) What tool does he use to draw process diagrams (around 46 min)

Alex Miller (Clojure team)18:11:23

I’m not watching the video but I’d bet some money that the tool is omnigraffle

baptiste-from-paris18:11:57

ok, I'll have a look then

saeidscorp18:11:35

why most of known clojure programmers use Mac? :thinking_face:

saeidscorp18:11:04

at least most of those who give talks...

poooogles18:11:28

Decent hardware, unixy...?

bfabry18:11:40

I think most programmers who give talks use macs these days, unless it's a .NET ecosystem talk/meetup/conference

bfabry18:11:02

definitely the way it is in ruby land

saeidscorp18:11:28

but personally I get really excited when I see someone giving a talk with live coding on a Linux box!

saeidscorp18:11:33

@bfabry really? I never watched any ruby talk...

tbaldridge19:11:36

@saeidscorp I think it's holdover from the days where running Linux on a laptop was a huge risk (most stuff didn't work) and OS X is more Unix than even Linux is. So since most production servers were Linux it was simple enough to code on OS X and deploy to Linux.

tbaldridge19:11:32

I love my Mac Book Pro, but the new hardware is crap, so we'll see what happens next time I need to upgrade. I just wish I could get MBP quality hardware with Linux pre-installed and fully supported.

saeidscorp19:11:41

aside from that risk, which was really a risk those days, OS X is not much unixy, I think. yes it's based on unix but that freedom in not present in its philosophy. Linux? you can literally do whatever you want with it. 😁

jgh19:11:22

it's close enough to make building for linux on a mac feasible unless you're using linux-specific stuff. There are always VMs too anyway. I like the build quality of MBPs and using Windows feels like using a rube goldberg machine sometimes

bfabry19:11:56

@saeidscorp it comes with a bash terminal and a unix-like fs, which is about 90% of what programmers are looking for

jgh19:11:02

our codebase at work is C++ with support for macos/linux/windows/android/ios, we do all of our development on macs because they give us the least amount of headaches.

tbaldridge19:11:34

And it matters even less with Clojure where the JVM is involved. I've worked on systems were we developed on OSX and deployed to Solaris. So for me it's always come down to the features Apple provides with their hardware. Now that they're taking that away I may switch.

tbaldridge19:11:13

If on the other hand they released a MBP with a recent CPU/GPU and 32GB ram, I'd be all over that. Touch bars, mobile GPUs, etc. Not so much.

saeidscorp19:11:04

:thinking_face:

tbaldridge19:11:18

Although @saeidscorp I have to mention....OSX is Unix, Linux isn't 😉

tbaldridge19:11:31

and perhaps we should move this to off-topic sometime soon.

jgh19:11:40

Yeah i think if I could find a PC laptop with good build quality I would run Linux on it instead of OSX. Not sure what's out there though, seems like every time I look at PC laptops they feel so flimsy.

jgh19:11:45

Good point tbaldridge

juhoteperi19:11:46

ThinkPad hardware quality is still very good and hardware is well supported in Linux. Most ThinkPad models are even certified for Ubuntu & available pre-installed with Ubuntu somewhere (haven't seen in EU though)

naomarik19:11:31

surface line is awesome, and i’d switch my main dev machine from osx as soon as they release a quad core surface book

dpsutton19:11:12

i'm running linux on a thinkpad x1 carbon. love it

naomarik19:11:13

by that time WSL should be more mature

bfabry19:11:37

if I had the option I'd be tempted to go back to thinkpad+ubuntu for my next laptop, as I'm not super impressed with apple's hardware choices lately. but, I don't have the option, and honestly it doesn't bother me much

mpenet20:11:35

I was a thinkpad person for years but since I started using an xps13 (sputnik) I am not looking back

mokr20:11:55

Looking for a lib that provides interpolation from map keywords like HugSQL uses for SQL queries. Something like: (fill-in “name=:name,password=:pwd,host=:hostname” {:name “Bob” :pwd “secret” :hostname “localhost"}) Google does not turn up anything obvious. Anyone?

dpsutton20:11:39

yeah i want to try one of those or probably the 15

bigkahuna20:11:57

I have an extra ClojureX London 2016 ticket for sale for the conference at Skillsmatter on 1st and 2nd December this week . It's on sale for the early bird price of £95. Would prefer a Paypal payment. Contact us if you're interested

cmath21:11:16

I need to get all of wikipedia as raw text in clojure. I know that there are db dumps available at: https://dumps.wikimedia.org/ -- my question is: are there any java / clojure libraries for converintg the wikimedia markup to plain text?

bfabry21:11:33

@cmath the format of wikipedia is MediaWiki, so I'd start there

bfabry21:11:04

looks like it's all written in java to start with https://www.mediawiki.org/wiki/Wikidata_Toolkit