Fork me on GitHub
#clojure
<
2017-02-23
>
bfabry00:02:33

@shader you won't be able to just do to-date/from-date, as that will mean when it deserializes a util.Date it wouldn't know whether it's a util.Date or joda date. but anyway I think you just need to extend Freezable2 https://github.com/ptaoussanis/nippy/blob/master/src/taoensso/nippy.clj#L316

tanzoniteblack00:02:59

the macros extend-freeze and extend-thaw (https://github.com/ptaoussanis/nippy/blob/master/src/taoensso/nippy.clj#L1413) would be better than directly extending Freezable2

bfabry00:02:14

oh there you go,thanks tanzoniteblack

qqq02:02:50

I understand (let [{:keys [a b]} ...]) however, what does

(let [{:keys [foo/a foo/b]} ...]}
mean ?

qqq02:02:58

the "foo/" part confuses me.

jeff.terrell02:02:20

It binds the name a to the value at the key :foo/a, and likewise for b.

jeff.terrell02:02:53

So, like, the map you'd be destructuring should look something like this: {:foo/a 1, :foo/b 2}.

qqq02:02:53

(let [a (:foo/a obj) b (:foo/b obj)] ...) ?

qqq02:02:32

@tap: some day, I need to read that end ot end instead of section by secton lazily 🙂

tap03:02:50

I think it’s ok. Lots of people are here to help

onetom03:02:26

can someone explain please what does wrong during this back and forth number conversion?

(let [n 9007199254740995
      converted-back-and-forth (long (bigdec n))]
  (- converted-back-and-forth n))
=> 1

onetom04:02:28

it's nowhere near Long/MAX_VALUE and BigDecimal is supposed to be arbitrary precision... 😕

onetom04:02:42

9007199254740995 is 0x20000000000003 which is just 7bytes, 54bits

iku00088804:02:58

static public long longCast(Object x){
	if(x instanceof Integer || x instanceof Long)
		return ((Number) x).longValue();
	else if (x instanceof BigInt)
		{
		BigInt bi = (BigInt) x;
		if(bi.bipart == null)
			return bi.lpart;
		else
			throw new IllegalArgumentException("Value out of range for long: " + x);
		}
	else if (x instanceof BigInteger)
		{
		BigInteger bi = (BigInteger) x;
		if(bi.bitLength() < 64)
			return bi.longValue();
		else
			throw new IllegalArgumentException("Value out of range for long: " + x);
		}
	else if (x instanceof Byte || x instanceof Short)
	    return ((Number) x).longValue();
	else if (x instanceof Ratio)
	    return longCast(((Ratio)x).bigIntegerValue());
	else if (x instanceof Character)
	    return longCast(((Character) x).charValue());
	else
	    return longCast(((Number)x).doubleValue());
} 

onetom04:02:20

ah, good point, i should have just looked up the definition of long sorry for the noise

iku00088804:02:31

looks like it is a case where it falls under the last else branch

iku00088804:02:01

(.doubleValue (bigdec 9007199254740995)) => 9.007199254740996E15

iku00088804:02:30

Floating point arithmetic looks like what is to blame here

joshjones04:02:46

(let [n 9007199254740995
      converted-back-and-forth (.longValue (bigdec n))]
  (- converted-back-and-forth n))
=> 0
if you need it, .longValue @onetom

onetom04:02:08

actually my problem arose because i was just using clojure.core// on a BigDecimal, but i should just drop down BigDecimal methods and use .divideToIntegralValue...

not-raspberry04:02:28

onetom: would +' work for you?

onetom04:02:34

im still mapping out the possibilities, and i just saw it yesterday that there are these *' variants. but for now this worked:

(let [units-to-buy (-> (.divideToIntegralValue wallet price)  (.longValueExact))] ...)

onetom04:02:24

btw, this whole issue was surface by generative testing, so im very happy that i invested into learning clojure.spec

danielgrosse05:02:18

How could I read a file and exit with true when a defined string is found?

joshjones06:02:28

@danielgrosse

(defn file-includes?
  [filename substring]
  (with-open [buf (BufferedReader. (FileReader. filename))]
    (if (some #(clojure.string/includes? % substring) (line-seq buf))
      true
      false)))

joshjones06:02:01

there are other ways like slurp but this will buffer, so you can use on larger files if desired. also, this is one line at a time and does not let you look for multi-line substrings, but this can be done too of course, just not with line-seq

danielgrosse07:02:26

I have to access java objects, but want to write a macro to make it more convenient. But now I struggle with the quoting of the object name. How could I rewrite a JavaClass.object to (JavaClass/Object)so the object name could be passed as variable?

placeboza07:02:04

interesting challenge

placeboza07:02:07

shouldnt be hard

placeboza07:02:16

even for me 🙂

placeboza07:02:37

giving it a go

placeboza07:02:40

but bear with, Im a noob

rauh07:02:08

@danielgrosse As a variable, then your only chance is reflection which is super slow. But a macro, yes then you could write (inv-java System.currenttimeMilis).

rauh07:02:09

(defmacro inv-java! [x]
  (let [[c m] (str/split (str x) #"[.]")]
    (list (symbol (str c '/ (symbol m))))))
(inv-java! System.currentTimeMillis)

placeboza07:02:39

aww. too fast for me

placeboza07:02:59

was busy on the third line

placeboza07:02:10

had too google too many things

placeboza08:02:06

Btw, I read the question a bit differently, so for interests sake, this is what I did (btw it supports class names with dot notation)..

placeboza08:02:30

`(alias 'str 'clojure.string) (defmacro java[obj] (let [t (str/split (str obj) #"[.]")] (read-string (str (str/join "." (butlast t)) "/" (last t))))) (macroexpand '(java Java.lang.Math.abs)) (java Java.lang.Math.abs)`

placeboza08:02:44

paste fail, but w/e

placeboza08:02:28

I read the question as calling a static on it

rauh08:02:38

Just to make it clear: I think all this is actually a terrible idea. 🙂 Good editors will understand (Xyz/zyx) and provide proper help/hints/arity-checks.

placeboza08:02:29

but yay, my first answer to a macro question. noob feel happy.

danielgrosse08:02:13

Thank you both. Maybe I wrote the question in a wrong way. I try to achieve something like literal notation in javascript. So I could do something like

(defmacro get-object
 [objectname]
 (Javaclass/~objectname)
)

danielgrosse08:02:40

Currently I made a map where I associate the Object to a keyname.

placeboza08:02:59

how do you know what hte java class is? or is that baked into the specific macro?

placeboza08:02:39

my java is non-existent, so maybe Im being blonde

placeboza08:02:59

what would you expect to get out of , say (get-object abc) with your pseudocode?

scknkkrer08:02:15

What is the best DB technology for using with clojure ?

placeboza08:02:25

imo, as a noob, mongodb

placeboza08:02:38

because the impedance of the document structure matches the forms in clojure very well

placeboza08:02:54

but again, Im a noob, so take with grain of salt

scknkkrer08:02:11

And why with example. Thanks you all guys. :)

placeboza08:02:38

Monger examples:

placeboza08:02:54

' (mc/insert-batch db "documents" [{ :first_name "John" :last_name "Lennon" } { :first_name "Paul" :last_name "McCartney" }])'

placeboza08:02:05

dammit how do you block quote code here

fernandohur08:02:25

As with everything, it depends on your use case but I also think mongo is very good, specially for prototyping or smaller projects. You rarely need to think about performance and since every clojure datastructure can be serialized you can really just focus on building features.

placeboza08:02:28

;; returns documents with year field value of 1998, as Clojure maps (mc/find-maps db "documents" { :year 1998 })

jarppe08:02:41

@scknkkrer I prefer for Datomic

placeboza08:02:20

Monger has a DSL as well...

placeboza08:02:22

(with-collection db "movies" (find { :year { $lt 2010 $gte 2000 } :revenue { $gt 20000000 } }) (fields [ :year :title :producer :cast :budget :revenue ]) ;; note the use of sorted maps with sort (sort (sorted-map :revenue -1)) (skip 10) (limit 20) (hint "year-by-year-revenue-idx") (snapshot))

sveri08:02:31

@scknkkrer I would not depend on the programming language when deciding for a database. These are two different things. When looking for a DB you might want to consider other stuff, like read / write performance, scalability, costs, support, do you need a key / value store, etc..

placeboza08:02:15

and mongo is fairly good in most languages anyway, because most languages are not set based constructs

placeboza08:02:30

but based on hierarchical / tree data

placeboza08:02:43

haven't tried Datomic, but I hear good things

placeboza08:02:51

again, use case matters

scknkkrer08:02:24

With all these criterias, I am looking for idiomatic technology for clojure. Any cassandra user ?

placeboza08:02:54

afaik, Datomic is the idiomatic choice for clojure, I think

placeboza08:02:16

why do you want to choose based on idiomatic tech for the lang though

sveri08:02:21

With datomic made by Rich Hickey I would also say that datomic is a natural choice. However, its not an open source license, except the free version.

mpenet08:02:43

@scknkkrer there are quite a few c* users, and we have quite decent bindings for c* as well: shameless plug > https://github.com/mpenet/alia

rauh08:02:11

My primary db is C*, I can highly recommend alia+hayt

placeboza08:02:19

been meaning to look into cassandra one day, thanks for that 🙂

rauh08:02:52

Super easy. Normally not a fan of clojure-DSL to represent SQL queries, but in case of C* it makes a lot of sense since the SQL dialect is so minimalistic. So I'm using hayt DSL with it.

mpenet08:02:23

then again if you hesitate between mongo, datomic and c*, maybe you need to have a clear idea of what are you requirements, these are all quite different in many ways

tap08:02:22

Is there any http library which expose data transfer rate information?

tap08:02:46

Or at a minimum have a hook to capture time of the first byte received and last byte received.

scknkkrer08:02:16

@mpenet, so, Is cassandra good choice for long-time ? I heard a bit of cassandra. And I looked a little bit.

mpenet08:02:56

depends on your requirement, it's not a silver bullet.

scknkkrer08:02:08

Can you give me a real-world example for fascinating me.

placeboza08:02:24

Yes, nothing is a silver bullet. That said, another team in our company is quite entrenched in cassandra, and it's a big system.

mpenet08:02:24

tell me what you want to do instead 🙂

scknkkrer08:02:25

With clojure.

placeboza08:02:45

they use cassandra for big data for a credit bureau

scknkkrer08:02:54

I don't know. Pick something.

mpenet08:02:10

if you don't need clustering, dealing with large volumes of data (or writes), maybe something else would fit better

mpenet08:02:16

(in short)

placeboza08:02:06

and mongo is a bit hybrid , so if you don't need the extra expressiveness of the queries, and hte sharding (which C* is better at anyway), then it's also not the best

placeboza08:02:14

that said, it's great to get going with

scknkkrer08:02:19

Yea, but early in project, I need implementation simplicity. Late in project, we will have really large datas...

scknkkrer08:02:36

How can I speel c*, any git repo. ?

placeboza08:02:40

I meant Cassandra.. assumed C* was the same thing (noob again)

placeboza08:02:52

for Cassandra look at alia and hayt like mentioned earlier

mccraigmccraig08:02:48

c* is cassandra

scknkkrer09:02:42

Wow. I need to read about cassandra, I think. Thanks you all.

emil0r10:02:20

has anyone had problems with the slingshot library and clojure 1.9?

emil0r10:02:01

I’m getting the following error: Caused by java.lang.UnsupportedOperationException Can't type hint a primitive local when I try to use the try+ and throw+ macros provided by the library

placeboza12:02:43

Anybody familiar with JDBC for MS SQL? Can't seem to get windows authentication working - copied ntlmauth.dll to my java library path as requested, and it still complains with "SSO Failed: Native SSPI library not loaded. Check the java.library.path"

placeboza12:02:59

fighting it for a while now

placeboza12:02:10

Im on a windows machine

dpsutton13:02:44

they mention writing out the java.library.path and just confirm it is what you think it is

placeboza13:02:55

yup I followed that 🙂

dpsutton13:02:16

i use ms sql with both the microsoft driver and now jtds

placeboza13:02:21

one thing I didnt do though, from that blog, let me try

dpsutton13:02:23

but each time we use connection string login

placeboza13:02:15

still nothing. one thing is that the first answer says I should place 32 bit version in program files (x86) and the 64 bit in program files. but I dont have a 64 bit java folder under Program Files

placeboza13:02:20

so that doesnt really add up

placeboza13:02:43

and I checked hte library path, found that C:\Program files (x86)\ is in there.. tried that, nothing

placeboza13:02:19

I bet rebooting will fix. sigh

benh13:02:27

dll might not load if the dlls that it depends upon cannot load. Its sometimes helpful to run depends.exe to analyse dll dependencies, and tell you what’s missing

yenda14:02:10

I made the above macro that wraps defmethod, it works fine in the repl during development but when running my program with lein run or running the jar I get"No method in multimethod 'execute'" for the tasks I defined

yenda14:02:14

I should mention that the deftask calls are made in different namespaces, and they are required in the core namespace

placeboza14:02:35

tx @benha . good point there

yenda14:02:43

it seems like it is not related to the macro but rather the fact that the defmethods are not in the same namespace since it doesn't work either when I use the result of the macro-expension directly

chrisblom15:02:50

i want to subclass a java class to customize one of its methods, whats the easiest way to do this from clojure?

tomaas15:02:35

hi I'm using clj-http.client and cljs-http.client and getting 403 (Forbidden) error in server when using the methods PUT and POST

tomaas15:02:05

GET is working well, btw

sveri15:02:34

@thomaas Maybe you are missing the CRSF token?

tomaas15:02:52

@sveri, could you paste me some link about that?

chrisblom15:02:10

reify only works for interfaces or protocols, i need to extend a class

dpsutton15:02:31

public interface Lock

sveri15:02:38

@tomaas Hm, in general? I think that is very good to be found by google. In case you use luminus here are the docs about it: http://www.luminusweb.net/docs/security.md#cross_site_request_forgery_protection

dpsutton15:02:43

reify the relavant interface that Reentrant Lock implements?

sveri15:02:04

Its just a guess that this might be the problem as GET requests dont expect a CSRF token, but POST / PUT / ... do

chrisblom15:02:13

@dpsutton that not really what i'm looking for, i need a subclass of ReentrantLock, as other parts of my code expect a ReentrantLock or a subclass

thegeez15:02:48

@chrisblom I think you don't need to write this in the parameter vector for lock and unlock

plins16:02:07

hello everyone, is there a way to create a type alias in clojure?

plins16:02:16

id like to do the following:

(s/defschema Benefit
  {:cpf s/Str
   :nomeSegurado s/Str
   :emailSegurado s/Str
   :atendimentoId s/Str
   :referenciaId s/Int
   :clausula s/Str
   :dataInicioBeneficio s/Str
   :dataFimBeneficio s/Str
   :motivo s/Str})

(defn my-function [^String bla ^Benefit foo] ...)

dpsutton16:02:24

my guess is that this gains you nothing

dpsutton16:02:43

and also that you want spec

dpsutton16:02:54

but my understanding of compiler hints is that is prevents reflection warnings

dpsutton16:02:08

since you don't have an actual underlying type you won't prevent this, so you get nothing out of the annotation

dpsutton16:02:22

could definitely be wrong though

plins16:02:48

id like to anotate with something, and the compiler complains of this code .. maybe i should try to integrate compojure with spec instead of prismatic

dpsutton16:02:02

what does the compiler say?

sveri16:02:32

@plins If you want something to check your types at compile time you need core.typed

plins16:02:33

Unable to resolve classname: Benefit

dpsutton16:02:44

there is no class called Benefit

plins16:02:56

@sveri i just want to document things a little bit, is meta the right way?

plins16:02:16

should i include types?

sveri16:02:19

@plins from clojure 1.9 spec is the way to go

plins16:02:29

hmm ok thanks 🙂

dpsutton16:02:46

if you want programmatic guarantees, use spec and if you want hints to the programmer use the doc string

yenda16:02:47

apparently using the :require [ns1 [subns1 [a] [b] [c]]] for in the ns declaration was my problem for the multimethods not being present at runtime

dpsutton16:02:13

but i doubt an end consumer would ever look in the meta of your function for usage hints

dpsutton16:02:33

but would greatly appreciate documentation explaining types and an example

plins16:02:40

im thinking about my team members looking at my code

plins16:02:55

so im going for docstrings i guess 😃

frank16:02:40

speaking of type hints, does anyone know how to generate an anonymous fn form with a type-hinted return value?

frank16:02:30

I've figured out from the docs that you can add type hints to params by putting {:tag type} metadata on the param symbols, but not sure what to do about return types

frank16:02:20

docs (https://clojure.org/reference/java_interop#typehints) say to put a ^type tag before the arg vector...

frank16:02:27

does that mean the metadata should go on the arg vector?

dpsutton16:02:19

what would a type hint on the return value do?

dpsutton16:02:30

you presumably want to give a type hint to the consumer of that value, yes?

frank16:02:46

good question

kirill.salykin16:02:30

Hi all, is there a way to do deep clone of hash ?

frank16:02:02

I guess type hinting on both the return value and params might be unnecessary...

dpsutton16:02:22

so just type hint the function that takes it as a param can work for you?

dpsutton16:02:03

also, check this out to make sure you are solving an actual problem

frank16:02:14

the functions that will take this are java methods, so I guess they're "type-hinting" by default

dpsutton16:02:21

my understanding is that type hinting does less than you think, so check if you are getting reflection warnings in the first place

frank16:02:42

I've already gotten my interop code to a place where it has no reflection warnings

dpsutton16:02:02

then my understanding (and i could be wrong) is that type hinting will gain you nothing

frank16:02:52

I guess you're right

frank16:02:14

sorry, not very familiar with java's type system or strongly typed languages in general

dpsutton16:02:23

me either. it's just what i've picked up from hre

dpsutton16:02:40

alex miller corrects a lot of misunderstandings of type hinting a lot so i've picked up a few things from him

bronsa16:02:19

@dpsutton a type hint on the return value makes it so that consumers of your function don't have to type hint it every time

dpsutton16:02:35

ah. thanks for the correction

bronsa16:02:42

also if it's a primitive type hint, it will optimize the emitted code to potentially avoid extra boxing

dpsutton16:02:07

will he see a benefit if he's already generating no reflection warnings?

frank16:02:15

@bronsa so should the type metadata go on the arg vector then?

bronsa16:02:29

.. except for deftype methods

bronsa16:02:37

but for everything else, yes

bronsa16:02:15

if you want to type hint the return value

bronsa16:02:25

if you need to type hint the return value

bronsa16:02:44

@dpsutton not necessarily, but possibly if he's using primitive math

dpsutton16:02:02

thanks for clearing that up

dpsutton16:02:23

I guess i was helping to spread the confusion about it 🙂

bronsa16:02:39

if neither *warn-on-reflection true nor *unchecked-math* :warn-on-boxed complain

bronsa16:02:46

then the type hint is usually useless

frank16:02:55

this is the context, in case anyone's curious:

(defn- method->fn
  "Takes a method and returns a type hinted anonymous `fn` form that
  calls the method."
  [{:keys [parameter-types declaring-class name]
    :as method}]
  (let [params (-> parameter-types
                   count
                   (repeatedly gensym))
        params-with-types (map (fn [param type]
                                 (with-meta param {:tag type}))
                               params
                               parameter-types)
        obj `obj#
        obj-with-type (with-meta obj {:tag declaring-class})]
    `(fn [~obj-with-type ~@params-with-types]
       (. ~obj ~name ~@params))))

bronsa16:02:09

type hinting anonymous functions is useless

bronsa16:02:13

the hint will be ignored

bronsa16:02:23

type hinting is a compile time thing

bronsa16:02:30

anonymous functions exist at runtime

frank16:02:00

without the type hints though, I get reflection warnings

bronsa16:02:04

well, type hinting the return value of anonymous functions, I should say

bronsa16:02:13

the args type hints are still useful

frank17:02:28

is type hinting the return value still useless if the anonymous function is stored as a constant?

bronsa17:02:04

type hinting the return value of a function is only useful if you use defn

bronsa17:02:54

using (def x (fn ^Foo [] (Foo.))) rather than (defn x ^Foo [] (Foo.)) will make the return type hint useless

frank17:02:14

ah, gotcha

rauh17:02:26

@bronsa This yields 1 vs 1.0. I'm confused

rauh17:02:30

(let [x (fn ^long [x] x)]
  (x 1.0))
(let [x (fn [x] x)]
  (x 1.0))

bronsa17:02:01

it's confusing

bronsa17:02:23

so, here's how it works

bronsa17:02:35

I lied before by saying that return type hints on anon functions are useless -- what I meant is, they don't get propagated outside the fn

bronsa17:02:57

so in your last example, that type hint acts as a cast for the return value of that function

bronsa17:02:20

any function that uses (x 1.0) as its argument

bronsa17:02:26

won't know that x returns a long

bronsa17:02:33

because it's only local info

bronsa17:02:54

type hinting has a lot of quircks

bronsa17:02:03

esp wrt primitive types

rauh17:02:09

So the type hint will still properly work for the function itself. Wrt, the compiler avoiding reflection for that anonymous function, right?

bronsa17:02:33

so, if you had

public class Foo { public void a (long x) { System.out.println("1");} public void a (Object x) {System.out.println("2")}}

rauh17:02:47

I agree, type hinting with primitives took me a while to get right. I wish there was more documentation about it. Cause me nice bug.

hiredman17:02:50

that effect of casting the return value will only happen for primitive type hints

bronsa17:02:06

and you invoked

(defn a ^long [] 1) (Foo/a (a))
you'd get 1

bronsa17:02:29

but if you tried with

(def a (fn ^long [] 1)) (Foo/a (a))
you'd get 2

rauh17:02:03

Also, if I run:

(binding [*print-meta* true]
  (pr-str
    (macroexpand-1
      '(defn xy ^String [x] x))))

rauh17:02:20

The defn just expands to def + fn.

bronsa17:02:36

what you don't see is the metadata that gets attached to the Var

bronsa17:02:43

use prn rather than pr-str

bronsa17:02:54

you'll see the arglists metadata has the type hint

rauh17:02:06

Oh yes, now I got it.

bronsa17:02:10

oh my bad, pr-str works just fine

rauh17:02:35

That all makes sense now.

bronsa17:02:40

but :arglists is what the compiler uses

bronsa17:02:04

which it only looks up on vars

bronsa17:02:12

and only attaches to vars created via defn

bronsa17:02:49

also what @hiredman said, type hinting only acts as casts for primitives

bronsa17:02:54

.. and only in some scenarios

bronsa17:02:13

in other scenarios it forgets to cast and just causes bad bytecode to be emitted

bronsa17:02:28

in others it causes the compiler to complain and not compile your code at all

rauh17:02:54

That's new...

bronsa17:02:07

¯\(ツ)

Sam H17:02:33

anyone know if you can (or even should be) redefining with-refdefs a java method like java.utils.UUID/randomUUID?

bronsa17:02:39

with-redefs only works with clojure Vars

bronsa17:02:50

and even then, it's usually not a good idea

bronsa17:02:57

and it won't work all the time

Sam H17:02:06

thanks, we'll probably define another function that calls out and redefine our function

jr17:02:05

why are you testing side effects like a random uuid?

jr17:02:16

I would pass that in as input so the function maintains purity

mruzekw18:02:22

I’m working with a web app (via luminus). I’m currently trying to apply access rules via the buddy-auth warp-access-rules middleware. Though it seems my changes only take place when I restart my server. Is this expected?

tanzoniteblack18:02:15

@mruzekw if you take a look at https://github.com/funcool/buddy-auth/blob/master/src/buddy/auth/accessrules.clj#L320 you can see that it compiles your rules and then returns an anonymous function that is actually being used as the middleware, that means that any changes you make to your access rules won't take effect until they've been recompiled and your server has the new function handed in as a middleware

mruzekw18:02:00

Thanks @tanzoniteblack I looked around but wasn’t able to make full sense of the code yet.

mruzekw18:02:05

But that makes sense now

tanzoniteblack18:02:14

so yes, that's expected. You should be able to work around this though if you do something like (def my-access-rules (wrap-access-rules <rules>)) and then use the symbol my-access-rules in your middleware

tanzoniteblack18:02:36

that should cause your rules to take effect whenever you redefine my-access-rules

tanzoniteblack18:02:45

but that might depend on which http server you're using 😄

mruzekw18:02:51

Using immutant

mruzekw18:02:11

Thanks, I’ll try this out

tanzoniteblack18:02:31

don't actually know the subtleties of how immutant works well enough to tell you if that should or shouldn't work, but I'd be interested to hear back what you find

jsa-aerial20:02:39

While (subseq sc >= s <= e) returns a lazy seq, (subseq sc >= s) does not - returns a PersistentTreeMap$Seq. Does anyone know if the latter behaves similar to lazy seq? That is, does it walk the tree step by step as asked for values or does it just make the whole thing up front?? Thanks

catilac20:02:25

apologies if this is the wrong place to ask - is there a recommended clojure postgresql package?

catilac20:02:47

i'm looking at clojure.java.jdbc

joshjones20:02:38

does anyone here use immutant/undertow as an http server?

tcrawley20:02:02

@joshjones: I do, but I wouldn't be unbiased :) What's up?

joshjones20:02:00

I'm just trying to figure out how to read the :body of a POST request. The body in the request is:

#object[io.undertow.io.UndertowInputStream 0x46598eaa "io.undertow.io.UndertowInputStream@46598eaa"],

hiredman20:02:24

@piotr2b what do you mean by multi-tails? are you saying you cannot have more than one tail position in clojurescript? because that is not correct

joshjones20:02:41

Do I really need to directly use the read methods, etc., in this UndertowInputStream class? Or is there a more straightforward way to do it? @tcrawley -- further, I see that the stream is closed, so I don't know how to get the data

hiredman20:02:55

your algorithm is not tail recursive, so recur won't work, has nothing to do with clojurescript

tcrawley20:02:42

@joshjones what type of data is the body? if it's a string, you can just (slurp (:body request))

joshjones20:02:59

@tcrawley thanks so much, that did it -- geez louise, I did not notice that it extends java.io.InputStream... derp! 🙂

tcrawley20:02:12

happy to help

dpsutton20:02:14

also, is tail recursion optimization beneficial outside of strict evaluation? if this is a lazy structure, does it matter if its tail recursive or not?

joshjones20:02:51

@dpsutton good point -- seems that it can just be constructed with the current lazy-seq / cons pattern of constructing a lazy seq

hiredman20:02:45

generate a lazy sequence is almost never properly tail recursive

hiredman20:02:57

or I should say, generating a sequence

piotr-yuxuan20:02:07

(actually the second code doesn’t work, there is an infinite loop in it)

hiredman20:02:09

because you have cons in the tail position

hiredman20:02:21

because you are building something up

hiredman20:02:38

your function is almost never in the tail position

hiredman20:02:56

your docstring is also incorrect about laziness

geek-draven20:02:06

@catilac I'm currently working on a project that uses a postgresql database and I'm using clojure.java.jdbc and also com.layerware/hugsql

catilac20:02:51

geek-draven: good to know! have you had any issues with jdbc? i'm trying to bring clojure into this company 🙂

geek-draven20:02:16

I've not had any problems with it, I even used it to connect to a Redshift database on AWS

geek-draven20:02:31

Good luck introducing it to your company, we've been using it for 2 years and have deployed nearly 40 back end applications in that time 🙂

catilac20:02:16

oh thats great to hear!

catilac20:02:28

and thank you for the well wishes haha. i feel like i'm going to need it

geek-draven20:02:40

no worries, our entire data pipeline is built in Clojure, and this is the first programming language I've learnt 😀

catilac00:02:45

thats great! you haven't done anything with jsonb have you?

geek-draven09:02:20

no, I've just been using plain old json files

hiredman20:02:29

ok, it is sort of correct, sort of not correct

hiredman20:02:39

and you definitely cannot use recur like you are

piotr-yuxuan20:02:41

Actually my question is whether this can be rewritten with tail recursion

piotr-yuxuan20:02:14

Oops, I’m sorry about the mistake in docstring. Could you elaborate on this?

dpsutton20:02:40

every recursive function can be rewritten to be tail recursive

hiredman20:02:51

it is sort of lazy because you do call map, but nothing in your function is lazy

dpsutton20:02:53

but i think we were thinking tail recursion and lazy are kinda at odds with one another

hiredman20:02:09

you call to recur in the second example is nonsense

hiredman20:02:28

#() is a new function, so you are recuring in that new function

hiredman20:02:52

you almost certainly don't want it to be tail recursive

hiredman20:02:56

(that function)

hiredman20:02:26

because to be properly tail recursive it can't be lazy

hiredman20:02:52

constructing a lazy sequence (that is really lazy) and recur are mutually exclusive things

piotr-yuxuan21:02:01

@joshjones thanks for your links, I gonna read it

piotr-yuxuan21:02:56

ok thanks for referencing this ticket @hiredman.

jamesy_source_clojure21:02:17

I’m starting a referral program for introducing new Clojure and other “Functional” Engineering Professionals for new gigs. Working with several customers hiring. Anyone interested in learning more, send me a message.

istvan21:02:12

hi all, actually I also have a project with Clojure (Datomic+Cassandra as well) if anybody in the EU and interested msg me

pesterhazy21:02:04

#jobs is more appropriate for job announcements

yedi23:02:22

is there a version of (some) that works on a (clojure.walk/postwalk) instead of (map) ?

yedi23:02:05

i basically want to walk through a datastucture and perform an update on the first element that meets a predicate while leaving all the other elements alone

hiredman23:02:35

that isn't some

hiredman23:02:54

(if (p node) (f node) node)

hiredman23:02:24

you could shorten it, if that is your thing

yedi23:02:25

yea but if i use that with postwalk, itll update all the elements that match the pred

yedi23:02:31

i only want to do it on the first on ethat matches

hiredman23:02:04

which isn't how postwalk works

hiredman23:02:12

you may want to look at zippers

yedi23:02:04

ooo specter looks promising, i might try that. though ideally i wouldn't have to pull in another lib

yedi23:02:20

ill check out zippers and see if i can leverage those, if not ill just use specter

jr23:02:17

you could make your predicate match only once but that seems like a waste of resources

jr23:02:41

with zipper you can walk the structure until pred matches, modify that location, then return the structure

dpsutton23:02:42

a shudder, stateful predicate

yedi23:02:07

apparently hiccup has built-in zipper helpers, so im thinkin this is the way to go