Fork me on GitHub
#clojure
<
2017-03-27
>
noisesmith00:03:36

it's not just a convenience - being able to do something in a local scope is an important feature - the semantics are different

mobileink00:03:36

it's not a primitive.

bcbradley00:03:09

is there a way to group related libraries under a single name?

mobileink00:03:12

i completely agree.

mobileink00:03:15

@bcbradley what do you mean? spreading ns stuff across multiple files?

bcbradley00:03:52

hrm, no nothing like that

bcbradley00:03:22

clojure.set/blah, clojure.string/blah

bcbradley00:03:39

is clojure. just part of the name?

bcbradley00:03:20

or is it like the major thing in maven? I want to say something like lwjgl-clojure.package-name/function-name

noisesmith00:03:58

bcbradley there are no rules about package names, except for how they map to the class path

noisesmith00:03:11

package name doesn't imply access the way it does to javac

noisesmith00:03:42

and it need not be related to the artifact or group defining it

noisesmith00:03:15

(but good practice is to use package names that make sense of course...)

bcbradley00:03:21

so you are saying i could use the name lwjgl-clojure.glfw for one "package" aka "library", and lwjgl-clojure.openal for another?

noisesmith00:03:53

I don't know how that would make them separate libraries, but OK

mobileink00:03:02

@bcbradley sorry, i don't follow you. please post the code that is giving you trbl.

bcbradley00:03:26

each of them have dozens of classes and i planned on making each class a namespace

noisesmith00:03:38

you can nest packages however you like

bcbradley00:03:53

for instance each class there would be a namespace-- according to what i had planned to do

noisesmith00:03:55

you can have as many packages as you want in one library

bcbradley00:03:21

hold on i'm a bit confused now

bcbradley00:03:29

i thought a clojure library was a collection of namespaces

noisesmith00:03:41

right, and each namespace has a package

noisesmith00:03:51

the package is the prefix leading up to the namespace name

bcbradley00:03:06

i thought each namespace was a collection of symbols (function defs for instance)

noisesmith00:03:14

when functions inside a namespace are compiled, they become classes, and that defines the package those classes will be in

tbaldridge00:03:26

Clojure really has no concept of packages.

mobileink00:03:49

@bcbradley : what exactly is causi g trouble. please post code so we do not need to guess.

tbaldridge00:03:57

Maven might, but Clojure just looks for classes on the class path. And files that match the namespace name

bcbradley00:03:08

this isn't a coding issue its a deployment issue

bcbradley00:03:21

i'm wondering how i should organize what i'm making, not fretting over a line of code

noisesmith00:03:56

@tbaldridge but when my function foo is compiled to foo.class the jvm thinks that class is in a package, no?

noisesmith00:03:25

not that this "package" does much - but it's there

mobileink00:03:52

@bcbradley well i'd like to help, but unless you can be more specific i cannot.

bcbradley00:03:38

here is the gist of it: C has no namespaces so when you look at opengl code you see that every function begins with gl, and its annoying. It wouldn't be too annoying to deal with except that java has no namespaces either (it has classes) and with lwjgl opengl is a package that contains a bunch of classes (for instance gl11), so the fact that both of these languages don't have namespaces forces you to say gl twice if you want to use it through interop in clojure

bcbradley00:03:09

i want to make it less painful to use these native libraries from clojure, so i'm making a clojure library or set of libraries to strip out the nonsense and just use namespaces (since clojure has them)

tbaldridge00:03:12

@bcbradley just stick it all in one dependency, with 30 namespaces. No reason not to do it that way

tbaldridge00:03:42

(but to be honest, writing gl 4x times really isn't a show-stopper in any GL app I've worked on)

bcbradley00:03:08

@tbaldridge so each "package" in lwjgl would map to a "namespace" in clojure?

bcbradley00:03:17

I thought about that but what do the classes become?

bcbradley00:03:29

gl30 for instance, has the functions for the 3.0 version of opengl

bcbradley00:03:31

and thats a class

bcbradley00:03:59

some of the classes have functions with identical names, so i can't just flatten it into one namespace

bcbradley00:03:28

i figured the only way to do this would be to have each package become its own "library" or dependency, and each class to become its own namespace

bcbradley00:03:33

that way I don't risk any conflicts

bcbradley00:03:46

but something about that feels like overkill, does anyone have any suggestions?

noisesmith00:03:16

why make them separate dependencies? why not have multiple groups of namespaces in one library?

bcbradley00:03:29

"groups" of namespaces?

