This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-02-21
Channels
- # admin-announcements (3)
- # beginners (15)
- # boot (96)
- # cider (5)
- # cljsjs (2)
- # cljsrn (3)
- # clojure (22)
- # clojure-austin (2)
- # clojure-russia (16)
- # clojured (2)
- # clojurescript (65)
- # css (4)
- # cursive (89)
- # datomic (7)
- # emacs (89)
- # events (1)
- # hoplon (126)
- # leiningen (2)
- # off-topic (2)
- # om (268)
- # onyx (19)
- # parinfer (42)
- # re-frame (5)
- # reagent (30)
- # yada (8)
@levitanong: when you are building trees like that it gets tricky
@micha: ah, my structure used to use loop-tpl to list out all the children of a node, but because datomic doesn't handle ordering, I decided to switch the structure to a linked list. Each node has a "next" and a "child". Because I wanted to minimize the amount of changes to the structure of the tree, I decided to look into keeping it this way and figuring out how to render it. (As opposed to, say, applying a function to traverse the linked list and convert it into a vector)
@levitanong: all of the code is available at https://bitbucket.org/alandipert/thelarch/src
micha did all the ingenious looptpl/zipper stuff, i am responsible for the miserable and broken datomic part
@micha: looking at the snippet. Hmm. Didn't know you could just use a defn. When would a defelem be preferred over defn? @alandipert whoa that's a lot of code. I've never used zippers before, so it'll take time for me to parse all this. :p it's 2 am, so I'll get back to you guys tomorrow. :D
a defelem turns into a defn + argument parsing
this would have worked also (defelem node [{:keys [z]} _] ... (node :z kid))
i can imagine factoring it into a defelem that defers to a private node
fn for internal use
Hmm. @micha mentioned that the structure was similar in that each node kept track of the 'next' node. Does zip/next add a sibling?
Fascinating. :o
I was trying to implement an if-tpl before you guys replied. :p I probably won't need to use it for rendering the structure if I figure out how to use zipper, but it's still something I foresee using for general control of element display. I feel like this is more semantically correct than hiding elements via css, so I'll continue building it out.
It's an uphill struggle though, as I'm very new to macros.
however i think hiding things with css eliminates a lot of corner cases you run into when you add or remove things from the dom
Haha, I foresee it interfering with certain css selectors like :first-of-type, etc...
And sibling selectors
although i've never run into it because when you have those kinds of selectors it's always in a list of things that are not statically known
Haha well, I'm really just taking apart the loop-tpl code and desecrating it. :p
And the loop-tpl code uses macros, so...
^ yeah that was a realization that was dawning on me
Enlightenment!
That's a relief!
It would make sense to just implement it without macros because it would be more intuitive for the user to use if-tpl like the stock if
alan compiled all the cljs into js, so we just load the js file in our app and then we can use the functions from js
yeah i mean when you're thinking about making a macro you should first implement allthe functionality with functions
I see!
where you have two branches, the consequent and the alternative, like for if the predicate is true or false
And the "and" macro
you can't do that with a function that takes 3 arguments because functions always evaluate all of their arguments first
Where you short the execution
I see!
I feel like this is the kind of thing I'd be taught in a computer science class
or amybe your thing is like if
, because then it would delay evaluation of the other branch until the predicate becomes rtue
That... Is a great idea
I suppose I should start simple though. :p
Thanks for the lesson, @micha! Super grateful. :D
I feel like I've learned more CS in my time working with hoplon and clojure than all my years working with JavaScript. @.@
So this is my implementation for if-tpl
so far:
(defn if-tpl* [truth true-tpl false-tpl]
(with-let [current (with-meta (cell nil) {:preserve-event-handlers true})]
(do-watch truth
(fn [old-truth new-truth]
(reset! current
(if new-truth
true-tpl
false-tpl))))))
And it works in the following case:
(let [truth (cell false)]
(div
(button :type "button"
:click #(swap! truth not)
"Swap it")
(if-tpl* truth
(div "true")
(div "false"))))
Yay! But it still causes a stack overflow when recursion is involved:
(defn list-item [sublist]
(if-tpl* (cell= (not-empty sublist))
(let [item (cell= (first sublist))]
(div (text "~{item}")
(list-item (cell= (rest sublist)))))
(div "end")))
(let [herp (cell= (range 10))]
(div
(list-item herp)))
Any idea why this is so?Yes, but this is just for a range of 10. Surely the stack isn’t so shallow.
When I println in the list-item
, I’m seeing it count properly, and then go into a lot of nil
s. So somehow the if-tpl
ceases to work.
@micha: Haha, I see what the problem is. Turns out, it’s because I’m evaluating the recursive call before it’s being passed to if-tpl
. Funnily enough, this was the very thing we were talking about a while ago.
And just like that, it works! All I had to do was bring the macro stuff back in! HAHA
@micha: If I were to make a pull request, where should I set the base branch? master? experimental?
😄 😄 😄
Thanks man!
This is the best emoji in the world
WITCHCRAFT