Fork me on GitHub
#beginners
<
2018-01-07
>
drewverlee03:01:02

Is it possible to get the args list of a function at runtime?

noisesmith03:01:52

it's metadata on a var

noisesmith03:01:00

but no, not on a function if that's all you have

drewverlee03:01:12

You can call meta on a function and it return the args. But i think because … its a var, that i wouldn’t be able todo it at runtime. Is that correct? i’m a bit shaky on functions being stored as vars and what the implications of that are.

noisesmith03:01:34

no, the functions don't have their meta

noisesmith03:01:42

the var does

drewverlee03:01:55

err, so someone would have to pass me the var? i couldn’t go from function symbol to var?

seancorfield03:01:17

Consider that (defn foo [args] body) is short for (def foo (fn [args] body)) -- #'foo is the var, foo is the symbol that "evaluates" to the function.

noisesmith03:01:19

symbol to var, sure

noisesmith03:01:24

just not the function itself

seancorfield03:01:34

So, yeah, you'd need the var itself.

seancorfield03:01:06

What's the problem you're trying to solve @drewverlee? Or is this just curiosity / an experiment?

drewverlee03:01:07

I want to write a library where you hand it a function and it makes that function available at the command line and provides a helpful prompt.

drewverlee03:01:13

The goal was just to have a quick way to make a cli for your program. So if your program took a number and increimted it. The dev could just do something like:

(defn add-5 "add 5 to x" [x] (+ 5 x))
(cli/add add-5)
./run-program --help
fns
add-5 [x] "adds 5 to x"

./run-program add-5 1
=> 6

noisesmith03:01:55

you could require that they pass in the var, or make it a macro and get the metadata that way

drewverlee03:01:41

That seems reasonable. Thanks for the advice!

drewverlee03:01:55

i’m about to fall asleep, i shouldn’t have sparked up a conversation about it lol.

Vincent Cantin08:01:04

I am a beginner and I just learned about clojure.spec. I would like to know if someone already made a macro that take a spec and gives a parsing code that would act the same as the conform function for that specific spec.

alexmiller13:01:12

Why not just call s/conform ?

Vincent Cantin14:01:03

My idea was to use the parsing code into some macro. s/conform only provides the parsed data.

Vincent Cantin14:01:59

that would be nice if the spec could be used to generate a parser.

alexmiller15:01:22

It is a parser, why would you need it to make itself?

Vincent Cantin22:01:51

I was (naively) thinking that it would be useful to the programmer to have a reduced, specialized version of this parser so we can make it part of the implementation of the function that is been specified.

Vincent Cantin22:01:33

For example, that could be useful in error prone cases where function's input is a list of parameters where some of them are optional, and no trivial to detect (i.e. not at the end of the list.

alex.gavrisco13:01:50

Hi clojurians, I'm parsing a HTML with hickory. It's great so far, however I have to parse now basically a text by some patterns. The fragment I have difficulties have the next shape:

<div id="container">
<!-- some non relevant elements -->
<!-- here begins the block which I should process -->
<strong>1.</strong>
<strong>...</strong>
<br>
<p>some text</p> <!-- a random number of paragraphs -->
<br>&nbsp;<br>
<strong>2.</strong>
<strong>...</strong>
<br>
<p>some text</p> <!-- a random number of paragraphs -->
<br>&nbsp;<br>
<!-- end of the second block -->
<!-- and so on -->
</div>
Basically, I have to partition all children by a condition (get sublists of elements which starts with a strong tag with number in it and ends with double <br> separated by nonbreakable space). So, my question is - how can I get those blocks correctly?

zsck16:01:37

After I've changed my project.clj to use clojure 1.9.0, how can I have spacemacs + cider start a REPL using that version of clojure? I really need better error messages.

zsck17:01:11

Oh. I am using 1.9. 😵

zsck18:01:23

I'm practising by doing some codewars challenges in Clojure, and just finished a partial solution to one problem. This one involves some simple parsing, which I'm doing in a very ad-hoc fashion here. Would anyone care to have a look at what I'm doing and suggest better/more idiomatic ways of writing this code? https://gist.github.com/zsck/64e509d9836377edc2a2c4eaac025d31

codonnell20:01:08

I wrote up a solution of my own at https://gist.github.com/codonnell/27da48e74cc4dbc7d71b40fe6eb61e92. To me, parsing a big string like that screams for a combination of str/split and partition/`partition-by`.

zsck20:01:01

Very nice! This is much more succinct than anything I'm ready to write yet.

codonnell21:01:27

Not sure if it's helpful, but I edited the gist to include my repl session while I was writing my solution. Might help to see my thought process.

zsck23:01:20

Thanks. I'll check it out. I am actually quite pleased with how my solution turned out. https://github.com/zsck/Kata/blob/master/src/Kata/ranking-nba-players.clj

zsck23:01:42