bcbradley00:03:47

is there some way to group up namespaces in one dependency?

noisesmith00:03:00

you can nest the directory paths however you like if you feel like grouping them

noisesmith00:03:22

I don't even know why they would need grouping, but sometimes that makes the relationships clearer

bcbradley00:03:24

i mean i guess i could just make one dependency and have each namespace name be the concatenation of the abbreviated lwjgl package name and class name

bcbradley00:03:32

do you think that would be better?

noisesmith00:03:13

rather than multiple dependencies in order to use one library, yes

bcbradley00:03:30

well its more like a collection of libraries but i see where you are coming from

tbaldridge00:03:06

It seems to me the simplest solution would be something like clojure-gl.gl.10/vertexf

tbaldridge00:03:58

So top level is library name, then "package", aka, GL, CL. Then the version number. And in that namespace are all the functions for that version/subpackage combo

bcbradley00:03:24

how about lwjgl-clojure.opengl.gl10/vertexf

tbaldridge00:03:42

People can use (:require [clojure-gl.gl.10 :refer [vertexf]) to remove some of the name redundancy

tbaldridge00:03:45

yeah, that works too

bcbradley00:03:13

based on what noisesmith was saying it would be easier for people to depend on if all the libraries came together under one dependency

bcbradley00:03:27

the only thing that makes me anxious about that is how i will handle the natives

bcbradley00:03:54

lwjgl comes with a bunch of native binaries that it depends on, depending on which packages you need to use

tbaldridge00:03:49

Well to be honest, at that point ^^ all you're saving is this: in lwjgl I can simply do (:import [.... GL]) then do: GL/glVertexF which not only matches all the OpenGL documentation (that's huge), but isn't that much writing either

bcbradley00:03:22

the extra gl is annoying, besides i've already produced the data structure that describes lwjgl

bcbradley00:03:51

its not just the gl

tbaldridge00:03:03

But one more point: Any serious GL work is going to use shaders and vertex buffers, so you end up writing GL even less...and you write it once, and then you're done.

bcbradley00:03:18

i spent some time going through the entire library and making a record of all the annoying repetitive namespaces being prepended to the function names

tbaldridge00:03:22

Personally I don't find library that reduce a few characters in typing that useful.

bcbradley00:03:45

the other thing i wanted to do is have a clojure library for this stuff where you could pull up the documentation in clojure

bcbradley00:03:36

besides, using java interop for this stuff can be annoying too once you start to try to build abstractions on it, often you have to wrap the java interop in an anonymous function to use ifN

tbaldridge00:03:43

But you have to consider this: going agains a few decades of OpenGL programming guides isn't going to be that helpful. I would rather be able to download the NeHe tutorials for Java and just copy most of them

bcbradley00:03:57

bleh blaze a trail

bcbradley00:03:00

i'm already halfway there

bcbradley00:03:34

i realize most people wouldn't go through all this just to sanitize some names and i guess it is a lot of work for something trivial

bcbradley00:03:52

in any case its already basically done, so that isn't really a valid concern (would have been a few weeks ago)

bcbradley00:03:37

so if each package has a native dependency associated with it, would i be better off making each package a separate library?

lvh02:03:34

is there something like group-by crossed with index? Like group-by, except instead of {:key [item]}, {:key item} (I know keys are unique.)

lvh02:03:50

Normally I do (into {} …) but it’s not super clear to me that that’s optimal 🙂

noisesmith02:03:31

I usually do (defn index-by [k coll] (into {} (map (juxt k identity)) coll)) - uses a transducer, it's a small bit of code, it works

noisesmith02:03:40

definitely not something that exists in clojure.core

lvh02:03:51

yep, that’s what I was about to do. Thanks 🙂

noisesmith02:03:07

note the usage of map transducer instead of calling map on the coll

nooga03:03:09

I’m writing here because #clojure-sanfrancisco seems to be deserted. Anyone in SF Bay Area? Are there any meetups here?

raspasov06:03:11

yes we have a bunch of people in the Bay Area 🙂 the meetup in SF is pretty regular, here’s link https://www.meetup.com/The-Bay-Area-Clojure-User-Group/events/231945973/

mars0i05:03:26

@bcbradley I don't follow everything in above discussion but seemed like inadvertent 3-way misunderstandings to me. Noisesmith's point is that you can add as many dots to a namespace name as you want, as long as you put source files in a corresponding directory structure. If you have a lot of namespaces that will give them more order, but won't do anything else. Maybe that's already clear. Maybe that's all you need? Or is the only misunderstanding mine?

