Fork me on GitHub
#off-topic
<
2017-01-01
>
sveri19:01:02

Although that "Enjoy the thrills of incomprehensible error messages because it’s all minified and the function names are meaningless. Savor the perverse joy you feel when you can actually read what the JS is doing anyway" sounds tough πŸ˜„

notanon19:01:31

it's really a nightmare these days

notanon19:01:59

babel -> es5 -> min/concat

notanon19:01:18

if you even understand whats running you're lucky

notanon19:01:46

or lately all these Java/OOP but JS noobs using typescript

notanon19:01:52

my company is crazy fo r typescript

notanon19:01:57

it's so gross

notanon19:01:15

people cant tell if the code they're writing is TS, ES2016 or just JS

notanon19:01:33

JS feels like it's going backwards

notanon19:01:57

when they introduced Object.create in ES5, it was perfect

notanon19:01:27

now they have classes and all these OOP constructs that add no value but have complicated the language and fractured the ecosystem

notanon19:01:21

you've seen this i assme

notanon19:01:51

that book on the left would be 2x as thick now

notanon19:01:59

and the good parts would still be about the same

notanon19:01:11

maybe an update for async/wait and destructuring

sveri19:01:46

I wonder if there will be a time when the progress will get slower and one can start relying on an API / featureset

notanon19:01:04

i think ES2017 will tell us

notanon19:01:15

if they keep going crazy for a 3rd year in a row...

notanon19:01:19

i dont think there's any hope

notanon19:01:36

although i've stopped paying attention at this point

notanon19:01:45

CLJS is so far ahead of JS πŸ™‚

sveri19:01:50

Yea, I think so too. But then try introducing cljs in a corporate where everyone is going with angular or react

notanon19:01:10

im actually having that battle right now

notanon19:01:31

we have a technical roadmap co-location meeting at the end of the month

notanon19:01:47

im putting together a presentation to outline our UI plans

notanon19:01:15

we have 3 angular 1 apps. and the whole organization is just assuming ng2 is the way to go

notanon19:01:31

im in quite a bind... i don't think ng2 is the way to go

notanon19:01:50

but i cant support writing new apps in ng1 either

notanon19:01:58

google really %#$@*@ us

notanon19:01:23

but theres support for react in other departments

notanon19:01:40

but try explaining immutuable data to my team...

notanon19:01:57

no easy path forward 😞

sveri19:01:01

Yea, its never easy πŸ˜„ I am not even trying really. My teamlead is very open and with have discussions about my findings and theories, but he is almost the only one. Also we have a team that builds web components for the whole business (like almost a thousand developers in total) and they started a few months ago with react. I saw the evaluation of different javascript frameworks by chance afterwards but cljs was nowhere to see.

notanon19:01:52

at least in my company... they only know of the big languages... java/js/c#

notanon19:01:04

other languages simply do not exist, because they have never heard of them

notanon19:01:25

but i would say, if you want to look on the bright side

notanon19:01:33

react is a giant step towards CLJS

notanon19:01:49

both depend on immutable data

notanon19:01:07

and both keep all state in that immutable structure

notanon19:01:35

and JSX is an extremely similiar concept to hiccup/rum/reagent with representing dom elements as data

sveri19:01:52

I never looked at react really, that sounds good πŸ™‚

notanon19:01:52

react and cljs like pure functions

notanon19:01:15

for JS, it's revolutionary

qqq19:01:31

it amazes me that ppl using js invented react

notanon19:01:32

for clojure it's just like 'duh, we already do that :)'

notanon19:01:01

lol yea no kidding, it's such a departure from the JS mindset

notanon19:01:05

kind of a miracle

qqq19:01:46

it's possible they suffer from callback hell more than anyone else, and were forced to invent it --- i.e. it's imposssible to write js gui apps without react

notanon19:01:17

as the proud owner of a several angularjs 1 bugs that simply cannot be reproduced or fixed

notanon19:01:30

because no one can understand the client's state at runtime

notanon19:01:35

...i'd have to agree

notanon19:01:22

we get the same bug reported about once a month with the user saving data but then it disappears

notanon19:01:37

we've put logging on every line of the js

notanon19:01:40

and on the rest endpoint

notanon19:01:48

lol still cant figure out wtf is happening

notanon19:01:12

it's the second biggest reason i dont want to use ng2

notanon19:01:34

just more of the same... spaghetti woven state machines are impossible to reason about

qqq19:01:46

I've recently gone to the extreme other end

qqq19:01:55

re-frame -- all state is in one giant db

qqq19:01:03

all views is a function of the db

