Clojurians
#clojure
<
2016-05-09
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

thug.nasty01:05:27

anyone know of a function that checks if a string is alphanumeric?

fasiha02:05:07

@thug.nasty: does (defn alphanumeric? [s] (not (re-find #"[^A-Za-z0-9]" s))) work for you?

thug.nasty02:05:31

@fasiha: where does that exist?

fasiha02:05:46

I just wrote it, sorry, it's not a built-in

thug.nasty02:05:32

I wrote my own, but I figured I’d ask instead of reinventing the wheel

fasiha02:05:37

Also, sorry that snippet shows how much of an anglophone I am… doesn't check non-ASCII alphabets or other scripts.

fasiha02:05:00

It's one of those questions that could probably support a library :stuck_out_tongue:

thug.nasty02:05:09

:simple_smile:

cky03:05:43

I haven’t tested it but you should be able to use [\W_] instead of [^A-Za-z0-9].

mpenet08:05:21

shouln't it be \w (lowercase)?

mpenet08:05:38

nevermind didn't notice the ^

mpenet08:05:03

\W wont match non-ascii too anyway

kauko14:05:16

@thug.nasty: https://github.com/funcool/cuerdas there's some nice string manipulation functions here

turbopape14:05:15

I like the play on the guitar strings @kauko :simple_smile:

kauko14:05:33

that's what cuerdas means? Guitar strings?

turbopape14:05:50

I think so...

turbopape14:05:01

I am not very well versed in spanish,

turbopape14:05:19

but It seems to me that it talks about guitars out there...

ddellacosta14:05:24

would be good to get a native Spanish speaker in here to confirm but I think “cuerda” has the same generality as the English “string"

turbopape14:05:32

yes, and strings are part of a guitar :simple_smile:

turbopape14:05:50

you plunk strings when you play the guitar :wink:

ddellacosta15:05:06

ah, I see there’s a reference to a song about guitars on the README, guess I missed that bit

roberto15:05:14

yeah, cuerdas are strings

ddellacosta15:05:14

I suppose that puts it into context :wink:

turbopape15:05:52

While my guitar gently « sleeps » :simple_smile:

lvh16:05:55

Hm, adding ^:whatever metadata annotations doesn’t work in macros because the annotation is applied to the sym inside the macro, right? So how do I do that? with-meta?

lvh16:05:00

(def ~(with-meta const {:const true}) … worked

lwhorton16:05:24

whats the idiomatic way to map a sequence of functions across data, where each fn expects the whole collection and does some transformation?

lwhorton16:05:43

I was thinking (map #(% dataset) [f1 f2 f3]), but surely there is a better way?

jr16:05:52

((comp f1 f2 f3) dataset) ?

mpenet16:05:48

((juxt f1 f2 f3) dataset)

jr16:05:16

oh right a different new collection for each fn

mpenet16:05:28

since you seem to want to not cumulate the transformations

lwhorton16:05:37

actually I do want to accumulate the xforms

mpenet16:05:53

well then (-> dataset f1 f2 f3) or comp

lwhorton16:05:49

okay, cool - thanks

lwhorton16:05:30

((apply comp my-fns) dataset)

punnie17:05:31

hey everyone

punnie17:05:10

so I just came across nested defns in some code review

punnie17:05:46

(defn function-name [arguments]
  (defn another-function [more args]
    …

punnie17:05:58

I was wondering if this is a good idea at all

jr17:05:13

no don’t do that

punnie17:05:15

since the internet seems to fail me on justifications on why it is not

punnie17:05:25

I’d use lets, or letfns at most

jr17:05:27

defn creates a var. you want a locally scoped variable

jr17:05:36

that points to a fn

punnie17:05:48

even in the context of another fn?

punnie17:05:15

so each time that function is called, nested stuff is recreated?

jr17:05:11

user=> (clojure.walk/macroexpand-all '(defn foo [] (defn bar [])))
(def foo (fn* ([] (def bar (fn* ([]))))))

jr17:05:20

yes, def creates a var

punnie17:05:10

good, thanks for that :wink:

kenny18:05:56

What is the preferred way to setup data for each clojure.test test? Right now I am just surrounding each test with a let block. Is this the normal way to do it?

ddellacosta18:05:11

@kenny: have you investigated fixtures? That may help, depending on what you’re trying to do: http://clojure.github.io/clojure/clojure.test-api.html#clojure.test/use-fixtures

kenny18:05:24

@ddellacosta: I have looked at fixtures but it looks like you can only set them up for ALL tests. I want to be able to setup data for each test individually.

ddellacosta18:05:06

I see. I have not come up with a special way to do that, and I do just end up doing a fair amount of (deftest does-something (let [a …, b …] etc.)

ddellacosta18:05:39

In some cases I have helper functions to populate values

kenny18:05:10

Right. That is where I am at right now. Just wasn't sure if there was a more conventional way to do that..

ddellacosta18:05:36

I would also love to hear it if anyone else has any other strategies that aren’t simply “use this other testing library…"

stuartsierra18:05:55

put lets in each test. That's clear & conscise.

kenny19:05:11

@stuartsierra: The only problem with that is it is a pain to run each test individually in the repl.

stuartsierra19:05:43

What's the source of pain?

kenny19:05:30

For example:

(deftest example-test
  (let [result (+ 1 2)]
    (is (= 3 result))
    (is (number? result))))
There is no way to run each is individually. I must run the entire let block in the repl in order to run the tests. The solution here is not clear. We do not want to define the same let block for every test because both of the tests can use the same result value.

kenny19:05:23

@stuartsierra: This may not be solvable through the clojure.test library, rather through some sort of repl integration. The repl needs additional context in order to run the individual test with it's "data" defined.

stuartsierra19:05:26

I typically treat a deftest as the smallest unit, one "test".

kenny19:05:32

It seems that is not the pattern that clojure.test is encouraging with multiple iss per deftest.

stuartsierra19:05:57

It's up to you :simple_smile:

stuartsierra19:05:03

I've used various styles: many assertions per test, one assertion per test.

stuartsierra19:05:02

I aim for each deftest to describe exactly one "thing," although I may make multiple assertions about that thing.

kenny19:05:00

And that makes sense. But there is currently no facility to run assertions individually in a test with multiple assertions. This is mostly valuable when first creating the tests and being able to interact with each assertion.

stuartsierra19:05:23

it's just copy-and-paste with the REPL

roberto19:05:25

hmmm, I don’t see why you would need to do so. I feel that if that is ever needed, it means the tests are not atomic enough.

kenny19:05:17

@roberto: It is useful when first creating the tests and when debugging breaking assertion(s). It would be useful to continually rerun that single assertion without rerunning all of the assertions.

roberto19:05:19

if assertions are grouped together, I think it is because they are tightly related/coupled, that if one breaks, they should all breaks. If one is run in isolation, you still need to run the others because a changed made to make that single assertion pass can break the others.

roberto19:05:28

and you won’t know it if you don’t run the entire test

roberto19:05:16

like the example above, if (number? result) passes, it doesn’t mean that the number is 3

kenny19:05:37

Yup, agreed. But it is much easier to debug the output of a single assertion rather than the output of more than one.

roberto19:05:36

what do you mean by debug. Debug as in using a debugger?

roberto19:05:26

with a debugger you can cancel execution if the values are not what you expect when it hits that break point.

kenny19:05:15

No. Just in the repl. Say I have 10 assertions in a deftest and a breaking change is made causing all 10 assertions the break. The test will now output 10 failing tests. That's great because all 10 assertions failed in that test. Now I want to start debugging why that test failed. I would probably start by looking at the first assertion and determining why it failed. I would want to make change, reload the file in the repl and rerun that individual assertion to see the output of the single assertion without polluting my repl with the output of all 10 failing assertions.

roberto19:05:07

oh, I use a debugger for that. I can run evaluations when the execution is paused and I can see what the output is.

kenny19:05:15

Hmm.. I have not used a debugger with Clojure before. Do you use Cursive and do you know if Cursive has a debugger?

roberto19:05:59

Cursive has a debugger, it comes with intellij. I believe it should just work.

roberto19:05:08

I user Emacs + Cider for clojure

kenny19:05:27

I will definitely look into that. Thanks for the link!

roberto19:05:00

you’re welcome. Having a debugger for this purpose is very handy. Has made my dev eperience with clojure even more enjoyable.

kenny19:05:06

Sounds like it. That was always a large pain point when writing and debugging tests in Clojure for me. Sounds like there is a great solution to my problem :smiley:

kenny19:05:20

And a typo in the video name :simple_smile:

turbopape20:05:27

There is also a quite cool debugger in cider!

derwolfe21:05:59

Hi - I’m working on adding some type-hints to some code that does a bit of java interop, and am a bit confused by the following reflection warning Reflection warning, fernet/core.clj:47:4 - call to init can't be resolved. The code being hinted is here: https://github.com/derwolfe/fernet-clj/pull/2/files#diff-52b6ee43a51f49a9a3235d5df781ece9R47

derwolfe21:05:44

What I’m finding a bit confusing, is that the type of instance is known, so why would it need to be hinted? Or am I thinking about this incorrectly :simple_smile:

ghadi21:05:04

mode needs a type hint I think

ghadi21:05:10

@derwolfe:

derwolfe21:05:26

ghadi: I’ll give that a try :simple_smile:

ddellacosta21:05:28

I would think it would be needed on the return to (Cipher/getInstance "AES/CBC/PKCS7Padding”), whatever that is, rather

ddellacosta21:05:34

since you are using a doto

ghadi21:05:39

i think the compiler can infer the other parameters, but not mode

ghadi21:05:07

@ddellacosta: : the compiler understands that call and infers type automatically

ddellacosta21:05:36

@ghadi: if that’s the case, why is it complaining about .init ? I’m confused then

ghadi21:05:53

there's like 9 overloads of the .init function

ghadi21:05:58

doesn't know which to call

ddellacosta21:05:58

oh, or are you saying…right, gotcha.

derwolfe21:05:47

ghadi: yep, I think that solved it.

clojure (defn aes128cbc
  [mode key iv message]
  (.doFinal
   (doto (Cipher/getInstance "AES/CBC/PKCS7Padding")
     (.init
      ^int (mode {:encrypt Cipher/ENCRYPT_MODE
                  :decrypt Cipher/DECRYPT_MODE})
      (new SecretKeySpec key "AES")
      (new IvParameterSpec iv)))
   message))

ghadi21:05:03

+1. It's silly because all the various overloads have int as the first parameter...

telent22:05:19

is it reasonable/idiomatic to require clojure.walk just so I can transform map keys from strings into keywords?

telent22:05:37

I mean, I doubt it adds to app size as that's part of core clojure anyway

telent22:05:03

but something in me says "surely that should be only two lines of code anyway"

ghadi22:05:14

deep or shallow transform?

telent22:05:23

shallow will be fine, i think

ghadi22:05:36

then it's a one-liner with into or reduce

ghadi22:05:20

(reduce-kv (fn [m k v] (assoc m (keyword k) v)) {} m)

telent22:05:57

I should remember reduce-kv

telent22:05:21

although as far asi I can see it's just sugar for reduce + a bit of destructuring?

ghadi22:05:08

sorta -- it actually goes through a different path. Here's @nathanmarz chiming in with specter :smiley:

ghadi22:05:25

(Enjoyed your talk Nathan. Finally understood the motivating example.)

nathanmarz22:05:41

Yea this is a basic Specter use case

ghadi22:05:41

nathanmarz: does FIRST go through sequential, or is there a way to specifically tear mapentry's?

ghadi22:05:00

a la key / val

nathanmarz22:05:05

ALL navigates to each key/value pair independently

nathanmarz22:05:45

internaly it coerces mapentry into a vector of [key value]

nathanmarz22:05:07

FIRST uses a protocol to do updates – in the case of vectors it will do (assoc myvec 0 newval)

kenny22:05:58

What is the meta tag, based on class, that an array of doubles should have? e.g. For string it is ^{:tag java.lang.String}. I know you can use ^doubles but I want a way that I can programmatically determine the correct tag.

kenny22:05:13

Couldn't find any existing function for this.. For those interested.. Just had wrote a lookup table

{Double    'doubles
   Integer   'ints
   Float     'floats
   Long      'longs
   Boolean   'booleans
   Short     'shorts
   Byte      'bytes
   Character 'chars}

roberto22:05:07

Where did clojure.contrib.zip-filter go?

currentoor23:05:34

I've got it working with phantomjs except the window size is tiny when i take a screenshot.

hiredman23:05:14

programatically you don't need a map like that, you can use java reflection to figure out the name of the array type for any type or class, instead of just having a closed map like that

hiredman23:05:31

the short cuts are for human use

hiredman23:05:12

the easiest way is something like

(class (java.lang.reflect.Array/newInstance Double (into-array Integer/TYPE [0])))