Fork me on GitHub
#clojure
<
2016-05-16
>
eraserhd14:05:18

Is there a decent Clojure parser that preserves comments and whitespace? I know that rewrite-clj has one, and that sjacket has one, but I think neither really intend that to be consumed.

arrdem14:05:22

rewrite-clj is the leader in that department AFAIK

arrdem14:05:43

Parsing comments meaningfully is really hard.

darwin14:05:32

@eraserhd: I wrote one custom in cljs, with a custom zipping library - my main goal was to use tools.reader and not custom implementation like clj-rewrite does. But it was never intended to be consumed as a library. Also requires patched tools.reader. Could be interesting for you just for inspiration to see scope of the problem: the main trick was to expose log-source*[1] from tools.reader and then expose it to track whitespace, comments and other “gray matter” [2][3] [1] https://github.com/darwin/tools.reader/commit/321abf7b4242b30c94052c93cdcf5d5d92c7dc38 [2] https://github.com/darwin/plastic/blob/master/src/meld/meld/parser.cljs#L33 [3] https://github.com/darwin/plastic/blob/master/src/meld/meld/tracker.cljs#L28

triss15:05:15

hi all. I'd like to make a java library available to my project. It's not in maven and I've had to compile the .jar myself...

triss15:05:49

where would I put it to make it available to my Clojure project. (I'm using lein for builds)

Lambda/Sierra15:05:19

@triss Quick and dirty answer: jar xf file.jar from within your src or resources directory.

Lambda/Sierra15:05:53

Longer, cleaner answer: make a new Leiningen project for the Java library, with a project.clj, compile it, and run lein install, then add it as a dependency of your project.

Lambda/Sierra15:05:32

or with Maven / pom.xml / mvn install

triss15:05:58

thanks @stuartsierra quick and dirty will do for me today.... jar xf blah.jar completd with out error... I'll see if I can import it

Lambda/Sierra15:05:42

You might need to restart your REPL process.

Lambda/Sierra15:05:27

There might be a Leiningen plug-in that does effectively the same thing without cluttering your src dir.

triss16:05:05

ok this is strange. Emacs knows all about the classes in the JAR now. It autocompletes the class names for me.

plexus16:05:14

@stuartsierra: In the past I've just put jars in my project somewhere and pointed to them in project.clj under :resource-paths. Anything wrong with that approach?

triss16:05:29

(:import [my.classes sub-a sub-b])

Lambda/Sierra16:05:58

@plexus: nothing wrong that I know of

triss16:05:40

(:import [my.classes sub-a sub-b]) works... but when I try to call a static method I get:

Lambda/Sierra16:05:44

@triss Java class names cannot have hyphens.

triss16:05:45

CompilerException java.lang.NoClassDefFoundError: Could not initialize class org.vamp_plugins.PluginLoader, compiling:(form-init4384086965817994186.clj:47:27)

triss16:05:07

sorry @stuartsierra that was a an attempted demo. real import statement is:

(:import [org.vamp_plugins
            Feature OutputDescriptor ParameterDescriptor Plugin PluginLoader])

Lambda/Sierra16:05:28

Maybe try @plexus' approach

triss16:05:01

will do cheers guys.

plexus16:05:20

:resource-paths ["jars/foo.jar"]

triss16:05:44

hmm... still no cigar.... do I need to add it to :dependancies as well?

plexus16:05:16

no, it wouldn't be managed by leiningen/maven so you don't need it in dependencies

plexus16:05:23

how are you calling that static method

triss16:05:47

(PluginLoader/getInstance)

plexus16:05:07

yeah that seems legit

giga16:05:16

Hello Clojurians, I wonder how relevant “Clojure Programming” is right now as 4 years have passed after the publication, and perhaps so much has changed in Clojure

seancorfield16:05:30

@giga: I think it’s stood the test of time pretty well. It’s a good all-round book.

seancorfield16:05:57

It targets Clojure 1.5 I believe? (I’d have to crack open my copy to check) So it doesn’t cover trandsducers… But I’m not sure there’s much coverage out there of writing transducers in any book (and using the built-in ones can be gleaned from the documentation).

giga16:05:44

no, it’s 1.4

giga16:05:30

“All of the book requires 1.3 or higher and has been tested against 1.4 as well"

seancorfield16:05:43

Ah, so it won’t have reducers either...

seancorfield16:05:42

So transducers, reducers, read conditionals, the new Java API… those are the "big" changes it won’t have.

seancorfield16:05:47

Not a huge list.

seancorfield16:05:27

The biggest jump in the books was 1.2 to 1.3 really, since all the 1.2 code was written against monolithic contrib and that changed dramatically in 1.3.

seancorfield16:05:53

The other changes since 1.4 that would affect code are the cond-> and as-> threading macros, and the various some-related additions, I guess.

giga16:05:41

Right now, I’m on two minds - whether should I jump into Web dev(the topic I’m most familiar in programming) with Clojure or continue building Clojure Basics Skills

giga16:05:07

I’m trying to avoid some framework driven book such as Clojure Web Development Essentials, but I’d like to hear experienced voice towards the topic 🙂

seancorfield16:05:31

If you have a specific web dev project in mind, that would give you somewhere to practice your Clojure "basics" 🙂

seancorfield16:05:27

If you want to get up and running quickly with web dev but really want to focus on honing your Clojure skills, try my FW/1 "framework" — really just a bundle of Selmer for view templates, Ring for the core, and a dynamic routing system (http://domain.com/foo/bar calls (bar …) in controllers.foo namespace).

seancorfield16:05:47

We’re using it at work because it means we don’t have to declare routes in code, but we can add mapped routes later if we want (as data).

giga16:05:04

Thank you 🙂

triss17:05:44

ah ok.. the .jar I'm using interfaces some C++ via JNI.... I've got a library file called vamp-jni.so that needs to be on the "Java load path"

triss17:05:07

I've tried adding it to the smae folder as the .jar but that's not worked.

triss17:05:25

does anyone know where I should stuff that file?

triss17:05:08

after a little fiddling I'm now getting:

triss17:05:33

1. Caused by java.lang.UnsatisfiedLinkError
   no vamp-jni in java.library.path"

plexus17:05:09

@triss you'll need something like :jvm-opts ["-Djava.library.path=...."] in your project.clj

plexus17:05:26

try pointing that at the directory where that so file is

triss17:05:21

thanks @plexus. that's sorted it. Cheers!

cupello18:05:23

Hi guys! I really need some help because I have no idea how to do that: I have a col : [ {:price 25} {:price 50} {:price 15} ] and I need to take 65 from this price col. The expected result is: [ {:price 0} {:price 10} {:price 15} ].

spei18:05:41

how are you getting your expected result? shouldn't they all be {:price 0}?

sveri18:05:58

he extracts 65 until it is 0

sveri18:05:10

65 -25 = 40 and 50 - 40 = 10

sveri18:05:15

leaves you with 0 10 15

roberto18:05:47

I would loop recur

sveri18:05:49

could be done easily with loop / recur, but I am waiting if someone comes up with a different solution

roberto18:05:59

with two params: the initial vector and the initial price (65)

roberto18:05:54

are you calculating roll over interests?

roberto18:05:16

there is one project where I need to do this with roll over interests, but it is in F#

mateus.henrique.brum18:05:58

(reduce (fn [rest,price] (do (conj {:price (abs (- price rest))} (- rest price) [] ) [ {:price 25} {:price 50} {:price 15} ] )

mateus.henrique.brum18:05:04

somethin like this ?

mateus.henrique.brum18:05:49

using reduce to recreate a map an keep your (abs (- price rest)) "price" up to date ????

mateus.henrique.brum18:05:44

(abs (- price rest)) => wont work ... :(]

mateus.henrique.brum18:05:53

you need a conditional ... 😕

cupello19:05:27

Done with loop / recur! thanks!

thug.nasty19:05:08

yeah, i would vote for loop/recur. for me it’s the readability

thug.nasty19:05:49

val_waeselynck: hey, there, not sure if this changes anything, but the api to an external service requires that I log in to grab a session key. Then, I can use their api, attaching the session key to all my requests.

thug.nasty19:05:18

val_waeselynck: would I still use something like redis for that?

thug.nasty19:05:39

wouldn’t that be a bit overkill since it’d used for storing just one session key?

thug.nasty19:05:39

it’d be used*

val_waeselynck19:05:41

@thug.nasty: a Redis instance is not that hard to manage 🙂

thug.nasty19:05:51

sure, but that’s not the problem

val_waeselynck19:05:53

the question is just what storage characteristics you need for that key

thug.nasty19:05:59

i just need to hold on to it

val_waeselynck19:05:00

should it be persistent?

thug.nasty19:05:06

it might change

val_waeselynck19:05:17

maybe you can just store it in your UI then

thug.nasty19:05:26

the UI doesn’t need it

thug.nasty19:05:29

it’s backend only

val_waeselynck19:05:48

and the backend doesn't have a database already?

thug.nasty19:05:55

it has a database

thug.nasty19:05:00

but I am using an external service

thug.nasty19:05:09

a third-party service

thug.nasty19:05:19

that requires that I acquire a session key

thug.nasty19:05:38

before I can utilize the service

thug.nasty19:05:56

there may be a scenario where the session expires and I need to get a new key

thug.nasty19:05:20

i wouldn’t need to use redis for anything else

thug.nasty19:05:29

so I figured it’d be overkill for this case

roberto19:05:00

ah, I just did something like that with something I’m doing for a friend on the side. They are migrating from quickbase to something else. Quickbase requires that you authenticate through their api and get a key that you then use to make queries. I created a component that when started, connects to quickbase, authenticates, and stores the key inside the component. Any other part of my app that needs that key (which in this case I limited to one component), just needs to specify a dependency on QuickbaseComponent

thug.nasty19:05:03

i’m not familiar with components

thug.nasty19:05:13

what do you mean by components?

roberto19:05:41

you don’t need component to do what you want, I just feel more comfortable using that. You can probably use an some sort of global atom.

thug.nasty19:05:57

ah, i’ll check that out, regardless. thanks 🙂

thug.nasty20:05:41

zane: great. thanks!

val_waeselynck20:05:57

@thug.nasty: sorry, was away. If it's okay to request a new key frequently, you can use an in-memory cache, which you can indeed back by an atom, or Google Guava for example

thug.nasty20:05:39

@val_waeselynck: np. I'll check that out too. Thanks :)

tom20:05:12

I'm aware that leiningen will evaluate for things like environment variables in profiles.clj but I'm curious how to do so in project.clj. Is it the same? #=(eval (System/getenv "ci.compile-path")) If I want to construct a strings, then like #=(eval (str (System/getenv "someurl") "/segment"))

noisesmith20:05:42

tom: the easier option is to use unquote or unquote-splicing

noisesmith20:05:02

~(System/getenv "ci.compile-path")

tom20:05:15

Inside project.clj ?

noisesmith20:05:30

defproject is a macro, and will unquote / unquote-splice

tom20:05:05

OK thanks!

hlolli21:05:05

(read-string "(str " \"I want qutation marks here \"" )") So my question is, how do I double escape qutation marks, \\" text \\" tries to resolve to symbol 😕

hlolli21:05:54

to be more accurate, this is excacly what Im trying to escape ((eval (read-string "(fn [index aindex] (apply vector ((fn [index aindex] (map #(str \"i \"\"sweet21\"\" 0 5 (get [-20 -22 -21] (mod aindex 3)) \" % \" 0 0 \" ) (get [[440]] (mod index 1) ))) index aindex)))")) 0 0) @noisesmith: you should be able to guess what I'm doing here 😛 "sweet21" needs to be quoted.

noisesmith21:05:52

"foo \"bar\""

hlolli21:05:41

yes, but I guess in my case, read-string and str seemingly will resolve escaped quotation marks...

Lambda/Sierra21:05:23

"\"with \\\"quotation marks\\\"\""

Lambda/Sierra21:05:01

reads as "with \"quotation marks\""

hlolli21:05:09

haha wow, I was assuming it had to look something like this

Lambda/Sierra21:05:43

First you escape the backslash as \\, then escape the quotation mark as \"

hlolli21:05:11

yup, this did the trick, I think I would have had to spend another half an hour to figure it out. Yes, escaping the backslash I did not think about. Thanks!

Lambda/Sierra21:05:33

you're welcome

leov21:05:41

hello all. um. I still think I should ask this quick question: is it ok in clojure if I start wrapping all my functions that works with external world and can throw exceptions into some either datastructure? I can go erlang style with [:ok ..] and [:error ..] return values, or maybe there is some other way? will it hurt readability and/or understandability in the team? it's not the built-in thing after all

xcthulhu21:05:40

@leov: I'd recommend throwing ex-info

xcthulhu22:05:51

Lets you attach a bunch of meta-data to your exceptions

triss23:05:04

hey all. if I've done an (:import [javax.sound.sampled AudioFormat])

triss23:05:20

how do I get at what we'd call AudioFormat.Encoding.PCM_SIGNED in java?

jr23:05:27

have you tried AudioFormat.Encoding/PCM_SIGNED ?

jr23:05:35

as a value

triss23:05:04

I get class not found on AudioFormat.Encoding

jr23:05:27

ah well import Encoding as well

triss23:05:26

thanks jr... got it going... biut only with a $: [javax.sound.sampled.AudioFormat$Encoding]

triss23:05:40

what's with that $?

jr23:05:21

Probably an inner java class of AudioFormat

jr23:05:09

AFAIK clojure munges the name so it is accessible as a namespace

jr23:05:33

where $ is a delimiter for inner classes

noisesmith23:05:33

jr: that's the jvm's way of making inner classes actually

noisesmith23:05:38

it has nothing to do with namespaces

noisesmith23:05:00

when you make an inner class, what is actually created is a regular class with a $ in the name