Fork me on GitHub
#beginners
<
2016-02-10
>
shaun-mahood00:02:24

What's the best way to strip the outer parens off of something like [[[vec 1] [vec 2]] [[vec 3] [vec4]]]?

meow00:02:14

something like flatten perhaps

akiva00:02:11

(flatten [[[1 1] [2 2]] [[3 3] [4 4]]])
=> (1 1 2 2 3 3 4 4)

shaun-mahood01:02:16

Sorry, badly worded question. I need to convert it from [[[vec 1] [vec 2]] [[vec 3] [vec 4]]] to [[vec 1] [vec 2]] [[vec 3] [vec4]]

solicode01:02:07

So basically the first element of the outer vector, or am I misunderstanding something?

akiva01:02:43

What does vec mean in this instance? Do you mean (vec)? Or do you just mean each [vec x] is a vector of n elements?

solicode01:02:49

Ah, I misread it

shaun-mahood01:02:31

Replace "vec 1" or any of them with whatever expression - doesn't matter really I don't think

akiva01:02:41

Either way, you can’t get [[vec 1] [vec 2]] [[vec 3] [vec4]] because those are two separate return values. They’ll have to be contained in a list or a vector or something.

akiva01:02:31

(first (partition 2 [[[1] [2]] [[3] [4]]])) gets you close.

akiva01:02:45

Basically a tuple of ([[1] [2]] [[3] [4]]).

shaun-mahood01:02:27

Baby stole the keyboard - thanks for the clarification, it's one of the mental stumbling blocks I keep running into trying to manipulate database rows into some useful format. Probably either need to just conj onto an existing vector or change how I'm destructuring things.

akiva01:02:20

One thing I encountered a lot early on is that I just tried to accept incoming data structures as-is and then tried to bend the hell out of Clojure to handle them rather than creating an intermediate step where the incoming data structure is transformed somehow and then transformed again.

akiva01:02:43

Basically as if you were taking a JSON API result, converting it into a map, and then going to work on it.

shaun-mahood01:02:04

Yeah, I'm definitely trying to do that a bit too often :) I do love how much useful production code I can get done without having to understand everything, but some of my habits from other languages definitely raise their head in cases like this.

akiva01:02:53

Absolutely. It’s a complete reboot of approach, really.

shaun-mahood01:02:57

Yeah. In this case I was trying to add a bunch of rows to a single header row, but I'm pretty sure I can just conj the header onto the data rows and it'll work - the exact opposite of my initial inclination.

akiva01:02:20

Yep. Any time I encounter a situation where incoming data can’t be easily worked upon, I divide up the work through several layers of transformation that can be linked together with a comp.

akiva01:02:47

I’m dealing with this exact issue right now with RethinkDB which doesn’t support keywords as values even within vectors.

shaun-mahood01:02:46

Oh that's a great idea - I'm working on rebuilding my existing reports in Clojure and want multiple outputs, so that approach should be awesome for that.

akiva01:02:18

Precisely! Misquoting here but the general idea is that it’s better to have dozens of functions that each do one thing well than one function that does one thing poorly.

akiva01:02:49

The more you divide up the work as ‘purely’ as possible, the more you can create a bunch of comp compositions that can then be used for a dozen different applications.

shaun-mahood01:02:04

Misquoting is fun :)

akiva01:02:24

I sometimes have functions that are literally just DSL sugar. Bottom-up programming is definitely the way to go.

akiva02:02:05

I’ve often defined a has? function being basically (defn has-whatever? [x] (contains? x :whatever)).

akiva02:02:18

All right. Off my soapbox now. Hah.

meow02:02:11

@shaun-mahood: I think someone is giving a talk at Clojure/west about this topic - keep your eye out for that - might help you.

clumsyjedi03:02:30

What is going on in my cljs environment if I have a namespace like this:

