Fork me on GitHub
#hoplon
<
2015-09-18
>
micha00:09:06

that's precisely it

micha00:09:20

the functions you create with mkremote don't return state

micha00:09:37

state goes into cells, and formulas react to changes in state in the normal javelin way

micha00:09:59

what the mkremote functions do return is a jQuery promise you can use to handle errors, for example

micha00:09:21

because errors want to be handled at the place where the request was initiated usually

micha00:09:48

like if you have something like `

flyboarder00:09:51

how do you mean? where is state generated then?

micha00:09:18

(defc stem-cell1 nil)
(def login! (mkremote 'my.namespace/login! stem-cell1 ...))

micha00:09:31

you can call the login! function now in the client

micha00:09:34

like for example

micha00:09:37

(let [user (cell nil)
      pass (cell nil)]
  (form :submit #(login! @user @pass)
    (label
      "User: "
      (input :change #(reset! user @%)))
    (label
      "Pass: "
      (input :type "password" :change #(reset! pass @%)))
    (input :type "submit")))

micha00:09:17

when you submit that form the login! function is called with two arguments

micha00:09:00

but notice how the return value of that call is discarded

micha00:09:20

the result will actually end up in the stem-cell1 cell

micha00:09:26

asynchronously sometime later

micha00:09:56

and presumably some user data will end up in there, as that's what the my.namespace/login! function in the server will return

micha00:09:05

if the username and password are okay, that is

micha00:09:25

then you will have formulas looking at stem-cell1 that might hide the login form and show something else

micha00:09:42

but the form you see there doesn't care what happens when the user successfully logs in

micha00:09:58

it just needs to know how to collect the arguments and call that functions

flyboarder00:09:12

where does stem-cell1 get defined? in the hoplon page?

micha00:09:25

you'd need to define that in your application

micha00:09:43

there i updated it

flyboarder00:09:47

ok so it could be any cell

micha00:09:08

you would likely wrap the login form like this:

micha00:09:43

(div :toggle (cell= (not stem-cell1))
  (let [user ...
    ;; login form as above here

micha00:09:57

so the login form is only shown when the user isn't logged in

micha00:09:11

i.e. when the cell containing user data doesn't have any user data in it

flyboarder00:09:32

and that goes for every bit of the application which needs to show or hide itself

micha00:09:48

you'd do it via formulas, yes

micha00:09:08

generally you can have two containers, one for logged in and one for logged out

flyboarder00:09:37

however when doing so avoid nesting cell=

micha00:09:18

(html
  (head ...)
  (body
    (div :toggle logged-out?
      ;; login form here
      )
    (div :toggle logged-in?
      ;; logged-in content here
      )))

micha00:09:54

(defc= logged-in? stem-cell1)
(defc= logged-out? (not stem-cell1))

micha00:09:36

it's pretty easy to reason about this way

flyboarder00:09:44

ok im tracking

micha00:09:05

since no state is being built up by pieces

micha00:09:19

the stem-cell1 cell contains some value

micha00:09:57

and the formulas relationship to it is invariant

micha00:09:10

compare to making an async AJAX call and attaching callbacks to show/hide all the various things

micha00:09:30

that way would tightly couple the login form to all those other things

micha00:09:52

this way the login form doesn't even know that an ajax call is being made, it just calls a function

micha00:09:05

and it doesn't know that anything needs to be hidden or shown

micha00:09:27

so you can factor the whole login form into a separate component that can be used in any application

micha00:09:08

this is the basic model for factoring a hoplon application more or less

flyboarder00:09:34

ok i will need to do some more digging on castra

mynomoto00:09:52

@flyboarder: https://github.com/hoplon/demos/tree/hoplon6/castra-chat is updated to use hoplon6 but not the latest neither castra3. But it runs on boot2 😉

flyboarder01:09:57

@mynomoto: thanks i was looking at that a bit earlier

flyboarder01:09:39

how far off is it from a castra3 implementation?

flyboarder01:09:16

is 2.2 very different from 3?

mynomoto01:09:07

@flyboarder: just a couple of hours, there is not that many differences. For a really simple project you can run lein new hoplon-castra your-project-name to generate a project that uses the latest hoplon and castra.

mynomoto01:09:28

The main differences are internal, cljson -> transit, a castra session. The main practical difference is that castra is now a middleware instead of a handler.

flyboarder01:09:55

as in it does things on both side of the response?

mynomoto01:09:40

*can use it like

mynomoto01:09:56

It intercepts the requests and short circuits it if it's a post request.

flyboarder03:09:37

@mynomoto: so I can mixin any other ring middlewares then as well

flyboarder03:09:10

how does that work with other things such as using the rest routes for an API?\

mynomoto03:09:04

You need to apply the castra middleware only on some of the routes since it intercepts all post requests, so don't apply it on routes that will receive those requests. Other than that you can mix and match at will.

flyboarder03:09:34

sorry not sure what you mean by that?

flyboarder03:09:48

how is it applied to only some?

flyboarder03:09:19

would I be creating an api app with a different route list?

mynomoto04:09:55

got to go now, good night.

flyboarder04:09:08

night, also git the sack

xifi08:09:11

@mynomoto: running boot dev on the hoplon-castra lein template gives me this stacktrace - https://www.refheap.com/109669 Running on windows if that's important

xifi08:09:59

@mynomoto: I just realized I changed clojure's version to 1.8.0-alpha5, 1.7.0 works fine

xifi10:09:39

@micha: I'm looking at spacemacs as you mentioned a couple days ago, man it's huge!

upgradingdave12:09:32

Just got my first castra rpc call working metal

alandipert12:09:42

i just updated and posted a minesweeper game i abandoned, https://github.com/alandipert/hoplon-minesweeper

micha12:09:33

haha awesome

alandipert12:09:58

it needs the expand-adjacent-non-mines function still, but that would be fun to write

micha13:09:39

no wonder that game is a classic

micha13:09:05

also mathiasx's roguelike, that will rule

onetom13:09:19

@flyboarder: we are sharing sessions stored in mongodb between our castra backend and our legacy nodejs app i think i can share the related code if it's not already shared. (though i was just deleting something like that today... i hope it was pushed to some other server simple_smile

xifi14:09:23

@alandipert: the original version had a couple more features, most notably middle-clicking a cell that already had all the flags it needs to set up would flip all the non-flipped neighbors at once

xifi14:09:09

other than that it feels just like the original 😛

xifi14:09:57

@micha: I remember you said formulas referencing other formulas are a code smell to you, yet here in Alan's minesweeper I see many formulas like that

onetom14:09:26

@xifi: i think he was saying something like creating new formula cells within formula cells are a problem (causes memory leak if im correct)

onetom14:09:11

like:

(def stem (cell 123))
(def double-squared
  (cell=
    (let [double (cell= (* 2 stem))]
         (* double double))
vs
(def stem           (cell 123))
(def double         (cell= (* 2 stem)))
(def double-squared (cell= (* double double)))

micha14:09:07

@xifi: referencing other formulas is not bad

micha14:09:13

that's the whole point of having formulas

micha14:09:34

the bad thing is creating new formulas in a formula

micha14:09:50

that's very different from just referencing an existing formula

micha14:09:25

if you do like (cell= (cell= foo)) or something you're creating new formulas each time the thing is recomputed

micha14:09:32

and nothing will ever garbage collect them

micha14:09:41

and there is no need to do this

alandipert14:09:32

@micha: i wonder if cell= should complain if it has cell= in it?

alandipert14:09:44

i guess it couldn't really know

flyboarder15:09:48

@onetom: I would appreciate any code you can share, im still new to clojure so seeing real world applications helps connect all the pieces together, @micha really got me tracking yesterday with the whole application development model in hoplon

flyboarder16:09:00

@micha: am I correct that creating an anonymous cell= at runtime within a cell= would also cause problems

micha16:09:33

@flyboarder that's what i was saying yes

micha16:09:28

the rule of thumb is just don't create new formulas in the body of a formula

xifi20:09:22

I see, thanks @onetom and @micha

xifi20:09:54

I just launched the nukes on my linux notebook, the damn thing won't load my /home partition 😞

flyboarder20:09:11

@micha ah I see that was probably the issue I was having before, refactoring yet again 😛

xifi21:09:37

nukes worked 😅

sjol21:09:10

just a few questions about hoplon, there used to be a documentation but since the new design where has all the data gone?

sjol21:09:56

- is it normal that the "A stateful custom element" example the timers show different times?

sjol21:09:15

- if I wanted to do a SPA that were to live in cordova, can HLisp be compiled to say app.js and be included as a lib? (like OM)

sjol21:09:34

- updates from the server, how are the done?

alandipert21:09:54

@sjol: hi, yes, the old docs are in history but they were too out of date for us to keep public

alandipert21:09:21

to answer your questions: 1. yes it is normal, the point of that demo is to demonstrate that different instances of the same component can maintain their own state

alandipert21:09:58

2. i haven't made a mobile app with hoplon but but others here have

alandipert21:09:57

we advocate https://github.com/hoplon/castra for server comm but any technique you use that can get values into cells is an option

sjol21:09:35

@alandipert: so I should be able to compile the templates to pure Javascript?

alandipert21:09:45

everything compiles to javascript, yes

sjol21:09:48

nice! And have you tried to use javelin with lib like D3.js? are there any caveat I should know about? ( OM has a few, which is why I ask )

alandipert21:09:17

i have done some d3, and there aren't any gotchas i'm aware of

flyboarder21:09:47

@alandipert: i cant seem to get castra-chat to build

sjol21:09:39

great, my intent is to use a cell as the data source and have the data change thus the d3 visualization change

flyboarder21:09:18

it complains about missing hoplon, do the new versions not build yet?

flyboarder22:09:02

Could not locate tailrecursion/boot_hoplon__init.class or tailrecursion/boot_hoplon.clj on classpath

micha22:09:12

flyboarder: can you paste your build.boot file please?

flyboarder22:09:44

right outta the hoplon6 repo

micha22:09:18

i don't see any hoplon dependency in there

micha22:09:35

oh the build/deps

flyboarder22:09:40

this is from the hoplon/demos repo hoplon6 branch

micha22:09:41

i remember now

micha22:09:05

if you look on clojars you can see the versions that will work

micha22:09:50

that demo is probably out of whack with latest developments

micha22:09:16

those things won't be batteries-included until we finish all the moving of things

flyboarder22:09:11

ok sounds good, but im confused as to why it is looking for the tailrecursion namespace at all? it's not in the deps file anywhere

flyboarder22:09:54

wait I see it

flyboarder22:09:38

it was in the boot file above looking for boot-hoplon