ido06:03:34

is it possible to filter maps using specter? (and get another map)

schmee07:03:58

ido yes, use setval

schmee07:03:52

dev=> (setval [MAP-VALS (selected? even?)] NONE {1 1 2 2 3 3 4 4})
{1 1, 3 3}

ido07:03:26

@schmee I was expecting select will do this

schmee08:03:38

that was my initial thought as well

schmee08:03:57

but the docs of select say

schmee08:03:00

>>> Navigates to and returns a sequence of all the elements specified by the path.

schmee08:03:12

that is, select always returns a sequence

schmee08:03:34

so to maintain the input data structure you must use setval

borkdude09:03:01

I’m trying Lacinia, the GraphQL library from Walmart. Where is the best place to ask questions about it?

mpenet09:03:08

(I am doing the same :))

singen12:03:03

Is anyone doing clojure app clustering? What do you use for remote logging/monitoring instances? Doesn’t matter if it’s a commercial service

mccraigmccraig13:03:06

@singen we've been using ELK for logging... pipe stdout logs to host (mounted) syslog in docker container -> logstash-forwarder -> logstash -> elasticsearch+kibana

nathanmarz13:03:26

@ido @schmee no need for selected? there, [MAP-VALS even?] is equivalent

kurt-o-sys13:03:10

@singen ELK here too, all logging to stdout.

kurt-o-sys13:03:41

discussed between logstash and fluend

scknkkrer15:03:16

Guys, I need help. It’s really important. 😞

scknkkrer15:03:22

Is there someone ?

dpsutton15:03:31

just ask your question

scknkkrer15:03:18

We have docker swarm system.

scknkkrer15:03:01

I want to run live/repl mode in docker swarm. When I try to run lein repl swarm service with this code; docker service create -w /olexibus --mount type=bind,source=/root/app/corporate/olexibus,target=/olexibus -p 3000:3000 --name corporate --network olxnet pandeiro/lein repl I get full repl initialization while repl input turn. It’s says "Bye For Now” like end of repl session. But I didn’t enter anything.

scknkkrer15:03:32

Why leiningen doesn’t initialize normally ?

rduplain15:03:33

You probably need to allocate a pseudo-terminal (with -t). Otherwise, the repl doesn't have stdin.

scknkkrer15:03:21

It read my project file and tried to start repl, tried to get deps.

rduplain16:03:06

Again, try adding -t to your docker command to allocate a pseudo-terminal.

scknkkrer18:03:10

swarm doesn’t allow me to do that. 😞

ddellacosta16:03:28

is there some obvious reason that there is no map-zipper in clojure.zip that I’m missing?

ddellacosta16:03:17

seems like xml-zipper is a special case of a map zipper

fbielejec19:03:32

I'm having trouble java-interopin' these chained calls: String logoutUri = UriBuilder.fromUri("http://localhost:8180/auth") .path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH) .queryParam("redirect_uri", "http://localhost:8080/product-portal") .build("Realm") .toString(); to clj: logoutUrl (-> (UriBuilder/fromUri "http://localhost:8180/auth") (.path ServiceUrlConstants/TOKEN_SERVICE_LOGOUT_PATH) (.queryParam "redirect_uri" "http://localhost:8080/product-portal") (.build "Realm") (.toString)) I get "java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;" (on line 2)

noisesmith19:03:29

fbielejec that makes me think one of those calls is actually varargs

noisesmith19:03:17

to do varargs, you need to put all the “extra” args into an array of the right type (in this case it wants Object, clearly)

noisesmith19:03:39

(into-array Object [s1 s2 …])

noisesmith19:03:56

I assume queryParam is vararg, from context

noisesmith20:03:09

or maybe path is

fbielejec20:03:22

@noisesmith it's a bit hard to debug, becasue I uberwar and deploy to a container (wildfly)

noisesmith20:03:50

ok - it’s build that is vararg

noisesmith20:03:31

change (.build “Realm”) to (.build (into-array Object [“realm”]))

noisesmith20:03:17

oh, and the same change is needed for queryParam

noisesmith20:03:05

- oh, that’s a little different (.queryParam “redirect_uri” (into-array Object [“]))

fbielejec20:03:16

hmm, still not happy, same error thrown

fbielejec20:03:28

I could actually create a proj inEclipse and inspect, now that I think 🙂

noisesmith20:03:48

fbielejec try adding items to the -> in your repl, one of those lines at a time