(ns thumbscrews.core
  (:require [om.core :as om :include-macros true]
            [om.dom :as dom :include-macros true]
            [cljs.core.async :refer [<! >! put! close! chan]]
            [taoensso.sente :as sente :refer (cb-success?)]
            )
  (:require-macros [cljs.core.async.macros :refer [go go-loop]]))

clumsyjedi03:02:53

connected to a browser repl

clumsyjedi03:02:08

stuff like

(js/alert 123)
works ok

clumsyjedi03:02:42

but I cannot see the sente namespace

solicode03:02:37

@clumsyjedi: I’m guessing you’re in the user namespace?

solicode03:02:24

You can switch to your namespace in the REPL like this (in-ns ‘thumbscrews.core) which is where the requires are happening.

solicode03:02:33

Or require what you want in the user namespace

clumsyjedi03:02:43

no, this is a call to sente/make-channel-socket! further down in the file that starts with the above (ns thumbscrews.core)

clumsyjedi03:02:03

this results in a Uncaught TypeError: Cannot read property 'call' of undefined in the JS console

solicode04:02:13

Oh, I see what you mean

sooheon07:02:06

I’m trying to convert nested hash-maps of arbitrary depth into a nice two-dimensional vector of vectors (to be displayed as csv). The result I want is something like this: http://konklone.io/json/?id=4ab5fc98b66d643040a0 The js implementation for that page is here: https://github.com/konklone/json/blob/gh-pages/assets/site.js#L13-L40 I don’t know js, so I find that hard to parse—could someone point me in the right direction in accomplishing this recursive flattening in idiomatic clojure?

meow08:02:43

perhaps one of the walk functions or flatten

sooheon08:02:01

@meow: flatten was giving me an empty seq result, but looking at clojuredocs again, I see there’s a workaround for maps. Thanks I’ll look into it some more

agile_geek08:02:11

@sooheon: you could also look at zipper and the specter library by Nathan Marz may be useful https://github.com/nathanmarz/specter

meow08:02:54

also look at the source code for flatten and you might understand it more clearly

sooheon09:02:23

@agile_geek: zipper I’m finding difficult to understand, but specter looks really powerful, thanks. Offhand, do you know if theres functionality in specter for creating and transforming keys, not vals?

agile_geek09:02:43

@sooheon: I don't know. I've not really had a chance to look at it in any detail.

sooheon09:02:13

@mikeb: I’ve just come up with an abomination that barely works, let me compare with the gist

olegakbarov15:02:03

how can i parse this format?

=> (f/parse iso-8601 "2016-02-06T14:45:00.000Z")
IllegalArgumentException Invalid format: "2016-02-06T14:45:00.000Z" is malformed at ".000Z"  org.joda.time.format.DateTimeFormatter.parseDateTime (DateTimeFormatter.java:899)

olegakbarov15:02:23

my custom formatter fails to do it, as well as any other that i tested

Chris O’Donnell16:02:08

(f/parse (f/formatters :date-time) "2016-02-06T14:45:00.000Z")
#object[org.joda.time.DateTime 0x66e24717 "2016-02-06T14:45:00.000Z"]

olegakbarov16:02:14

and are there any way to format it to this 2016-02-06T14:45:00 ?

Chris O’Donnell16:02:08

Take a look at (f/show-formatters)

olegakbarov16:02:22

i have this:

=> (f/parse iso-8601 (f/parse (f/formatters :date-time) ends_at))

ClassCastException org.joda.time.DateTime cannot be cast to java.lang.String  clj-time.format/parse (format.clj:154)

olegakbarov16:02:58

i do have working iso-8601 formatter

Chris O’Donnell16:02:59

f/parse goes from string to datetime. f/unparse goes from datetime to string.

olegakbarov16:02:49

yes, correct! thank you!

roberto18:02:54

is there a way to list all files in resources?

mbh21:02:50

Is it idiomatic to use ? in keywords (e. g. :disabled?)

akiva21:02:30

If the result is true/false, then sure.

mbh21:02:06

Ok, thanks simple_smile

stig23:02:43

alrighty, this is probably the channel for me :-)