These are chat archives for mithriljs/mithril.js

31st
Aug 2017
cmkarlsson
@cmkarlsson
Aug 31 2017 01:00
Has anyone tried mithril with bucklescript?
spacejack
@spacejack
Aug 31 2017 01:15
I assume you'd need some form of FFI
cmkarlsson
@cmkarlsson
Aug 31 2017 02:47
It is more if mithril would suit a more functional style. I.e passing all data in, immutable data structures etc
Isiah Meadows
@isiahmeadows
Aug 31 2017 04:12
@spacejack You would, but BuckleScript is much less bad than most other functional FFIs. (It helps that OCaml is an impure functional language, kind of like Clojure/ClojureScript.)
@cmkarlsson Ironically, React actually works better with OCaml/Reason (alternate front-end), using BuckleScript for the code gen backend.
pakx
@pakx
Aug 31 2017 05:30
@cmkarlsson , I'm just checking my understanding here -- do you mean using Mithril with the js code generated by bucklescript's translation of a source OCaml library? @spacejack ... the end product of bucklescript is (readable) js; would one need a foreign-function-interface?
robinchew
@robinchew
Aug 31 2017 05:50
Hey @isiahmeadows and @pygy, just want to remind you about issue #1916.
cmkarlsson
@cmkarlsson
Aug 31 2017 07:00
@pakx I just wondered if I could use bucklescript to write my business logic and use mithril as a base. as @isiahmeadows mentions I know there are react bindings and there is a translation of the elm architecture which seems fine but I like mithril and just looking into if it would be feasible to create mithril bindings. Or if there will be too much of a clash between different paradigms, (function stateless vs OO stateful)
Isiah Meadows
@isiahmeadows
Aug 31 2017 07:25
@robinchew Thanks for the heads up. I'm still a little strapped on time, but if you'd like, feel free to take a crack at it. All the relevant details start from this comment down; in particular, what they link to is probably more relevant than the comments' text themselves.
robinchew
@robinchew
Aug 31 2017 07:27
I can do the fix, the issue was writing the test.
Isiah Meadows
@isiahmeadows
Aug 31 2017 07:27
I was referring to the mock
robinchew
@robinchew
Aug 31 2017 07:28
oh ok
robinchew
@robinchew
Aug 31 2017 07:34
Will you accept the PR without a test. I can at least add a note in the change-log as botvac suggests.
Patrik Johnson
@orbitbot
Aug 31 2017 07:34
botvac? :smile:
robinchew
@robinchew
Aug 31 2017 07:35
Guy who commented in the PR
Isiah Meadows
@isiahmeadows
Aug 31 2017 07:35
That's @tivac's bot :wink:
Primarily for Danger warnings.
robinchew
@robinchew
Aug 31 2017 07:36
Oh ok. I think bug #1916, is pretty severe, basically the view is not respecting the state. Kind of defeats the purpose of mithril
Isiah Meadows
@isiahmeadows
Aug 31 2017 07:36
@robinchew I'd rather merge a failing test (which I've done before) than no test at all.
robinchew
@robinchew
Aug 31 2017 07:36
alright it's a Go then!
Press that merge
Isiah Meadows
@isiahmeadows
Aug 31 2017 07:39
@robinchew I'm delaying until I get agreement from @pygy (or at least @tivac) on it, but that's probably the only thing blocking merging.
robinchew
@robinchew
Aug 31 2017 07:39
Thanks man
Isiah Meadows
@isiahmeadows
Aug 31 2017 08:53

@cmkarlsson BuckleScript code could end up looking a lot like the equivalent JS code in practice, but you will have to take into account the fact OCaml has a much higher idiomatic preference for stateless code.

OCaml isn't really that far off of what JS would have been like if it was instead expression-based and immutable by default. (The few differences include OCaml's module system, awkward hash maps, and possibly syntax)

