Fork me on GitHub
#clojure
<
2017-06-20
>
gowder00:06:16

Can someone help me figure out a probably-stupid oops? I'm trying to avoid blowing the call stack on a non-recursive function (calculating triangular numbers) by leveraging memoize + laziness. This code works, and prints 28 as expected:

(defn tri [num]
  (if (= num 1)
    1
    (+ num (tri (- num 1)))))
(def triangulate (memoize tri))
(println (triangulate 7))
However, if I try and map the triangulate function to a lazy infinite seq with:
(def triangles (map triangulate (range)))

(println (take 7 triangles))

it blows the call stack (testing this code out using cljs in planck, if it makes a difference). In fact, even if I only do (def triangles (map triangulate (range 7))) and (take 2 triangles) it still blows the stack.

noisesmith00:06:28

the self call doesn't go back and call the memoized version

gowder00:06:50

oh, that would make a difference rather

gowder00:06:15

I'm an idiot

noisesmith00:06:18

(def triangulate (memoize (fn tri [num] (if ... (+ num (triangulate (dec num))))))

noisesmith00:06:35

back references to a def you are inside are allowed

gowder00:06:50

I knew it would be a dumb mistake... 🙂 thanks @noisesmith !

gowder00:06:06

hmm. even the properly memoized version still blows the call stack though.

(def triangulate
  (memoize
   (fn tri [num]
    (if (= num 1)
      1
      (+ num (triangulate (dec num)))))))

(def triangles (map triangulate (range 7)))

(println (take 2 triangles))

-> maximum call stack exceeded...

gowder00:06:25

I'm still stupid.

gowder00:06:32

that's because the range starts at 0. oooops

gowder00:06:02

is there a blush emoji here somewhere? this works 😱

gowder00:06:18

this might be take a nap time. 🙂

qqq01:06:57

is it well defined what #?(:cljs 1) evaluates to in clojure ? is it 'nil', nothing-at-al--since-stripped-awway-by-reader, or undefined

noisesmith01:06:19

> If no tags match and :default is not provided, the reader conditional will read nothing (not nil, but as if nothing was read from the stream at all).

joshjones02:06:59

@gowder FWIW, memoizing a function does not prevent a stack overflow .. if the function is called recursively many times when no memoized values are available yet, it will still blow up.

spangler02:06:32

Every time I use partition I think it is going to behave like partition-all…. until awhile later tiny parts of data are missing everywhere and I remember my nemesis

kwladyka07:06:12

Do we have list of functions like into which works with transducers?

kwladyka08:06:39

oh so only a few, thx

leonoel08:06:33

for clojure.core, yes + core.async has other usages + advanced stuff here https://github.com/cgrand/xforms

tianshu07:06:59

how to do sql in in clojure.java.jdbc?

tianshu08:06:19

Is that I have to write in (?, ?, ?) and provide 3 values.

kwladyka08:06:46

Do you see here place for transducer? https://pastebin.com/ABd9rYAr

hoff10:06:07

how can i call a java function that expects a primitive float? (f 0.5) won't work because 0.5 is read as a java.lang.Double

mgrbyte10:06:57

(f (float 0.5)) ?

hoff10:06:01

(type (float 0.5)) yields java.lang.Float

bronsa10:06:19

that's because type expects an Object so the primitive float will get boxed again

bronsa10:06:01

but in contexts where a primitive float is accepted, (float 0.5) will do the job

hoff10:06:34

nonetheless, (f (float 0.5)) doesn't work. f is a constructor and i'm getting No matching ctor found for class

hoff10:06:04

if i do (f 1) it works because there's a constructor for ints

hoff10:06:12

but i can't call the one for floats

hoff10:06:22

found a solution. The full signature of f was (f float float float float). calling this in Java with f(1, 1, 1, 0.5) works fine because the ones get coerced

hoff10:06:48

in clojure i have to write (f (float 1) (float 1) (float 1) (float 0.5)) to get the same effect

hoff10:06:03

i was only trying (f 1 1 1 (float 0.5))

hoff12:06:00

so i'm trying to implement an abstract class using proxy and i want to set a protected field during an init method. using set! seems to fail because of the visibility restriction

hoff12:06:19

even packageprivate won't work even though it's the same package in my test case

hoff12:06:29

i can only set the field if it's public

gaverhae13:06:14

@hoff write a subclass in Java that exposes whatever you need?

michaellindon14:06:06

Is it expected that executing java -jar mystandalone.jar from the command line returns focus back to the user when the main function is finished? When I execute the jar file my main function runs, gives the output, and then it just hangs

michaellindon14:06:06

i think i fixed it by adding (System/exit 0) at the end of my main function

mfikes15:06:24

@michaellindon Instead try shutdown-agents, which might address the root cause

gaverhae16:06:40

There's a 60 seconds delay on the agent threadpool or something like that; shutdown-agents bypasses that.

aromo18:06:14

Thank you, Alex!

eoliphant18:06:04

hi I have a ‘flattening’ question I have a list like this (def listoflists [[1 2 3 4] [5 6 7 8]]). I’d like to build a new list that’s something like [ 1 [1 2 3 4] [5 6 7 8]] by doing [1 something(listoflists)] . (flatten) is ‘greedy’ Doing it on the entire collection gives me [ 1 1 2 3 …] just on listoflists results in [1 (1 2 3 ..)]. I’d found some notes that indicated that either (apply concat listoflists) or (mapcat identity listoflists) would do what I want, but they both seem to essentially do a flatten

(def listoflists [[1 2 3 4] [5 6 7 8]])
=> #'user/listoflists
(pprint [1 listoflists])
[1 [[1 2 3 4] [5 6 7 8]]]
=> nil
(pprint [1 (apply concat listoflists)])
[1 (1 2 3 4 5 6 7 8)]
=> nil
(pprint [1 (mapcat identity listoflists)])
[1 (1 2 3 4 5 6 7 8)]
Any suggestions

noisesmith18:06:53

@eoliphant if [1 [1 2 3 4] [5 6 7 8]] is not a typo, the answer is (cons 1 listoflists)

lvh18:06:10

Is there a way to get clojure.test/are to report the values for which it failed on failure

noisesmith18:06:16

it doesn’t seem like you actually want flattening at all

eoliphant19:06:27

ah heck didn’t really think about it that way

eoliphant19:06:46

yeah i’m dynamically building up a Datomic transaction

eoliphant19:06:56

and have lists of adds and retracts

eoliphant19:06:04

going to restructure it

noisesmith19:06:36

if it needs to remain a vector for datomic, you can use (into [1] listoflists)

michaellindon19:06:15

is there an idiomatic implementation of binary trees to be found anywhere? I cannot seem to find much content on binary trees in clojure -> it makes me believe that the standard was of delclarying a node object with key left and right is not idiomatic in clojure

noisesmith19:06:36

a clojure sorted-set is a binary tree iirc

miikka19:06:01

ClojureScript has CLJS ports of the Clojure datastructures, including the PersistentTreeMap, which is the red/black tree used for sorted-map and sorted-set https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L7649-L8364

miikka19:06:53

There you have node objects RedNode and BlackNode, defined with deftype and having left and right fields

michaellindon19:06:41

this looks good, let me check some of these out, thanks

donyorm19:06:06

So I have a project running in both boot and lein. Under lein it runs fine, but under boot I get a ClassNotFoundException: org.jboss.vfs.VirtualFileFilter. Both projects have the exact same dependencies. Why would boot faile to load JBoss properly?

hiredman20:06:38

boot does classloader jiggery pokery after the jvm has started, lein starts the jvm with the classpath set

donyorm20:06:13

hiredman: So do you have any suggestions for solving the issue?

noisesmith20:06:37

does this eastwood message mean anything? I didn’t get a warning

dbg wrong-pre-post: condition=(:exec game-record) line=103 test-ast :op=:keyword-invoke

donyorm20:06:13

hiredman: So do you have any suggestions for solving the issue?

joshkh22:06:58

just wondering if anyone here uses clojurewerkz/neocons on a semi regular basis?

joshkh22:06:13

in case someone picks this up later, i find myself writing a lot of cypher queries and executing them via tquery, but i'm constantly mapping through results to pluck the :data values and ignore all the other stuff i don't care about (incoming relationships, meta properties, etc.). i'm now resorting to spectre to stay sane. is there a better way?

qqq22:06:59

in a *.cljc file, I should be able to just do: (:require [clojure.core.match :refer [match]]) and it all works right? or do I have to #?(:cljs ... :clj) separate lines ?

donyorm22:06:54

you probably need to escape the vector (`'[clojure.core.match :refer [match]]`)

donyorm22:06:09

not sure beyond that

qqq22:06:15

but it's insided the ns part

qqq22:06:28

(ns ...
  (:require ... ))
why do i need quotes inside a ns ?

donyorm22:06:00

right, you don't. Sorry about that

qqq22:06:12

effort is apprecaited

qqq22:06:18

this latest "some stuff is magical clj/cljs is confusing me"

madstap22:06:39

@qqq I think this should work.

(ns foo.bar
  (:require
   [clojure.core.match :refer [match] #?@(:cljs [:include-macros true])]))

madstap22:06:36

You may get away with not including the include-macros thingy, and just :requiring normally, but it depends on how the namespace you're requiring is written.

csm23:06:14

hrm, there really is no way to override hashCode for a defrecord, huh?

csm23:06:07

I’ve got an issue with that, I have a defrecord that contains a derived map from potemkin, but which one of the “keys” of the derived map is null

csm23:06:25

which causes hashCode to throw a NullPointerException