fbielejec20:03:53

didn't try your second suggestion

noisesmith20:03:06

it should need both, according to the api docs

noisesmith20:03:33

clojure interop with java is great, except varargs are kind of clumsy (and inheritance …)

fbielejec20:03:14

works, beauty 🙂

fbielejec20:03:29

many thanks!

noisesmith20:03:04

glad I could help

noisesmith20:03:03

I wonder how hard it would be to make something like ((varargs foo object-instance arg arg2 type) arg arg arg) and turned it into (.foo object-instance arg arg2 (into-array type [arg arg arg]))

Al Baker20:03:15

Have a luminus re-frame app, and looking to let someone run it who is new to clojure... is there a way to get a lein run that includes all the cljs steps?

noisesmith20:03:21

that’s not an ideal syntax I guess - but there should be a nicer way to do it

noisesmith20:03:16

albaker you can define the :prep-tasks for the profile run uses, or have them do lein do cljsbuild once, run

Al Baker20:03:25

ah cool, thanks

noisesmith20:03:49

lein help sample has examples for setting up :prep-tasks

bja20:03:35

@ddellacosta wouldn't you use seq-zip most of the time?

ddellacosta20:03:30

@bja I must be missing something because that doesn’t seem to know what to do with the map I’m passing in

bja20:03:22

@ddellacosta no I'm missing something

ddellacosta20:03:52

yeah, I assume that seq-zip wants a seq

bja20:03:02

would you expect a map-zip to be (zipper map? vals ...)

noisesmith20:03:17

@fbielejec I was thinking about how clumsy varargs can be - this macro appears to work

