Fork me on GitHub
#hoplon
<
2016-08-25
>
thedavidmeister12:08:07

@onetom i bet that’s why my boot reload doesn’t really work

onetom15:08:41

@thedavidmeister i've prepared a minimal repo where you can play with reload https://github.com/onetom/boot-reloadable-hoplon (i used it to debug an error thrown from (reload :on-jsload true), but it turned out i was using boot-hoplon 0.2.2 instead of the latest 0.2.4, so there is no example of defonce in it yet)

onetom15:08:21

@jumblerg i've also prepared a reload example specifically for hoplon ui: https://github.com/addplus/hoplon-ui-reload-example

onetom15:08:06

i would be curious what do you think about this approach of having a cell as the content of body which i reset! on namespace reloads

flyboarder15:08:49

Hello everyone, Im using ~ unquote in a formula cell to hoist another cell up, but I’d like to use this inside a macro, how can I prevent the macro from hoisting the cell until later in the formula cell?

flyboarder15:08:25

seems like an extra ` does the trick? …. apparently not

flyboarder16:08:56

@micha Is there an example somewhere which shows macro expansion in a formula context?

micha16:08:29

@flyboarder how do you mean?

micha16:08:56

javelin fully expands all macros in the formula before it does its own work, is that what you mean?

flyboarder16:08:40

So to avoid evaluation of some-other-value I am using a macro

micha17:08:09

i don't think you want to use a macro there

flyboarder17:08:29

oh ok, do you have another idea?

micha17:08:43

is the problem that some-other-val is a cell?

flyboarder17:08:41

no, it uses pred, which will fail if pred is nil

micha17:08:27

i'm not following

micha17:08:34

you have a when pred there

flyboarder17:08:55

the above will work, but if I try to use it in a function and pass in my route-params they are evaluated and it calls (fbdb/get-in (fb/post) (:id route-params)) which fails because route-params is nil at first

flyboarder17:08:30

the whole get-in thing will throw an error if it doesnt get non-nil params

micha17:08:43

i don't see how it can get nils though, it's guarded by the when (:id route-params)

flyboarder17:08:27

right but in a function call (fbdb/get-in (fb/post) (:id route-params)) is passed in as an arg, which evals it anyway, I was trying to write a macro to guard it

micha17:08:22

are you saying that (fb/post) is what is nil?

flyboarder17:08:31

but the macro screws up my reset! because the cell is a value then

micha17:08:42

i don't see how it can be evaluated if (:id route-params) is nil

micha17:08:05

it will never get to the code that calls listen-once if (:id ...) is nil

micha17:08:27

if (fb/post) is nil you can just add that to the guard expr

micha17:08:07

i don't think macros will help because your problems are strictly runtime ones

dm317:08:01

I'd do add-watch here, doesn't that work?

flyboarder17:08:27

@dm3 I havnt used add-watch before

dm317:08:43

assuming pred is a cell

dm317:08:05

(with-let [fbc (j/cell nil)]
  (add-watch pred
     (fn [_ _ old new] ;; not sure about args
        (when new
          (fbdb/listen-once ref (str/...) #(reset! fbc (db->clj %))))))

flyboarder17:08:27

@dm3 interesting, ill have to play with that

flyboarder17:08:36

@dm3 that will only watch one of that arguments tho right

dm317:08:51

but you can deref ref there

dm317:08:55

I mean you should

flyboarder17:08:29

I may not be able to guarantee that my incoming arguments are cells

dm317:08:39

they need to be watchable

dm317:08:47

not sure what's the right protocol in cljs

dm317:08:12

but I think it's possible to coerce them to that

micha17:08:28

you can make ref a cell that only changes when it's not nil

micha17:08:00

or do (when (and pred ref) ...

flyboarder17:08:25

@micha ^ do you mean in my function or in the macro version?

micha17:08:55

in your function

micha17:08:21

there is not way to know if ref will be nil unless you evaluate it, of course

micha17:08:03

so (when (and pred ref) (stuff in here will not evaluate unless ref and pred are both not nil)) shoudl work

flyboarder17:08:04

ah right, slight miss communication, ref is only either a value or throws an error, I would need to make this a macro to delay ref evaluation no?

flyboarder17:08:22

if it’s a function it throws the error before entering my func

micha17:08:32

or just (try ref (catch js/Error _))

micha17:08:05

that will evaluate to nil in case an error is thrown

micha17:08:41

macros won't help when the issue is a runtime thing

micha17:08:10

a macro can't help you do anything you can't just do manually

micha17:08:29

because all it can do is generate code, which you can also just type yourself

flyboarder17:08:21

right, ok so just to summarize, in a formula cell I can do this to eval things before the formula (cell= ~(things to pre eval)) but I cannot do that inside a macro (defmacro blah (cell= ~(things to pre eval)))

micha17:08:05

in a macro you probably want to use the formula fn instead of cell=

micha17:08:24

well maybe, it depends

micha17:08:58

your macro can also macroexpand its arguments, like the javelin one does

flyboarder17:08:18

and I think thats whats happening which is why its a value not a cell anymore

micha17:08:20

that's why javelin does that, so that macros can compose

micha17:08:44

so if your macro will macroexpand its arguments before it generates its code you will be safe

micha17:08:14

alan and i have been planning to make a lisp where this is the default behavior, too

micha17:08:27

applicative order macros

micha17:08:06

this lets macros compose the way functions do in lisp

micha17:08:46

the macro doesn't know or care about macros in its arguments, just like a function doesn't know or care about the functions that might be evaluating to the values it gets as its arguments

flyboarder17:08:32

That seems to be the way I default my thinking, why doesnt it just do this!?

micha17:08:40

however, if you can't solve the specific problem you have without macros first, then macros won't help you

micha17:08:08

macros can only generate some code at compile time

micha17:08:18

you need to know what code it needs to generate 🙂

flyboarder17:08:01

You’d think there should be a way to specify if I want my argument evaluated when it is passed to my function, instead of either yes it’s evaluated (func) or no it’s not (macro)

flyboarder17:08:15

like partial argument eval

micha17:08:42

in cljs it's not even between those two choices

micha17:08:48

in cljs you have compile time and runtime

micha17:08:58

and at compile time of course no cljs is evaluated

micha17:08:31

it's just a happy coincidence that cljs and clj both use the same type of ast (sexps)

micha17:08:54

but it's not like in clj where macros expansion is interleaved with evaluation

flyboarder17:08:20

right because it’s all at compile time

micha17:08:28

cljs macros don't even run in cljs

micha17:08:36

they run in a completely different language

micha17:08:10

we just leverage the similarity of the two languages to make some things act as if you could write macros in the same language

micha17:08:30

but like in clj you can make a macro that uses a function defined in the same namespace

micha17:08:37

not so in cljs

flyboarder18:08:57

@micha ok so trying to use formula this returns a function, which takes cells?

micha18:08:17

the arguments don't have to be cells

micha18:08:27

but if they are then it will react to changes in them

micha18:08:45

but i strongly recommend doing this manually first, before making macros

micha18:08:05

like if you can't hardcode it to fix your problem, the macro won't help at all

micha18:08:21

the macro just allows you to generalize the hardcoded solution

micha18:08:06

and the things you have to do to hardcode the solution will be the exact same things the macro will need to do, later

flyboarder18:08:07

lol well it works so long as I dont put it in a function, this tells me my issue is when the arguments are evaluated

micha18:08:22

your macro will have to put them in a function then

micha18:08:27

if you decide to make a macro

micha18:08:57

it can't do anything you can't already do, all it can do is automate generating code

micha18:08:03

like generating a fn wrapper

micha18:08:06

or something like that

micha18:08:27

the compiler doesn't interleave with evaluation

micha18:08:38

so it has no impact on when things get evaluated

flyboarder18:08:44

thats basically what im trying to do but im using ~ in my formula which doesnt work once it’s a macro

flyboarder18:08:10

cant I delay ~ so it’s done by the formula not the macro?

micha18:08:32

~ isn't seen by formula

micha18:08:39

only cell= sees it

flyboarder18:08:51

right cell= is what is in my current version

micha18:08:06

there is no need for ~ in formula, since you pass it args separately

micha18:08:20

cell= just generates an equivalent formula expression

micha18:08:57

(cell= (+ a b)) ;=> ((formula (fn [x y] (+ x y))) a b)

flyboarder18:08:21

I will try to hardcode it as a formula version

flyboarder18:08:26

and go from there

micha18:08:08

how do you call fbwhen-cell

micha18:08:33

what arguments do you give it

flyboarder18:08:36

(hfb/fbwhen-cell (:id route-params) (fbdb/get-in (fb/post) [(keyword (:id route-params))]))

flyboarder18:08:14

thats the issue, arg2 (fbdb/get-in (fb/post) [(keyword (:id route-params))]) needs to wait before it can eval

micha18:08:23

wait for what?

flyboarder18:08:33

route-params not to be nil

flyboarder18:08:52

it throws an error

micha18:08:00

why not use a try/catch?

micha18:08:12

i never found a use for NPE yet in lisp

flyboarder18:08:17

well any non-nil value isnt valid logic

flyboarder18:08:31

so even if I catch the error I need to replace it with something

flyboarder18:08:38

that something needs to exist in db

micha18:08:46

you can replace it with ::not-found or whatever

micha18:08:01

a distinct value that represents invalid data

micha18:08:13

but isn't an exception that will propagate up the call stack

flyboarder18:08:25

yeah it seems that if I want to implement this as a function, I need to sanitize the argument inside and out of the function

micha18:08:01

throwing null pointer exceptions in lisp is rarely necessary or useful imho

flyboarder18:08:15

like sanitize it outside to stop the error, and then again inside so make sure im not getting passed nil

micha18:08:28

that get-in function should just notthrow

micha18:08:53

instead of throwing it just returns :get-in/invalid or whatever

flyboarder18:08:58

yeah but thats how the firebase library works

micha18:08:14

you don't need to do it that way though

micha18:08:25

just wrap it in a cljs function that doesn't throw

micha18:08:37

or monkeypatch it troll

flyboarder18:08:22

^ good point, lol I can just do whatever with it 😛

flyboarder20:08:34

@micha had a few 💡 makes much more sense now thanks!