qqq19:01:06

so much easier to reason about

notanon19:01:48

that sounds like heaven

notanon19:01:37

i havent used re-frame, will check it out

qqq19:01:37

there's also a #re-frame channel here

notanon19:01:39

i've been trying to figure out whehter i should any library tbh

qqq19:01:41

it's very helpful

notanon19:01:01

om, hoplon, re-frame, om.next, untangled

notanon19:01:11

lots of options

qqq19:01:19

I went the process of: (1) react is dumb, I don't need react -> (2) I can implement react beter myself -> (3) I should use a library ==> reagent --> (4) I need more, re-frame

notanon19:01:19

and they're all complicated

qqq19:01:23

reagent is very simple

qqq19:01:31

re-frame is also very simple after you get reagent

qqq19:01:39

it also provides re-com, which is an amazing UI library

notanon19:01:45

ill have to check it out today

notanon19:01:54

i was just going to dig into rum actually

sveri19:01:57

I would vote for reagent

notanon19:01:03

but you've changed my mind for now at least πŸ™‚

sveri19:01:13

Its a good mixture between react and re-frame

notanon19:01:45

i tried reading thru the re-frame stuff a couple weeks back

notanon19:01:03

i can't remember why i stopped

qqq19:01:13

it's heavy on philosophy and light on 3examples

qqq19:01:40

https://reagent-project.github.io/ <-- I'd start with this, and move ot re-frame only when you feel "I have too many reactive atoms; I wish they were all centralized in one place"

notanon19:01:35

thats what i went thru a couple weeks ago

notanon19:01:39

maybe i never made it to reframe

notanon19:01:16

ah yeah i remember going to the github... so much text to get thru

sveri19:01:42

Hm, you can as well just have one ratom with reagent. There is nothing against it AFAIK

qqq19:01:12

sveri: in theory, yes, in practice ...

notanon19:01:14

nothing stopping you from doing that yourself, no?

sveri19:01:36

@qqq Ok, I listen, have never used it in a heavy app myself, so I am curious

notanon19:01:04

same, curious for your opinion

qqq19:01:22

I may be wrong, but I believe the reason this is a bad idea is due to impl of reactive-atom

qqq19:01:44

so the way the reactive-atom works, is that when you de-ref one, you lookup the callsgack, find the nearest (fn [] .... )

qqq19:01:52

and you go "this dude needs to be re-evaluated if I ever update"

qqq19:01:57

(this is to ensure you always show latest)

qqq19:01:09

so the problem with just one reactive atom -- is that any time anything updates, the entire UI is recomputed

qqq19:01:24

the alternative to this is lots of small reactive atoms -- but now you have distrubuted state

qqq19:01:38

one thing re-frame does is "centralixed state, but you can subscribe to "keys" "

qqq19:01:52

so it's sorta like "if (get-in [key set] central-state) " changes, then call a update

qqq19:01:55

but the state is still centralixed

qqq20:01:03

does this make sense, or am I being confusing?

notanon20:01:27

that makes perfect sense

notanon20:01:44

does re-frame have it's version of r/atom?

qqq20:01:58

I believe it's built on top of reframe

qqq20:01:11

err, reframe built on top of reagent

sveri20:01:13

Hm, I remember having used reagent with one atom and only parts of the application were updating itself. Otherwise you would not be able to have two text inputs in one atom. Or did I misunderstand you?

qqq20:01:29

you can have two text inputs ikn one atom {:top-field ... :bottom-field ... }

notanon20:01:09

if i understand you correctly @qqq you're saying that in that example of top-field and bottom-field being in one atom, a change to top-field might cause a re-render of bottom field as well

sveri20:01:40

Yes, thats how I understood it too, but thats not the case.

notanon20:01:45

and in re-frame, each component will subscribe to just the elemtns they care about like 'give me updates to :top-field'

notanon20:01:00

ah, really?

qqq20:01:22

@sveri: can you give sample code?

sveri20:01:34

Yes, it would be a bit pointless to have one atom for every "mutable" object in your UI.

qqq20:01:59

@sveri: suppose you have (:top-field @state-atom) .... when state-atom changes, it has to recall the outer fn ... I doln't see how it can infer "well, my parent is :top-field, so if :top-field does not change, I don't have to re-render)

sveri20:01:25

@qqq The last time I used it is a bit ago, so not out of my head. But, if you want to, I wanted to livecode anyway, we might look into that too

qqq20:01:10

can you say something? I want to see if voice/sound works

qqq20:01:22

cool; thanks

qqq20:01:43

this is f*cking awesome

