Fork me on GitHub
#beginners
<
2018-11-05
>
shidima09:11:40

I have a list with strings that I need to turn into just the strings

'("foo" "bar" "baz") => "foo" "bar" "baz"

shidima09:11:02

How would I do that?

dangercoder09:11:15

It has to be in a collection. Or if u want to do something with the individual strings u can use some kind of iteration

shidima09:11:25

I need to turn it into input for sh to run a shell command

didibus09:11:35

@rafael.mshidomi How are you calling sh? I assume it takes a string, so you can use clojure.string/join:

(clojure.string/join " " '("foo" "bar" "baz"))
"foo bar baz"

didibus09:11:06

If you want it as a string of string, you can use pr-str:

(apply pr-str '("foo" "bar" "baz"))
"\"foo\" \"bar\" \"baz\""

shidima09:11:21

It needs sperate strings for the commands:

tools.core> (shell/sh "ls -la")
IOException error=2, No such file or directory  java.lang.ProcessImpl.forkAndExec (ProcessImpl.java:-2)

shidima09:11:39

tools.core> (shell/sh "ls" "-la")

shidima09:11:37

I'm trying to make a function like this:

(defn run-azure-command
  [cmd]
  (println
   (shell/sh "az" cmd)))

didibus18:11:23

@shidima You just want apply then.

(apply shell/sh "az" cmd)
Where cmd is a list of commands like '("foo" "bar")

shidima07:11:34

Will give it a try, thanks

dangercoder10:11:48

@shidima this works for me

test=> (def foo  ["ls" "-la"])
#'test/foo
test=> (apply clojure.java.shell/sh foo)

shidima10:11:55

Ah, I should use apply on the sh call

shidima10:11:30

yes, that works, thanks!

dangercoder10:11:57

you're welcome:v:

rcustodio11:11:07

Good morning

rcustodio12:11:31

Any style-guide

rcustodio12:11:00

To get to know how to order the functions (naming)

rcustodio12:11:36

Thanks @jumar I was reading that one, but it doesn’t say how to sort name funcs, I don’t think that matters much

jumar12:11:10

Clojure compiler requires functions to be defined before they are used so it implies this sort of ordering. Other than that it's probably a good idea to group related functions together. If there's more to your question, I might be missing something...

rcustodio12:11:00

I was considering in doing in alphabetical order, but that wont be good because I would have to do a lot of (declare)

deliciousowl15:11:00

Probably doesn't matter much. That said it probably is a good idea to separate critical functions from non-critical functions, as well as functions with side-effects (!) Another great paradigm I've seen used is for splitting up libraries / code: Input → Events → Actions → Output

andy.fingerhut16:11:21

If your goal in sorting them in alphabetical order is to be able to find them more quickly later, another approach is to use an editor/IDE that lets you jump to a definition, no matter which file it happens to be in, from other places where that name is mentioned.

rcustodio18:11:01

Thanks for your helps, that clear it up, I like the Input → Events → Actions → Output

rcustodio18:11:03

Gonna try that

didibus18:11:24

I think you're over thinking this

didibus18:11:00

Just don't worry about it for now. But don't use declare

Lennart Buit18:11:06

Hai, I have a q regarding clojure spec. Lets say I have a spec for a higher order function with an int predicate as argument, and I spec this arg like so: (spec/fspec :args (spec/cat :arg int?) :ret boolean?), how could clojure know that I am not secretly providing a string predicate? The type of the argument of a (- for example -) anonymous function is not recorded right, so there is no way of knowning that (fn [a] (= a "spaghetti")) is not an int pred right?

hiredman18:11:29

the way spec checks functions is via generative testing

hiredman18:11:51

spec is not a type system

hiredman18:11:02

by that I mean, spec is not a mechanism for reasoning statically(meaning without running) about the properties of a program

Lennart Buit18:11:08

Yeah that makes sense

Lennart Buit18:11:56

Its quite tempting to compare them to Haskell’s type signatures/type checker, but yeah you are right that they aren’t. They are merely type signatures.

didibus20:11:53

They're not type signatures either. They are predicates. Think of it like a cool syntax to define complex pre/post conditions.

Lennart Buit20:11:14

yeah you are right. I have mostly been using them to spec input types/output types but there is nothing stopping me from using them to reason about value as well.

noisesmith18:11:53

if nothing exercises or otherwise checks the functions spec, it's effectively a comment as data. If you actually exercise the function specced the arguments that are functions are tested by generating various args and calling with them

Lennart Buit18:11:46

yeah I have instrumentation enabled in my test suite in the hope that I trigger any type errors iff they are there.

jstaab19:11:50

Is there a function in core or somewhere like (defn ensure-coll [x] (if (coll? x) x [x]))

noisesmith19:11:14

No. Wanting something like that is a sign you are using a poorly thought out API, it's an easy function to write but it's better to fix the source of the data to be consistent (when possible)

noisesmith19:11:30

anyway, the code you have there does what one would expect, if you need it

Lennart Buit19:11:46

I stumbled upon kibit today: https://github.com/jonase/kibit which may be able to automatically answer those types of questions ^^

jstaab19:11:19

I like kibit, haven't had a chance to add it to my project yet

jstaab19:11:48

I've got a jsonschema like {"type": "number"}, I want to make it nullable by changing it to {"type": ["number", "null"]}, using (update schema "type" #(-> % ensure-coll (concat ["null"])))

jstaab19:11:54

Is there a better way to do that?

Lennart Buit19:11:47

why is it {"type": ["number", "null"]} instead of {"type": "number", "null": true}?

Lennart Buit19:11:13

maybe a diff question tho

lilactown19:11:36

I think that’s just JSON schema ¯\(ツ)

jstaab19:11:38

Is that something you can do with json schema? If so, I'd use it

Lennart Buit19:11:21

I don’t know actually, I thought you had some custom JSON data, but if its a standard then probably not

noisesmith19:11:50

why not (fn [x] [x "null"]) ?

noisesmith19:11:25

is it sometimes already a vector?

lilactown19:11:42

yeah, unfortunately that’s just how JSON schema is

Lennart Buit19:11:57

do you have a spec link, now I am kinda curious

Lennart Buit19:11:18

I find it strange that you would model like that

lilactown19:11:51

JSON :face_with_rolling_eyes: what do ya expect? 😛

Lennart Buit19:11:04

or is it just a sorta-sum-type? is {"type": ["number", "string"]} also valid

lilactown19:11:19

yes, I believe so

lilactown19:11:22

it’s a sum type

Lennart Buit19:11:50

well that makes a little more sense

lilactown20:11:03

IMO it would have been better to just require “type” always to be an array to simplify but they probably are optimizing the usual case of something being a single type

Lennart Buit20:11:17

yeah think so too

Lennart Buit20:11:41

null as a type makes sense tho 😉

Lennart Buit20:11:52

instead of a value

jstaab19:11:11

Yeah, it's sometimes a vector

noisesmith19:11:35

yeah, then your ensure-coll is probably the right thing

jstaab19:11:48

Alright, thanks for the help

noisesmith19:11:15

alternatively, you could have a multimethod that dispatches differently for coll vs. string - but for only two possibilities that is probably a bit much

noisesmith19:11:46

I assume it would never be extended to other cases

jstaab19:11:59

Nope, it's pretty much the null case

jstaab19:11:06

maybe sometimes a uuid vs an object but meh

lilactown19:11:40

if you have control over the schema, I think this could be valid: {"type": ["number"]}

lilactown19:11:09

so then you could just conj "null" onto it

jstaab20:11:36

Not a bad idea

Lennart Buit20:11:22

kibit actually finds some cool stuff

Lennart Buit20:11:35

hmm it has some issues understanding that and and or are macros it seems

Logan Powell21:11:44

I'm in unfamiliar territory here: Do I need to worry about a function name conflict between cljs.core and a third-party library? If so, how might I fix it? Can I use :refer-clojure :exclude here given it's not my code?

enforser21:11:31

You should be fine. In your code resolve will still be clojure.core/resolve