Fork me on GitHub
#beginners
<
2016-03-27
>
dp05:03:04

I’d like to time an arbitrary function, send the time taken off via side-effect (to the SGG stack incidentally) and then return the result of the called function: Thusly:

(time-a-function '(db/get-record [1234])); => returns record
So far in my ignorance I’ve tried:
(defn time-a-function
  [metric-name expression]
  (def start (System/currentTimeMillis))
  (def result (eval expression))
  (send-to-sgg metric-name start)
    result)
however, simply using eval runs into namespace issues and I am guessing is the wrong tool for the job. Would anyone have any recommendations?

seancorfield05:03:01

First off, def creates a global / top-level Var so you don't want to use it inside a defn. Since you just want local bindings, you want let there.

seancorfield05:03:56

Second, since you want to pass in code that you want evaluated in place, you'd probably want a macro for this...

dp05:03:49

Thank you, sorry, still much a beginner there.

seancorfield05:03:48

(defmacro time-a-function
  [metric-name expression]
  `(let [start# (System/currentTimeMillis)
         result# ~expression]
     (send-to-sgg ~metric-name start#)
     result#))

seancorfield05:03:58

Off the to of my head... untested...

dp05:03:26

Of course…. thank you. I believe you’ve already answered my next question about getting the start time too.

seancorfield05:03:57

(oops, typo, edited)

seancorfield05:03:47

Hope that at least gets you going in the right direction, even if it doesn't actually work.

dp05:03:30

Absolutely. I’ll start fiddling with it and go from there. I think I understand backticks in macros, but I’m going to have to do a bit more reading to fully understand the rest of the symbols and their applicability.

dp05:03:14

s/backticks/quotes

seancorfield05:03:19

The # is used to generate local symbols (if that helps).

dp05:03:51

(nodding like I understand :P)

seancorfield05:03:57

Sometimes things that seem like a no-brainer can be hard in FP, and things that seem really difficult are easy.

dp06:03:36

For Haskell that’s really true. I’m finding Clojure to be not all that much of a jump from JS

dp06:03:50

But, similarly, I’ve not really done anything serious

dp06:03:55

One other question if I may. I’ve noticed that my use of macroexpand works on things like ->, but fails to expand the macros I write. Is this expected behaviour?

dp06:03:21

instead it appears to evaluate them, even when I pass them in quoted

seancorfield06:03:14

A macro is a macro -- yours should work the same as the ones in clojure.core.

seancorfield06:03:36

Can you http://refheap.com an example of what you're trying that doesn't work?

dp06:03:47

Ah hell… My apologies, I’m going to have to run. It is a problem which can wait. Thank you for your help.

himmallright16:03:19

Hey, I'm working through Clojure for the Brave and true. Does this look right for implementing map using reduce? I first didn't use vectors and just reversed the list, but I'm not sure if this is better...

(defn map-reduce
  [function data]
  "An implementation of map using reduce"
  (seq
   (reduce (fn [x y] (conj x (function y))) [] data)))

himmallright16:03:08

I am seeing many problems with this... lol

bwstearns16:03:36

@himmallright: can you link to the section of brave clojure?

himmallright16:03:50

It was just basically a challenge

himmallright16:03:10

embedded in a paragraph

bwstearns16:03:41

I think the basic idea is that map and reduce are similar. reduce acting as a map builds a collection with f applied to each element of that initial collection

bwstearns16:03:17

Took me a minute (too much food in me at the moment, moving slow), but I think an implementation like this is the idea:

(defn map-in-reduce [f coll]
  (reduce 
    (fn [coll elem]
      (into coll [(f elem)]))
    []
    coll))

bwstearns16:03:33

so you're basically removing reduce's generality by deciding in advance what the reduction will be.

seancorfield16:03:58

But you always tell reduce what the reduction will be, don’t you?

seancorfield16:03:48

I mean (reduce + 0 (range 5)) is supplying a reduction of (fn [total elem] (+ total elem)) for example.

bwstearns16:03:56

That's true.

seancorfield16:03:05

There’s a general principle here that you can create a more general function that can be used to implement both reduce and map...

seancorfield16:03:53

It’s been a while but I think I was looking first at a function like this (defn chn [c h n l] (if (seq l) (c (h l) (chn c h n (rest l))) n))

seancorfield16:03:37

And then a function r that generalized the end-of-sequence test and the rest-of-sequence test… that took two more functions.

seancorfield16:03:42

so (defn map [f l] (chn cons (comp f first) nil l)) I think and (defn reduce [f i l] (chn f first i l)) or something...

seancorfield16:03:05

I think r was something like this (defn r [p c h t n l] (if (p l) n (c (h l) (r p c h t n (t l)))))

bwstearns16:03:41

damn. that is a lot more abstract than I was thinking.

bwstearns16:03:17

are those names conventional for things?

bwstearns16:03:10

I assume to some degree, so I guess a better phrasing is, is there a place to learn the convention being used?

seancorfield16:03:57

I don’t know about conventional but those were acceptable names back in the 80’s when I was doing my postgrad work on FP… I don’t know whether I made them up or whether I got them from a book...

bwstearns16:03:03

ok, I just dropped that into light table and with syntax highlighting and tabbing it reads easier

seancorfield16:03:33

Yeah, I wish Slack had paredit mode or parinfer 😆

bwstearns16:03:04

you can do `

bwstearns16:03:11

like for block code

bwstearns16:03:21

(defn r [p c h t n l] 
  (if (p l) 
    n 
    (c (h l) 
       (r p c h t n (t l)))))

bwstearns16:03:44

I think it's technically github flavored markdown? I've had triple-backticks fail on me to make block code before.

seancorfield17:03:02

Yeah, I know about blocks of code — but want I really want is paren matching 😄 — I’m so spoiled by paredit mode in Emacs!

adamkowalski19:03:55

since it is now possible to make an interactive repl in clojurescript, somebody should make a clojure specific developer chat website that can also evaluate your code, and provide syntax highlighting and parinfer functionality. that would also make it really easy to discuss ideas with other people in a dynamic way as you can actually run some code and have them see what that does

seancorfield19:03:30

That sort of thing is being discussed in #C0CB40N8K @adamkowalski

seancorfield19:03:03

(or it was, I haven’t been paying attention to that channel recently)

adamkowalski19:03:19

awesome, I really think that could make learning the language much simpler

adamkowalski19:03:38

when I was learning haskell the irc channel had something called lambda bot which could eval arbitrary expressions

seancorfield19:03:43

See also #C0J20813K I think which was one of the projects that spun out of the community discussions (and, I believe, is on the schedule for Clojure/West).

adamkowalski19:03:23

sometimes just browsing the history and seeing the ridiculously smart solutions people came up with to solve problems others had helped me learn a ton

seancorfield19:03:45

The freenode IRC channel for Clojure has at least one bot that evaluates Clojure expressions and reports them back… I thought there was such a bot here as well…

seancorfield19:03:09

Ah, there we go! /clj (map inc (range 5))

adamkowalski19:03:46

nevermind then haha, i guess I just never new about this bot

adamkowalski19:03:53

seems like not to many people use it

seancorfield19:03:13

Because it can be annoying to constantly have evaluations posted into channels…

adamkowalski19:03:17

yeah thats true, but I feel like it can be really useful especially on a beginners channel where people might have a conceptual misunderstanding of how something works, and being able to demonstrate the way things evaluate can be exactly what somebody needs

seancorfield19:03:29

You can go into a DM with @slackbot and use the /clj command there if you want to experiment.

adamkowalski19:03:53

hey how do you use a npm library in clojurescript, as in on the front end not on the server

adamkowalski19:03:40

I used to use webpack for that, but now I am not sure how to go about this, I tried using lein-npm but it I am not sure how to make the modules available on the browser

seancorfield20:03:22

No clue. Try #C03S1L9DN maybe?

adamkowalski20:03:06

I think for now Im just going to download from source and include it into my project. I am trying to get highlight js to work but it turns out getting clojure highlighting is a little harder then I thought haha