qqq20:01:17

what editor / ide are you using? cursive ?

notanon20:01:46

yea that surive

qqq20:01:23

I think we just have to modify "current-page"

qqq20:01:56

text field lools good

qqq20:01:00

(let [state (ratom {:age "" :name ""})] .... )

qqq20:01:12

(swap! state assoc-in :name ... )

qqq20:01:54

oh, retrieetinv value

qqq20:01:58

you need it

qqq20:01:00

e.target.value

qqq20:01:26

(.-value (.-target %)) <-- might work }

notanon20:01:33

^^ πŸ™‚

notanon20:01:00

let me see if there is a dom api for re-render

qqq20:01:31

maybe something like this

qqq20:01:46

[:pre (do (. js/console log "we rerender") "hello world")]

notanon20:01:08

ye athat might work

qqq20:01:54

live coding is so cool

qqq20:01:58

I have to try this in the future

notanon20:01:42

a complex UI with a dozen form fields... nested tabs, etc

notanon20:01:45

a wizard ui

qqq20:01:51

this must be what it's like to be a manager; someone else does all the work, and you just comment

notanon20:01:41

did it render both again?

qqq20:01:49

it appears to be rendering both

notanon20:01:18

isnt there like a '4th' type of reagent component

notanon20:01:25

i think they mention this in the intro tutorial thing

qqq20:01:58

there's 3 iirc: (1) use standard ones, (2) use one wrapped in a (fn [] .... ), (3) roll your own (for crazy things like canvas/webgl); I don't know of this mythical 4th type

notanon20:01:13

lol im sure you're right

notanon20:01:18

i dont remember

notanon20:01:56

maybe if you didnt @state but instead passed :name in to the render fn

notanon20:01:23

defn sub1 [name]

notanon20:01:50

get rid of @state

notanon20:01:13

and in current-page, wrap sub1/2 in lambdas

notanon20:01:02

thats a big difference

qqq20:01:10

how does this work?

notanon20:01:12

that should be highlighted in big bold letters on reagent page

qqq20:01:19

it checks if the args are the same, and does not re-eval if arg does not change?

notanon20:01:37

yeah, thats what the perormance section seems to imply

qqq20:01:45

I agree that it's not re-rendering, but I have no idea by what mechanism are we avoiding the re-render

notanon20:01:49

it will only re-render if params are diff

qqq20:01:57

is (:name s) a parameter in this case?

notanon20:01:14

in current-page [your-comp takes-your-args]

qqq20:01:30

I'm really glad you did this

notanon20:01:32

since takes-your-args didnt change

qqq20:01:39

I would not have undertood it otherwise

notanon20:01:53

i feel like i just learned reagent in a couple minutes πŸ™‚

qqq20:01:06

pay sveri tuition πŸ™‚

notanon20:01:38

secretary to do routing?

notanon20:01:42

i thought that was a server library

qqq20:01:14

we should have sveri do these live sessions for all useful clj/cljs libraries

notanon20:01:28

do you make your links on-click and call secretary?

notanon20:01:39

or does secretary hook into navigation api

notanon20:01:05

how do you navigate to about-page?

notanon20:01:30

wheres the link?

notanon20:01:50

acccountant?

notanon20:01:16

very easy to use

notanon20:01:30

will definitely check reagent out

notanon20:01:46

i'd rather have small libraries that do one thing

notanon20:01:55

than a big library that tries to handle everything

notanon20:01:38

theres a html5 shim that adds history api to older browsers

qqq20:01:41

sveri: off topic: are you on the free, 9.99, or 99.99 / month plan?

notanon20:01:51

by adding #routes to the url

notanon20:01:19

twitch resolution is too fuzzy to read code IMHO

notanon20:01:23

and big delay

qqq20:01:23

it's juyst amazingly sharp at 1080p w/ no lag

notanon20:01:00

yea that looks fine

notanon20:01:22

thats awesome. the delay would kill livestream code

notanon20:01:30

since voice and typing need to align

notanon20:01:33

thx for demoing this

qqq20:01:08

yeah; thanks for demoing this

qqq20:01:11

how do I start streaming myself?

notanon20:01:28

download OBS

notanon20:01:55

even if not, obs is really good for streaming

notanon20:01:12

makes it very easy to set it up and control whats displayed

notanon20:01:20

free too πŸ™‚

qqq20:01:08

ah, all what http://livecoding.tv provides is a FMS Url and Streaming key

qqq20:01:11

it's up to me to stream data to that url

qqq20:01:15

okay, so yeah, probably OBS

notanon20:01:21

most of them are like that