As for a start, here's some thought:

  • Mithril supports object components of TS type Component<...>, closure components of TS type (vnode: Vnode<...>) => Component<...>, and class components of new (vnode: Vnode<...>) => Component<...> (where ... is the same across all of them). OCaml has a direct translation of all of them:
    • Records: { foo = bar }, JS interop: [%bs.obj { foo = bar }]
    • Functions: fun vnode -> comp_inst, JS interop: postfix [%bs]
    • Classes: class foo vnode = object (self) ... end, no JS interop with new (because BuckleScript is dumb - BuckleScript/bucklescript#1956).
  • There's a lot of duplication in the generic parameters for the component-related types in Mithril's TS definitions. In particular, Component<...> and Vnode<...> share the same parameters with the same constraints.
  • OCaml could express that very conveniently through judicious use of modules and module functors. A similar TS proposal I made expresses this sentiment very well, if you can make the logical connection between ML modules and Scala's abstract types or Swift's/Rust's associated types.
  • Mithril's types are complex enough that you may want to consult this in depth.
cmkarlsson
@cmkarlsson
Aug 31 2017 09:38
@isiahmeadows Thanks for the pointers. I'll start to play around with it and see where I get
Isiah Meadows
@isiahmeadows
Aug 31 2017 09:47
Welcome and good luck!
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 20:15
hey, i'm having an app with 2 components served via a wrapper with vnode.children. the thing is both of them are updated when they should not.
Tim Killian
@tskillian
Aug 31 2017 21:32
If I pass an array to a component through attrs, and that array changes, the component it was passed to should run its view method for virtual diffing purposes right? Trying to figure out if my understanding of this is wrong or there must be something wrong with some of my code :)
spacejack
@spacejack
Aug 31 2017 21:35
@tskillian it will render the current values of attrs, but render is not triggered when attrs values change.
Redraws are triggered automatically by event handlers and m.request
If data changes on some other event like a timeout or socket or events that occur outside of mithril's knowledge, then you need to call m.redraw() yourself.
Tim Killian
@tskillian
Aug 31 2017 21:42
i see, that makes sense - I was just manually pushing objects to the array from the console expecting the view to change
thanks @spacejack
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 21:45
i updated my example to make an ideea about what i mean https://jsfiddle.net/cmnstmntmn/nnwuk034/
Rasmus Porsager
@porsager
Aug 31 2017 21:56
@cmnstmntmn view functions are always called unless explicitly cancelled, so the count will go up for every redraw, hence the update..
(your onkeyup is calling redraw)
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 21:59
i see. so i should go for components as functions (without view)
hmm, the thing is that i'm having multiple inputs triggering an object update; using onupdate at the component level was nice, and i did not have to trigger an update function for each event
Rasmus Porsager
@porsager
Aug 31 2017 22:02
No you shouldn't mutate values inside your view function 😉 (vnode.attrs.count++)
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:04
should i use flyd over a global object? and then trigger an update from inside the modified object, and not from the component
Rasmus Porsager
@porsager
Aug 31 2017 22:09
Sorry, i'm not quite sure what your issue is.. In the fiddle you posted you were increasing a counter at every redraw, but expected it not to increase?
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:09
right
i mean if each components are keyed, the redraw should only happen for the 'current' component? not for the whole application
Rasmus Porsager
@porsager
Aug 31 2017 22:12
Ok. Mithril calls all view functions of components in your tree, and uses the return value to diff with the previous value. If you increment a value inside the they function like that it will be diferent than the previous value and mithril will update the dom..
What are you trying to achieve?
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:16
well, i have let's say two components in the same app
each of them, contains some input, and with every update i want to trigger an update function that will update a real DOM element
https://jsfiddle.net/cmnstmntmn/nnwuk034/6/ i've mande an example here
and somehow they should be independent; when comp1 is updated only the dom1 should be affected and vice-versa
pakx
@pakx
Aug 31 2017 22:18
@porsager , IMO the "issue" was better demonstrated in @cmnstmntmn 's first example. But even in this example, for comp2, change its view to output a static number, say 22. Then run code. Now enter "a" in the input box. Look at browser log -- it shows "comp updated comp2". i.e. comp2's onupdate was called. Why? (I would expect it to be called only if there were an actual diff/update for comp2.)
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:25
indeed
Fred Daoud
@foxdonut
Aug 31 2017 22:29
@cmnstmntmn I'd like to buy a vowel. ;)
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:30
:scream:
Rasmus Porsager
@porsager
Aug 31 2017 22:33

Ah.. Now I get it 😊 Afaik onupdate is always called.. The docs here could be read is if it would only be called on dom changes..

But here it's pretty clear it's every redraw with vi dom element present.

Hmm.. The example in the first link actually shows the same.. An empty view function but a counter incrementing at every redraw..
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:37
it is the same. i just added the behaviour of the console inside the view
Rasmus Porsager
@porsager
Aug 31 2017 22:38
@cmnstmntmn it's how it's supposed to work 😊 Why can't you just change what you need to change in your onkeyup handler?
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:42
well i could do that, but each events keyups , onchange from inside components i have to do two things: to alter the object (the default behaviour) and then to call a function that will output the object to the real dom
using onupdate .. was one timer;
Rasmus Porsager
@porsager
Aug 31 2017 22:45
Could you try to do it like that in a Flems or fiddle? Then it might be easier to spot how it can be improved..
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:46
well something like this
i don't know if it's understandable
Rasmus Porsager
@porsager
Aug 31 2017 22:47
And you want to do the exact same thing in each event?
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:48
just a sec
Rasmus Porsager
@porsager
Aug 31 2017 22:52
Aight, I'm of to bed, but maybe someone else can help 😉 If not i'm here en about 8 hours again 😋
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:53
hehe, sure take your time :D
pakx
@pakx
Aug 31 2017 22:53
Hhh, to me it makes little sense that a lifecycle event named onupdate would be invoked when nothing has been "updated". Unfortunately this happens even when not using "components" per se. Flems here
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 22:54
thank you
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 23:07
hmm, very weird
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 23:13
it's understandable because it's the same element obj2 referenced
Constantin Angheloiu
@cmnstmntmn
Aug 31 2017 23:22
i think i understand now; an update hook it, triggered by m.mount every time an event occurs, everywhere inside/outside the current component