Fork me on GitHub
#beginners
<
2017-06-19
>
Jon06:06:18

(defmacro div [props & children]
  `(create-element :div ~props ~(into [] children)))

Jon06:06:17

in this macro, into [] is slow. But if it's a sequence, it would try to evaluate and get an error. Is there a better solution for this?

dominicm11:06:22

@jiyinyiyong (vec children) might work faster I guess.

Jon02:06:53

dominicm: https://stackoverflow.com/a/12044502/883571 it sounds like they are the same

dominicm08:06:08

For small lists, vec has different behaviour. It will do less work based on my reading there.

Jon10:06:20

I will use vec next time, anyways it's shorter to write

guy14:06:48

have you imported the Math namespace? Or does the Math package you imported have a round function?

guy14:06:08

also what are you passing the function?

okwori14:06:26

Yeah I was passing it like (get-point-percentage 19/20). So its either (get-point-percentage 0.95) or (get-point-percentage (float 19/20)). Thanks @guy

guy16:06:26

@simon hey sorry i just saw your reply, did u get it working?

okwori16:06:12

@guy Yes. I was passing it as a fraction

guy16:06:50

i tried your code out and i got

guy16:06:01

(get-point-percentage 19/20)
=> 95N

guy16:06:12

is that what you expected to happen?

okwori16:06:43

Yes. Just 95 here...

guy16:06:12

oh right

guy16:06:16

i see the difference now

guy16:06:32

I had imported

[clojure.math.numeric-tower :as math]

guy16:06:38

while you were using Math

guy16:06:46

sorry its my bad for making an assumption

noisesmith16:06:28

so it’s Math/round vs. math/round

okwori16:06:48

Its Math/round

noisesmith16:06:01

and use double instead of float for floating point coercion btw

noisesmith16:06:20

unless you really prefer 32 bit precision over 64

guy16:06:44

thats why it was throwing the reflector exception

guy16:06:53

Math/round can't handle a clojure.ratio

guy16:06:10

because it doesn't have a java method that takes a clojure ratio i believe

noisesmith16:06:34

because ratio doesn’t implement an interface that the Math lib understands

noisesmith16:06:14

funny that things in java.lang.Math wouldn’t know what to do with a java.lang.Number, but there we go

madstap17:06:53

Btw, @simon #(:distance %) is redundant, could be just (into [] (map :distance tryme3))

madstap17:06:17

There's also a "shortcut" called mapv, so it could be just (mapv :distance tryme3)

zlrth20:06:52

i have a bug that’s hard to debug because i represented some app state as anonymous functions and java objects. for example: this

{:name "cash" :amount 5000 :contribution-period (fn [date] (time/plus date (time/months 1))) :start (time/date-time 2017 6 1) :contribution-counter (time/date-time 2017 6 13)}
when entered into the repl, is this
{:name "cash", :amount 5000, :contribution-period #function[user/eval52021/fn--52022], :start #object[org.joda.time.DateTime 0x287be984 "2017-06-01T00:00:00.000Z"], :contribution-counter #object[org.joda.time.DateTime 0x5ac23eaf "2017-06-13T00:00:00.000Z"]}
say i want to do
(def fixture-data {:name "cash", :amount 5000, :contribution-period #function[user/eval52021/fn--52022], :start #object[org.joda.time.DateTime 0x287be984 "2017-06-01T00:00:00.000Z"], :contribution-counter #object[org.joda.time.DateTime 0x5ac23eaf "2017-06-13T00:00:00.000Z"]})
i get a bunch of runtime exceptions saying unmatched delimiter: ) and ] which are from the #object[... I can’t see a theoretical justification for forbidding the reader from reading anonymous things. And because this is a LispReader$ReaderException, i’m inclined to think that this is the reader not being sophisticated-enough to handle an object’s and anonymous function’s syntax. Am I off base?

weavejester20:06:18

Yes, the reader can’t read back arbitrary objects and functions.

weavejester20:06:29

I mean, yes, you’re right 🙂

zlrth20:06:32

why not? i mean, they’re there. i tried googling for an explanation from an authoritative source, and couldn’t find one.

noisesmith21:06:39

clojure functions aren’t intended to be readable, it’s simply not a supported feature. the object identity will be a different hex code on each recompile, which will usually be each run of your code

zlrth21:06:58

very well. the mere fact that my app-state is now full of #objects and #functions was giving me pause. i’ll grudgingly do something else. thanks! : )

noisesmith21:06:11

if you convert the joda.time.DateTime to a java.util.Date that does serialize

noisesmith21:06:24

or you could add a data reader for that type I guess

jaysherby21:06:30

FWIW, I've been there before. I once had this grand plan to pass around function objects as a cheap way of doing distributed computing. Unfortunately it was a bust. Functions aren't quite as serializable as it sometimes seems they should be in a lisp.

zlrth21:06:44

interesting!

zlrth21:06:21

and thanks noisesmith i’ll look into that.

madstap21:06:26

You could pass around code as data, then eval it when you want to use it. {:some-fn '(fn [x] (inc x))}. You'd need some way of specifying the environment, requires, etc though. IIRC that's what datomic does for database functions.

jaysherby21:06:21

Yeah, the environment and context, etc. is what got me.

jaysherby21:06:02

Also, in my plan, you'd write your code like normal and it would get converted into data on the fly. That turned out to be not so straight-forward.

jaysherby21:06:31

So it would kind of suck to have to write your code as lists first. It would be another layer of misdirection.

jaysherby21:06:34

At the time (this is an old project) I was hoping for a lisp that would be a theoretically fully serializable environment.

vitruvia22:06:10

whats the difference between a macro and a function. i.e. why are and and for macros and not functions?

rgorrepati23:06:37

Macros don’t evaluate their arguments, but functions do. This is useful for forms like and - because it only evaluates the arguments until it finds one false. And one false in series of arguments to “and”, will generate a false

rgorrepati23:06:21

The main difference however is, macros generate code that is evaluated, while functions are evaluated outright

vitruvia23:06:22

but isn´t that evaluating the arguments, too?

rgorrepati23:06:47

@vitruvia In the expression, (and (= 1 1) (= 2 3) (= 3 4)) only expressions until (= 2 3) are evaluated (and they are evaluated left to right) - because (= 2 3) is false, the evaluator doesn’t even get to look at (= 3 4)

rgorrepati23:06:16

You can imagine a more complex expression, that for example generates 100 digits of pi and checks it against this value in the arguments - (= (generate-pi 100) 3.14……….)

rgorrepati23:06:33

In this case generate-pi will never be called, saving the cpu time

colinkahn23:06:46

You can use macroexpand-all to see the full output of a macro too: https://clojuredocs.org/clojure.walk/macroexpand-all

colinkahn23:06:00

user=> (use 'clojure.walk)
nil
user=> (clojure.pprint/pprint (macroexpand-all '(and (= 1 1) (= 2 2) (= 3 3))))
(let*
 [and__4467__auto__ (= 1 1)]
 (if
  and__4467__auto__
  (let*
   [and__4467__auto__ (= 2 2)]
   (if and__4467__auto__ (= 3 3) and__4467__auto__))
  and__4467__auto__))
nil

vitruvia23:06:41

thanks guys