qqq20:01:25

@sveri: are you using OBS to stream ?

notanon20:01:29

twitch, etc

sveri20:01:44

Yes, I did use OBS

sveri20:01:54

right now in the stream

sveri20:01:39

Although it does not work on my laptop where I have dual graphics (nividia / intel) which is a pity and I had to install some other software (I cannot remember the name right now) which is shareware and was way harder to setup

qqq20:01:54

got it; thanks

sveri20:01:25

did you register already?

qqq20:01:13

only with a throwaway to test out privacy / security

qqq20:01:21

I'm looking at it as an alternative to google hangout sessions

qqq20:01:32

where screen sharingis blurry as hell and nothing compared to the live streaming you just did

qqq20:01:56

looks like I need to pay if I want to control who can view the stream

sveri20:01:57

really? one would think that google knows how to transmit quality streams

qqq20:01:01

so as long as I'm streaming < 1 TB, it's cheaper to just pay Digital Ocean $5 / month than the $9.99 http://livecoding.tv paid account

notanon20:01:30

thats neat

notanon20:01:49

it's important you control who watches though?

qqq20:01:52

it's really simple too; and worked first try

qqq20:01:13

yeah; it's for a study group, people probably don't want their comments archived

sveri20:01:13

Hm, setting up my own rtmp server would be nice too, but then, where is the reach. In your case it makes sense. When I livestream I want to reach people and have some kind of chat about coding stuff.

qqq20:01:45

absolutely; if you want to share http://livecoding.tv is where it's at; if you want it to be private, private stmp server is the way to go πŸ™‚

qqq21:01:05

we should do more of these sessions

qqq21:01:10

are there common libraries we all want to study?

qqq21:01:23

(these sessions can be public; these don't need to be private)

notanon21:01:37

im pretty curious, wouldnt mind hanging around for probably almost anything

notanon21:01:47

the topics i've been looking into lately are datomic and spec

notanon21:01:56

but i assume that's old news for most clojure people πŸ™‚

sveri21:01:19

I am working on a project for some time, a web application and I might stream tomorrow evening again πŸ™‚

sveri21:01:30

Depending on how my work day was+

notanon21:01:43

if im around ill check it out

notanon21:01:55

i follwed u on livecoding

sveri21:01:15

Yea, cool, I just refollowed you πŸ™‚

notanon21:01:51

oh man, my first follower!

qqq21:01:20

I'd be interested in studying "deploying on AWS / figuring out of I can cider/nrepl into a live server / clj interacting with s3 /rds / storage "

qqq21:01:37

was on GAE a few weeks ago

notanon21:01:48

i would definitely like to figure out nrepling into a running remote server

qqq21:01:01

but not liking the hoops I had to jump through to setup ring handlers to work on google app engine / warm startups

notanon21:01:02

i have deployed clojure to AWS for work

notanon21:01:11

on an EC2 instance, very easy stuff

notanon21:01:37

i just used lein-ring plugin to generate an uberjar

notanon21:01:52

then copy the file to the ec2 instace and java -jar... so so easy

qqq21:01:03

interesting; so right now, dev locally = I have figwheel, but not AWS resourdces; ... package + push = aws, but no figwheel

qqq21:01:11

how did you "mock" aws resourdces locally ?

notanon21:01:28

i don't πŸ™‚

notanon21:01:56

do you mean mocking like a aws cloud db?

qqq21:01:18

so the app, in the end, needs to talk to aws db servies right ?

qqq21:01:24

so when you're developing , how do you test taht?

notanon21:01:24

yeah it calls dynamo

notanon21:01:33

i just connect to the actual dynamo

notanon21:01:51

i dont do much unit testing

notanon21:01:57

(much meaning, any at all)

notanon21:01:10

would love to see the value

notanon21:01:24

but i always end up regretting writing them

notanon21:01:38

and they almost always end up #_

notanon21:01:56

because i get tired of maintaining them for no purpose

notanon21:01:11

thats why im so interested in spec... i want to see if generative testing can be useful

qqq21:01:34

hmm, thinking of spec in terms of "not writing unit tests" is very interesting

sveri21:01:48

I am not sure, but I think for generative testing it only makes sense if you can define useful invariants

sveri21:01:00

like in the spec examples

notanon21:01:27

i was thinking about it like this:

notanon21:01:39

my functions make assumptions, like this value is not nil

notanon21:01:43

or this is anumber

notanon21:01:48

or i have these keys

notanon21:01:12

if i can generate the tests/data, i will find out assumptions that i didnt realize or think about

notanon21:01:55

but when i look into how to generate non-trivial data

notanon21:01:02

it seems like quite a bit of work

notanon21:01:20

but... i really havent given it enough effort to know

qqq21:01:44

the difficulty there seems to be generating interesting test cases ayutomatically

qqq21:01:01

suppose you're testing a db, with inserts / deletes / queries; generating interesting tripl.ets randomlly seems very hard

notanon21:01:29

thats a good example tho

notanon21:01:35

say i have a people table

notanon21:01:46

i can generate a 'person' map

notanon21:01:02

and maybe my db has name as 50 varchar

notanon21:01:11

but my function forgot to guard against length > 50

notanon21:01:30

i would think the generative tests could find something like that

sveri21:01:40

Thats true

sveri21:01:01

might be interesting to look into that further. I would be up for it in my next stream

sveri21:01:09

I have specced my db functions anyway

sveri21:01:21

but not used generative testing up to now

notanon21:01:51

i'd be interested in seeing your spec'd db functions

notanon21:01:35

although... now that i think about that scenario

notanon21:01:55

the generative test wouldnt help, unless you actually executed the inserts/etc

sveri21:01:17

of course, I have a test database for my database tests πŸ˜„

notanon21:01:19

since the function wasnt guarding against length > 50

notanon21:01:34

hmm. would be interesting to see if it works/provides value

qqq21:01:39

my current (terrible) unit testing practice is this: 1) I write code 2) something breaks 3) I try to debug by testing sub expressions and what I expect those sub expressions to be 4) I save these expectations as unit tests