This is literally my first Clojure program

codonnell02:01:59

Very impressive! nice work

codonnell02:01:07

minor suggestion, instead of (flatten (map analyze-game games)), you can do (mapcat analyze-game games)

zignd20:01:29

In Schema, I'm using s/defn to add constraints to my functions and I have one that returns an anonymous function, is it possible to describe this anonymous function in the output schema? Here's an example:

(s/defn foo :- foo-output-schema []
  (fn []
    "test"))
I'd like to create a schema for (fn [] "test") here. And would probably use it in foo-output-schema.

noisesmith20:01:18

you can't really do a schema check on a fucntion - you can check the output of calling a function, but functions don't carry any info that we can run checks on

zignd20:01:40

oh, i see, thanks for the confirmation. would you know if this is something achievable somehow with clojure.spec?

onionpancakes20:01:24

@zack.mullaly I would try to incorporate threading macros -> and ->> to make things more readable and eliminate unnecessary let bindings. For example, tokenize-game-details can be rewritten as such:

(defn- tokenize-game-details [game-sheet]
  (let [tokens (str/split game-sheet #" ")]
    (->> (map try-parse-int tokens)
         (map vector tokens)
         (map lex))))

zsck20:01:15

Awesome. I didn't realize ->> could work like this. I thought I'd have to manually create a bunch of partial functions to use it.

zignd20:01:48

@zack.mullaly there's also as-> that lets you define a symbol for the value of the first argument, and then you can the symbol as a place holder in the arguments to the subsequent calls. it's worth checking it out, might be useful when you need more flexibility

zsck20:01:43

Duly noted, thanks!

zignd20:01:40

oh, i see, thanks for the confirmation. would you know if this is something achievable somehow with clojure.spec?

noisesmith20:01:19

@zigned no - spec has the same problem. But there is s/defn for schema that I haven't really looked at, it may or may not be "checkable" in terms of its return value by another schema

zignd20:01:53

that might be the way to go then, i will check it out. thanks @noisesmith :)

zsck20:01:38

Is there a function that takes a value and a collection of functions and calls each function on the supplied value? e.g. (applicative value [f1 f2 f3]) => [(f1 value) (f2 vlaue) (f3 value)]?

noisesmith20:01:49

((juxt f g h) x) => [(f x) (g x) (h x)]

noisesmith20:01:35

juxt takes functions and returns a function, also the function used can be called on any number of args (as long as all of the functions it takes accept those args of course)

zsck20:01:32

Great, thanks!

noisesmith20:01:46

+user=> ((juxt inc dec (fn [x] (* x x))) 42)
[43 41 1764]

Caio Guedes21:01:22

Guys, can help with a clojure.java.jdbc error? I'm trying do a insert, but its not working... (Is that the correct place for ask that?)

ghadi21:01:02

Sure @caio.cesar.g.souza, paste some code

noisesmith21:01:47

@caio.cesar.g.souza one thing right off the bat - there's some tutorials out there suggesting a postgres jdbc driver from clojars that is way out of date and not compatible with up to data clojure.java.jdbc

noisesmith21:01:01

and the symptom people get is errors on insert

noisesmith21:01:42

so if you are using a postgres driver from clojars, first step is to use the real postgres driver (it will come from org.postgresql on maven)

Timothy Brumbaugh22:01:02

Hey everyone I’m new to the clojure game still in college to give you some background, what is the best way to format clojure to deal with those parentheses!

jgh22:01:29

just do what i do and put everything on one line

noisesmith22:01:34

@tbrumbaugh1976 there are some good editor plugins that help keep things balanced and such - what editor or IDE do you use?

Timothy Brumbaugh22:01:36

I use eclipse CCW

noisesmith23:01:04

sadly it looks like all CCW provides is rainbow parens, which is useful but not as advanced as some other options http://doc.ccw-ide.org/documentation.html#_clojure_editor_features

noisesmith23:01:37

in emacs with cider, or vim with fireplace, or Intellij with Cursive you can use paredit (which automatically inserts close parens with open parens and has keystrokes for manipulating forms directly) and parinfer which changes parens based on indentation

noisesmith23:01:20

but honestly a big part of it is getting used to it - it's something that one learns (much like the error messages) for better or worse and in the long run isn't a huge problem

seancorfield00:01:56

@tbrumbaugh1976 How attached to Eclipse are you? Perhaps consider Cursive (based on IntelliJ) - or Atom/ProtoREPL (or Emacs or vim of course).

justinlee00:01:54

I’ll put a plug in for atom with the following packages: https://gist.github.com/jasongilman/d1f70507bed021b48625 It’s not quite as sophisticated but its so much less cognitive load for a newcomer.

seancorfield01:01:23

Yeah, I switched to ProtoREPL after two years of Clojure in Emacs (and years of Emacs nearly two decades ago) and I've been really happy with Atom.