=> (defmacro vararg
      [method object & args]
      (let [[regular [_ t & variable]] (split-with #(not= % '|) args)]
        `(. ~object ~method ~@regular (into-array ~t ~(vec variable)))))
#’user/vararg
=> (macroexpand-1 '(vararg get java.nio.file.Paths "foo" | String "bar" "baz"))
(. java.nio.file.Paths get "foo" (clojure.core/into-array String ["bar" "baz"]))
=> (vararg get java.nio.file.Paths "foo" | String "bar" "baz")
#object[sun.nio.fs.UnixPath 0x14ebb640 "foo/bar/baz”]

ddellacosta20:03:33

@bja I’ve been using this definition FWIW: http://stackoverflow.com/a/15020649, it does exactly what I need

ddellacosta20:03:07

seems like the obvious implementation in terms of how it behaves. Just curious why that or something like it isn’t included by default.

fbielejec20:03:27

@noisesmith nice, I'm saving it

noisesmith20:03:48

let me know if it fails in some unexpected way - for simple stuff it works so far though

noisesmith20:03:01

I’m a little skeptical of 10 minute old macros on principle 😄

ghadi20:03:17

I like that macro @noisesmith

ghadi20:03:30

done stuff like it with ... instead of the pipe

noisesmith20:03:57

oh yeah, … is probably more readable there

noisesmith20:03:03

easy enough to swap in

noisesmith20:03:12

I wonder how it handles hinting

ghadi20:03:03

CLJ-440 has been open for years. Probably should be closed IMHO unless someone can find some new vararg interop syntax that has 0 implications on existing code

greg_arcara20:03:07

Is it appropriate to ask the idiomatic way to do something in clojure here? I've only been doing funcitonal/clojure programming for about a week and am trying to improve on how some of my code looks/works.

tbaldridge20:03:14

@greg_arcara always better to just ask the question 🙂. But sure, here is a good place or also in #beginners

greg_arcara20:03:48

@tbaldridge #beginners sounds like a good place for me hah

schmee21:03:05

can someone help me translate this psuedocode to Clojure?

01 function negamax(node, depth, color)
02     if depth = 0 or node is a terminal node
03         return color * the heuristic value of node

04     bestValue := −∞
05     foreach child of node
06         v := −negamax(child, depth − 1, −color)
07         bestValue := max( bestValue, v )
08     return bestValue

schmee21:03:32

it is non-functional in every way and I’m having a hard time translating it

lvh21:03:17

do you care that it’s implicit-stack recursion?

lvh21:03:28

(apply max &c)

lvh21:03:47

no big deal to translate one to the other I guess

schmee21:03:15

what is &c in this context?

schmee21:03:25

that lack of early returns is what’s making it hard for me

schmee21:03:54

lvh something like this?

(defn -negamax [game depth color]
  (if (or (g/game-over? game) (= depth 0))
    (* color (evaluate game))
    (apply max (map #(- (-negamax % (dec depth) (- color))) (advances game)))))

lvh21:03:30

but yeah

lvh21:03:32

pretty much

lvh21:03:14

I mean, you need a base case for game advances being empty

schmee21:03:50

holy shit it works perfectly

schmee21:03:56

thanks 😄

schmee21:03:05

my tests just magically passed

lvh21:03:21

so, apply max Float/NEGATIVE_INFINITY

lvh21:03:22

probably

lvh21:03:51

min and max don’t have nullary arities

schmee21:03:52

this is one of the few times where I’ve seen an imperative approach be much cleaner and more readable then the functional one

lvh21:03:12

eh, it’s a translation of one to the other

lvh21:03:22

I’m not sure there’s no more elegant functional description 🙂

schmee21:03:50

yeah, wait, I’m just an idiot. I used to have a bunch of atoms in there but I don’t need those anymore

lvh21:03:55

plus, regardless, I would write that second branch with ->>

schmee21:03:00

so this is functional

schmee21:03:31

yeah, that probably a good idea

schmee22:03:44

>>> Note The flaw in this code is that it is not updating the alpha after checking each child. It does get set when the cousins are calculated. This means I will need to write a new function that combines the map and take-while.

schmee22:03:46

what a cliffhanger

noisesmith22:03:36

@schmee something that might help is reduced form with reduce

noisesmith22:03:58

specifically for the if val >= beta return val part

schmee22:03:35

that's a good one!

noisesmith22:03:39

notice that there would have been an exception thrown if it got to nil - it effectively short circuits

schmee22:03:10

I can’t help but feel like alpha and beta have to be atoms

schmee22:03:49

cause I don’t see how the updated values can reach the recursive calls otherwise

noisesmith22:03:45

schmee the alteration of alpha directly translates to part of the reduce (based on the code snippet on the chong kim site)

noisesmith22:03:13

instead of foreach you have reduce, instead of changing alpha you return an accumulator with the new alpha in it, instead of the early return of val you use (reduced val)

noisesmith22:03:20

it all translates directly without mutation

noisesmith22:03:37

oh, and val would also be a value in the accumulator

schmee22:03:00

:thinking_face:

schmee22:03:21

alright, I’m going to play around with that tomorrow, it’s way past bedtime already 😄

schmee22:03:26

thanks for the suggestions 👍

liamd22:03:04

is clojureql dead? all the doc sites are down and the last commits were years ago. asking because it seems to be the way to get data from a sql db into incanter.

tanzoniteblack22:03:22

You should be able to use to-dataset from a sql library of your choice, since most clojure sql libraries return a sequence of maps

tanzoniteblack23:03:22

and...the incanter project itself seems to be pretty much dead, but you can find some discussions in #incanter

Shantanu Kumar08:03:31

There’s also #sql channel for any SQL topics

noisesmith22:03:40

@schmee essentially (reduce (fn [[alpha val] child] (cond (> val beta) (reduced val) (> val alpha) [val val] :else [alpha val]))) init node)

noisesmith22:03:19

oh wait there’s also the part where val gets calculated - exercise for the reader, heh

schmee22:03:51

haha, I’ll try!

noisesmith22:03:59

but that should be pretty close to a working pure version of the foreach

schmee22:03:38

you seem to have this one in the bag, I might just ping you if a need the answers sheet for this one… 🙏

bradford23:03:53

Every time I see Dakrone I think "Dankthrone" which sounds like a rad Stoner Metal band

qqq23:03:09

1. I am writing code in cljs. 2. This code requires a macro. 3. I wrote a macro in a clj file. 4. This macro does something stupid and throws an exception at compile time. 5. The error I get back from the cljs compiler does not seem very helpful. 6. Is anyone else running into this problem?

adambrosio23:03:08

@qqq wrap the macro in a try catch and .println to System/out

qqq23:03:34

@adambros: I'm not sure I understand. Are you suggesting:

(defmacro ...
  (try ....
    (catch / println )))
?

adambrosio23:03:45

Sorry I'm on my phone, but basically yes

adambrosio23:03:34

That way you control what you see, it's usually helped me, as the unhelpful errors are a npe and it just give me one line

adambrosio23:03:20

It's (catch Exception e (.println System/out ...))

alex.ter.weele23:03:50

Is there a function like this in core, specter, or somewhere else?

(defn apply-if [f p x] (if (p x) (f x) x))
I find that I need this a lot, to e.g. optionally do a transform in a (->> …)