notanon21:01:59

i wouldnt call it terrible πŸ™‚

qqq21:01:19

maybe I should call it lazy, it's unit tests on demand only when you need them

notanon21:01:21

i can't understand the write-the-test-first mentality

notanon21:01:43

i write code by having a problem and trying to solve it

notanon21:01:53

i can't think about the code as if i already had the problem solved

notanon21:01:01

thats why i love the repl so much πŸ™‚

notanon21:01:17

i can hack away until i get it right, and then copy/paste into my source file

sveri21:01:57

Hm, I was working in house once, we were developing with 3 guys for over 6 months and not writing one single test. It was a mess. Our web service also provided the basis for bills and invoices and the uncertainty about if my now code broke some important stuff that could actually cost us a lot of money was just bad.

notanon21:01:19

that does sound scary

sveri21:01:13

It definitly was. They had some investors and were 1 year late with the software when I joined. The investors said something like, get it done until end of the year or everybody will be gone, so it was a do it or just leave the job.

sveri21:01:25

But still, its just stupid to work that way.

qqq21:01:43

@sveri: how do you unit test ?

sveri21:01:23

Its a bit different. At work we test almost everything. Unit Test, Integration tests, system tests, UI tests.

sveri21:01:01

For me myself I start writing tests whenever a function does not do what I thought it would do. So when exploring in the repl is not enough because I dont want to call the same function with different arguments again and again.

sveri21:01:16

So I just keep my REPL stuff in the test namespaces, basically, its not much more.

qqq21:01:49

so you type the stuff you want to eval/test in the _test.clj file, then C-x C-e it, instead of directly typing it in the repl?

notanon21:01:23

C-x C-e? is that a emacs thing?

qqq21:01:38

eval-last s expr

sveri21:01:42

No, I do put the (deftest ... stuff around it, but usually thats it. (deftest (call-fn (is (= expected-rs result)))

qqq21:01:10

sveri: directly in the source file ?

sveri21:01:34

yea, so in the end I have tests

sveri21:01:24

like here for instance: https://github.com/sveri/getless-clj/blob/master/test/clj/de/sveri/getless/db/food_test.clj#L25 If you look at it, its just the call to the function in question with some boilerplate to make it a permanent test

sveri21:01:38

Testing in clojure usually is very easy, thats what I find at least

sveri21:01:16

and thats already with test database setup

sveri21:01:11

https://github.com/sveri/getless-clj/blob/master/test/clj/de/sveri/getless/service/activity_test.clj Here its even less to do. And for exploring in the repl you would have to rerun the same function with different arguments. And if you look at it like that, tests make your life easier as they take the work to reevaluate everything again and again from you.

notanon21:01:40

yeah that seems helpful to me

notanon21:01:16

it's basically just taking the code i'm already executing in repl and making sure it continues to work that way

notanon21:01:58

not sure how it will pan out over time

notanon21:01:30

yeah... i dunno... maybe πŸ™‚

notanon21:01:40

i will try it out and see

sveri21:01:58

yea, just go ahead and do what you have to do πŸ™‚