These are chat archives for mithriljs/mithril.js

8th
Apr 2016
lochrist
@lochrist
Apr 08 2016 00:36
github
James Forbes
@JAForbes
Apr 08 2016 00:56
woah I missed a lot of interesting conversation last night!
James Forbes
@JAForbes
Apr 08 2016 01:16

Hey @lhorie may I suggest an alternative data structure for the underlying hyperscript, seeing as you are undecided and exploring things?

I am proposing, you'd still be able to use m('div', ...), but the underlying structure is almost as readable as the invocations.

  1. Less memory usage (no closures)
  2. Faster (no need to invoke lots of little m conversion calls
  3. Potentially simplifies a lot of the internals of mithril, less (Object.keys) calls as an example
  4. Kind of like a handwritten mithril-objectify

What if it the output of m was so similar in structure to the invocations, that in some cases, you could write the data output directly, and save your callstack/memory usage. Something like:

//model
var text = m.prop("")
var count = m.prop(0)

//view

[ 'div',  [], [
   ['input', [ 
       ['type', 'text' ],
       [ 'oninput',  m.withAttr('value', text)]  //fig 1.
 ]],
  ['button', [
     ['onclick', count, [ count() + 1 ]] //fig 2.
  ], 'Increment']
  ['p', [
     [' style', [
          ['font-family', 'Helvetica'],
          ['font-size', '2em']
     ]]
  ], 'The count is '+count() ]
]]

I think the attrs and the style are pretty self explanatory. But I just want to quickly talk about event handlers.

In mithril, there are generally two kinds of event handlers.

  1. Receives values from the dom (input[type=text])
  2. An action, that will trigger an internal modification (a counter with a button for inc/dec)

Snabbdom has this great idea where in the case of 2. you don't need to do any binding, you just specify the args to call the function with if it were fired.

function clickHandler(number) { console.log('button ' + number + ' was clicked!'); }
h('div', [
  h('a', {on: {click: [clickHandler, 1]}}),
  h('a', {on: {click: [clickHandler, 2]}}),
  h('a', {on: {click: [clickHandler, 3]}}),
]);

So I'm just stealing that idea. But I'm suggesting the arguments are always an array (this is a low level API), so there is no need to do any arg slicing. It's all about performance.

So in fig1, there is no array in the index[2] so there is no need to bind, just call the handler directly.

In fig2, there is an array of args. So we just pass them along.

[eventName, handler, args] = event // the array from above

window.addEventListener(
  eventName.replace('on', ''),
  args 
   ?  _ => handler.apply(null, args)
   : handler
)

Also, while we're on crazy ideas.

What if the document fragment was passed into the controller on init.
It removes a lot of that weird awkward code when you are passing state between config and the controller.

I'm not 100% sure how that would work. Particularly when you don't know what the root element tag will be for a component. But it might simplify things?

@barneycarroll I like this function sandwich idea, we should get on that
spacejack
@spacejack
Apr 08 2016 02:48
@JAForbes pretty neat stuff!
I can't speak to its feasability but I have to say the idea of data structures is quite appealing.
khades
@khades
Apr 08 2016 03:39
mm sandwich
James Forbes
@JAForbes
Apr 08 2016 04:50

@spacejack thanks, I'm curious what @lhorie thinks about the feasibility too. Perhaps its harder to traverse/index. If everything is a list, it becomes hard to know if you are looking at a tag, or an event handler, or a style object without having more context while traversing.

One nice aspect of this list approach, is augmenting elements after the fact with standard list operations.
And not overwriting existing keys:

['ul',, [
   ['li',[], 'Apples'],
   ['li',[], 'Bananas'],
   ['li',[ ['style', ['font-family', 'Helvetica'] ] ], 'Oranges']
]]
.map(colorizeList)
var colorizeList = ul =>
  ul => ul.map(
       li => li[1].concat(
         ['style', [
              ['color', randomColor()]
         ]]
       )
   )

The colorizeList function adds a style tag to each li, but the existing structure already had a style list. In the old structure,we'd need to use 'Object.assign' or something.
But in this new system, we just add our style list and they both coexist, like 2 separate stylesheets.

The conflicting li just becomes:

['li', [ 
   ['style', ['fony-family', 'Helvetica']],
   ['style', ['color', 'rgb(111,123,123)']]
], 'Oranges']
There is no awkward merging of objects or traversing keys and then zipping them back to the object
James Forbes
@JAForbes
Apr 08 2016 04:56

Again, you'd still be able to write:

m('li', { style:{ fontFamily: 'Helvetica' } }, 'Oranges')

This is just a low level thing.

Barney Carroll
@barneycarroll
Apr 08 2016 07:16
@JAForbes the way you illustrate that is really interesting
I believe DOMVM has everything as arrays
As does the great ancestor of Javascript virtual DOM, JSONML
Barney Carroll
@barneycarroll
Apr 08 2016 07:22
Have you seen t7?
I'm wondering how easy it would be to write a simple MSX adapter with something like that
Closing tags instead of loads of ])})}
James Forbes
@JAForbes
Apr 08 2016 08:42

Hadn't heard of either @barneycarroll

But you are right: https://github.com/leeoniya/domvm/blob/1.x-dev/demos/TodoMVC/js/view.js#L21

Barney Carroll
@barneycarroll
Apr 08 2016 09:09
Leo, based on your insights into Inferno + t7, was the conclusion that t7 was too slow for parsing string input on every draw?
I started off with 'closing tags do make things clearer sometimes' and 10 minutes later I'm attempting to write an HTML parser from scratch on the train
Don't do programming kids
khades
@khades
Apr 08 2016 10:12
what's the best way to concatenate js files and uglify them?
gulp/grunt plugins
Stephan Hoyer
@StephanHoyer
Apr 08 2016 10:13
there is no such thing as "the best way": I prefer browserify+uglify
Barney Carroll
@barneycarroll
Apr 08 2016 10:13
Stephan's preference = the best way ;)
Stephan Hoyer
@StephanHoyer
Apr 08 2016 10:13
hehe
James Forbes
@JAForbes
Apr 08 2016 10:40
@khades are you on a unix flavour or windows?

This is my development script:

watchify modules\ui\src\index.js -d -p [ tsify ] -t [ babelify --presets [ es2015 ] ] -o dist\bundle.js -v --poll=1000

It's processing both typescript and es6

And this is the production script with uglify

browserify modules/ui/src/index.js -p [ tsify ] -t [ babelify --presets [ es2015 ] ] | uglifyjs -mc > dist/bundle.js

So you can just take out -p [tsify] and -t [babelify --presets [es2015 ]] if you are not using anything like that. I include it because sometimes involved examples are better than simple examples

Barney Carroll
@barneycarroll
Apr 08 2016 10:46
You're on TypeScript @JAForbes ?
James Forbes
@JAForbes
Apr 08 2016 10:48

tentatively, the js language support in vscode is terrible since the latest typescript salsa update. As soon as you make a file .ts all the old functionality comes back.

feels like a bait and switch

The ts thing is new for the branch that I'm on, we'll see
Barney Carroll
@barneycarroll
Apr 08 2016 10:48
Aha
So you're saying simply by telling the IDE it's TypeScript not JavaScript it's suddenly aware of your dependency graph and API surface?
James Forbes
@JAForbes
Apr 08 2016 10:49
@isiahmeadows mentioned the string literal types the other day, and I thought that would map really well to Elms Action Type approach
@barneycarroll yes exactly, its ridiculous
but I really like this new flag they are adding in this new release, no implicit nulls
I also wrote a crazy eslint config recently. I'm hoping with the union types, string literal types, no implciit nulls, immutable eslint plugin, I can get a pretty Elmy environment
Barney Carroll
@barneycarroll
Apr 08 2016 10:52
Here's how far I've gotten so far
import as from 'asarg'
import m  from 'mithril'

export default ( [ open, close ], content ) =>
  close.replace( /$\s*<\/|>\s*^/ )::as( tag => 
    m( tag, content )
  )

// Usage:
// m`<ul>
//   ${ list.map( item =>
//     m`<li>
//       ${ item }
//     </li>`
//   ) }
// </ul>`
Wow
That syntax highlighting is terrible
Hmm. Slightly better
James Forbes
@JAForbes
Apr 08 2016 10:53
gitter :/
Barney Carroll
@barneycarroll
Apr 08 2016 10:53
Aha specify es6 not javascript
m`<ul>
  ${ list.map( item =>
    m`<li>
      ${ item }
    </li>`
  ) }
</ul>`
Why? Because "designers love HTML"
And curly brackets
And dollars
James Forbes
@JAForbes
Apr 08 2016 10:54
not enough computer science in there
Barney Carroll
@barneycarroll
Apr 08 2016 10:54
Who doesn't love dollars
I know man
Barney Carroll
@barneycarroll
Apr 08 2016 10:56
Hahaha
Yeah
The lightweight anti-pattern
Works for the simplest scenario, only took me 20 minutes
James Forbes
@JAForbes
Apr 08 2016 10:56
which is pretty astonishing
Barney Carroll
@barneycarroll
Apr 08 2016 10:57
Therefore the 913545677e45 edge cases will only take me like a day, right?
James Forbes
@JAForbes
Apr 08 2016 10:57
are you using a babel plugin for :: ?
Barney Carroll
@barneycarroll
Apr 08 2016 10:57
Yes
James Forbes
@JAForbes
Apr 08 2016 10:58
How are you finding it? Any patterns emerging?
Barney Carroll
@barneycarroll
Apr 08 2016 10:59
I've decided it's wrong
It's a functional plaster on a deep OOP wound
The plaster is now infected
Pipe operator is superior in every way
^ That's my hack to make :: work in a more functional way
( expression )::as( expressionResult => { /* whatevs */ } )
James Forbes
@JAForbes
Apr 08 2016 11:02
I'm finding it hard unwrapping it in my head
what would it look like in es5
close.replace( /$\s*<\/|>\s*^/ )::as( tag => 
    m( tag, content )
  )
Barney Carroll
@barneycarroll
Apr 08 2016 11:03
(function( expressionResult ){ return /* whatever */ }( expression ))
James Forbes
@JAForbes
Apr 08 2016 11:04
but that specific code snippet
Barney Carroll
@barneycarroll
Apr 08 2016 11:04
export default ( [ open, close ], content ) =>
  m( close.replace( /$\s*<\/|>\s*^/ ), content )
James Forbes
@JAForbes
Apr 08 2016 11:04
I might just be braindead from working with AWS all day
Barney Carroll
@barneycarroll
Apr 08 2016 11:05
Or
export default ( [ open, close ], content ) => {
  const tag = close.replace( /$\s*<\/|>\s*^/ )

  return m( tag, content )
}
James Forbes
@JAForbes
Apr 08 2016 11:05
doesn't replace need a 2nd arg?
Barney Carroll
@barneycarroll
Apr 08 2016 11:05
OMG yes
James Forbes
@JAForbes
Apr 08 2016 11:05
that's why I was so thrown, I thought it was curried or something
Barney Carroll
@barneycarroll
Apr 08 2016 11:05
Unless we really do want a undefinedulundefine tag
James Forbes
@JAForbes
Apr 08 2016 11:06
looks right
so you're binding the string that has been replaced as an argument( asarg) to the m function
Barney Carroll
@barneycarroll
Apr 08 2016 11:07
Yes
It's actually a pointless indirection
James Forbes
@JAForbes
Apr 08 2016 11:07
I'm not saying that, I was just trying to imagine how far you can take it? Can you keep chaining it?
Like a pipe?
Barney Carroll
@barneycarroll
Apr 08 2016 11:07
The point of as is to get an immediate reference to the preceding operand in a point-free manner
Yes
It's useful when composing deep structured objects
James Forbes
@JAForbes
Apr 08 2016 11:08
I'm definitely going to give it a try when I get a chance
Barney Carroll
@barneycarroll
Apr 08 2016 11:10
If you want a better feature, you could use @mindeavor 's pipeline operator plugin mindeavor/es-pipeline-operator#18
James Forbes
@JAForbes
Apr 08 2016 11:11
I found a sweetjs macro for it a while back, had no idea I could use it with babel
that's great
I remember reading a esdiscuss thread and just being so sad
Barney Carroll
@barneycarroll
Apr 08 2016 11:19
?
That's happened to me a few times
Mostly filed under "we can't have nice things because somebody thought of crap things 10 years ago"
James Forbes
@JAForbes
Apr 08 2016 11:24

Seems pointless. Functions can be trivially composed to form a “pipeline” without introducing new syntax: lodash.com/docs#flow

These examples only make this language extension look like a confusing and horrible thing. How is this an improvement, in any way?

This is a terrible example. It looks a lot better with what's already available

About the usefulness of this proposal, this one conflicts with the function bind syntax and assuming FBS is all rainbows and unicorns and everyone should use it, then this proposal makes no sense since the original example should be written like this (and it's already good enough)

Using this is a clear winner since that's how the native and user utility methods for the .prototypes of String, Array and such work

I really don't see much gain in adding this syntax when there is already a FBS proposal that covers most of the cases.

https://esdiscuss.org/topic/the-pipeline-operator-making-multiple-function-calls-look-great

:(

Barney Carroll
@barneycarroll
Apr 08 2016 11:25
FFS
It's the "pull the ladder up after you" approach
James Forbes
@JAForbes
Apr 08 2016 11:25
It's a sad thing.
~ "FBS is already being included so why do we need this superior alternative?"
Barney Carroll
@barneycarroll
Apr 08 2016 11:34
You know what's funny
FBS has met massive resistance at stage 1
You could fill both proposals with "the other exists so let's stop discussing this"
And we'd never get anywhere
James Forbes
@JAForbes
Apr 08 2016 11:43

Its threads like this that make me happy that JS will probably become "just a compilation target" eventually. And I like JS. But most of es6 is just noise.

The examples where mindeavour demonstrates inserting user functions into a proprietary chain is just superb. Its effortless.

https://github.com/mindeavor/es-pipeline-operator

Barney Carroll
@barneycarroll
Apr 08 2016 11:53
Yes, it's great
And it's the kind of thing where I really don't want to go 'oh I'll just include 2 or 3 wrapping functions at run time' as a solution

Lodash already exists

Is the dumbest argument ever

Underscore started as a way to make up for the fact that ES5 was taking too long
James Forbes
@JAForbes
Apr 08 2016 11:55
And the fact Lodash implemented flow and introduced fp says a lot. Such a mainstream library moving away from chaining and also recently removed the this arg from all of its iterators
If even Lodash is implementing a pipe operator, that has to point to it being moderately useful.
es6 has a lot of junk, I just don't get why people would be so harsh on such a clearly obviously useful, powerful operator
James Forbes
@JAForbes
Apr 08 2016 12:02
Alright I'm done being off topic, sorry everyone
Rasmus Porsager
@porsager
Apr 08 2016 12:04
@JAForbes @barneycarroll Please don't stop. It's wonderful lurking inhere listening to your discussions ;)
James Forbes
@JAForbes
Apr 08 2016 12:05
@porsager thank you! We need a rant channel I think
Rasmus Porsager
@porsager
Apr 08 2016 12:05
Haha.. Yeah, so long as mithril specific conversation doesn't get buried it should be fine right?
Barney Carroll
@barneycarroll
Apr 08 2016 12:06
The sad thing is there's a huge degree of naive young conservativism with JS
Everybody's scared of JS fatigue
James Forbes
@JAForbes
Apr 08 2016 12:07
@porsager ok, well everyone tell me to shut it if gets too much
I will take 0 offence
Barney Carroll
@barneycarroll
Apr 08 2016 12:07
I was talking to Kyle Simpson the other day and Jesus it was so sad
He was saying arrow functions are just trouble because they will confuse new users
And he started saying that every function should be named, language features were bad, etc.
James Forbes
@JAForbes
Apr 08 2016 12:08
WAT?
Barney Carroll
@barneycarroll
Apr 08 2016 12:08
Seriously
Which is tragic because he's a clever and influential industry figure and a teacher
Read and weep
Read the thread from the start
This one's a gem: apparently there are some operations like assignment where you don't need a function label
James Forbes
@JAForbes
Apr 08 2016 12:12

when done correctly, the name is absolutely never redundant cruft. when done poorly, it always is.

total garbage

Leo Horie
@lhorie
Apr 08 2016 12:13
Going back to the jsonml idea, iirc the issue was the need for concat instead of nesting arrays when you use e.g. .map
Re: t7, there were two problems, 1) stringly typing and 2) dominic was compiling it for perf which kinda beats the point of using plain es6
James Forbes
@JAForbes
Apr 08 2016 12:16
naming things, often obfuscates common generic patterns, reinventing everything because the names in 2 functions are completely different, but the structure is exactly the same
Barney Carroll
@barneycarroll
Apr 08 2016 12:20
^ exactly
It's the arrogance of thinking you will, off the top of your head, in your day to day work, come up with better idioms than the language itself
And then you end up with sendAction getObjectAtIndex etc
ServiceAdapterManagementBroker@brokeServiceManagementAdaption
James Forbes
@JAForbes
Apr 08 2016 12:22

@lhorie any thoughts on the structure I proposed

:point_up: April 8, 2016 11:16 AM

Barney Carroll
@barneycarroll
Apr 08 2016 12:22
@lhorie thanks, that makes sense
the issue was the need for concat instead of nesting
Leo Horie
@lhorie
Apr 08 2016 12:23
@JAForbes that's what i was responding to when i said jsonml
James Forbes
@JAForbes
Apr 08 2016 12:24
ah, I don't follow the problem
the need for concat instead of nesting?
like concatting two components together? Isn't that trivial?
Leo Horie
@lhorie
Apr 08 2016 12:27
Leon (the domvm author) mentioned he might move to hyperscript syntax if he needs to improve perf
Concat does an array copy, so not good for perf. It also adds noise that wouldnt be there with hyperscript
But yes the issue is concat instead of nesting, because nesting has semantic meaning in jsonml and its variations
Barney Carroll
@barneycarroll
Apr 08 2016 12:30
Yes
Leo Horie
@lhorie
Apr 08 2016 12:30
Namely a new tag / component
James Forbes
@JAForbes
Apr 08 2016 12:31
Is this mainly an issue when stitching together components, or just generally within a view?
Barney Carroll
@barneycarroll
Apr 08 2016 12:31
You can no longer attomically detach things either because they're dependent on contextual structure to represent something other than contextual structure
Leo Horie
@lhorie
Apr 08 2016 12:32
Any time you do a somedata.map, you'd need a concat also
James Forbes
@JAForbes
Apr 08 2016 12:33
Why not push.apply? and splice?
I guess I need to reflect on it, I'm sure you guys have considered all the ins and outs
Leo Horie
@lhorie
Apr 08 2016 12:35
Those don't return the right data structure, so you would need to break it out into procedural template assembly
But yes i did consider jsonml as a vnode struct candidate
James Forbes
@JAForbes
Apr 08 2016 12:36
that's great, really fascinating
Leo Horie
@lhorie
Apr 08 2016 12:38
Fwiw i was optimizing hyperscript (i.e. m() ) the other day
James Forbes
@JAForbes
Apr 08 2016 12:39
What was your approach?
Leo Horie
@lhorie
Apr 08 2016 12:39
Got it down to about a tenth of current speed for strict usage
James Forbes
@JAForbes
Apr 08 2016 12:39
Are you removing the variadic api?
Leo Horie
@lhorie
Apr 08 2016 12:39
I memoized the regex stuff
James Forbes
@JAForbes
Apr 08 2016 12:39
oh wow
Leo Horie
@lhorie
Apr 08 2016 12:39
Nope still there
James Forbes
@JAForbes
Apr 08 2016 12:40
how much speed would be gained by removing the regex altogether and just sticking to attrs?
I just find I'm using that input[type=text].awesome stuff less and less
dontwork
@dontwork
Apr 08 2016 12:50
does anyone have a great example of why wordpress is bad for a very large website
with lots of interactivity
James Forbes
@JAForbes
Apr 08 2016 12:55
Ludum Dare seems to manage, but most competitions seems to involve the site being unresponsive at submission time. @dontwork
I'm not sure how much of that blame lays at the feet of wordpress
I'm going to try out this ML thing. I'm not totally convinced/understanding the problem. When I eventually find out how wrong I am I'll write a blog post on it so others can decide to refuse to learn from other's mistakes :P
spacejack
@spacejack
Apr 08 2016 12:59
@dontwork I don't work on WP sites personally but every one I've come across had customizations that made it impossible to update after that. Then... security problems. Not sure how easy it is to customize without making updates impossible but it seems to happen a lot.
Gilbert
@gilbert
Apr 08 2016 12:59
I use the input[type=text].awesome syntax all the time !
James Forbes
@JAForbes
Apr 08 2016 13:00
@mindeavor It would be quite easy to have a util that composed with m to enable it (perhaps even using the pipeline operator), but I'm just curious how much the convenience costs. If its expensive, we could opt out at the library level
and opt in at the user level
var M = compose(m, specialRegexThing)
Well, it might have to be a wrapper function, or a special version of compose that carries additional params. But still!
Barney Carroll
@barneycarroll
Apr 08 2016 13:05
@JAForbes interesting
Justin
@WreckedAvent
Apr 08 2016 13:05
@barneycarroll belatedly, the props come from another component. Most components are dumb and have no opinion about the data they're handed. Then there's usually a container component which has more opinions about the domain or if the view is simple enough, the root of the view itself, which orchestrates how to apply the data from the model to the components. Exactly none of these require a controller, though, usually the container component is just passing the data down to more specialized components
Barney Carroll
@barneycarroll
Apr 08 2016 13:05
@mindeavor I've recently really taken to it
Gilbert
@gilbert
Apr 08 2016 13:06
But will something like mithril-objectify still work? If so, it's not worth taking it out
Barney Carroll
@barneycarroll
Apr 08 2016 13:07
I know this might sound completely backwards, but I prefer defining static and string based attribute-y things in a template literal as the first argument
James Forbes
@JAForbes
Apr 08 2016 13:07
Well if specialRegexThing just added it to the attrs, mithril-objectify would have to work with it
Barney Carroll
@barneycarroll
Apr 08 2016 13:07
Then dynamic and functional stuff in the hash
Gilbert
@gilbert
Apr 08 2016 13:07
@barneycarroll I have the exact same reasoning
Justin
@WreckedAvent
Apr 08 2016 13:08
@lhorie not the first time I've heard complaints about redux and boilerplate. It really is quite something else if you tried to use it on, say, a simple CRUD app
Barney Carroll
@barneycarroll
Apr 08 2016 13:08
I find it helps separate concerns
Gilbert
@gilbert
Apr 08 2016 13:08
I did some consulting on a react project this past week. I can't express how annoying it was to have to include all the things mithril gives you by default
Justin
@WreckedAvent
Apr 08 2016 13:08
The "solutions" I've seen people provide don't seem much better though, like a 200kb library for "functional reactive" programming
James Forbes
@JAForbes
Apr 08 2016 13:09

@barneycarroll I used to do that. But I find all my styles are inline so I don't need classes. And, I have utils for most basic element components, and they use attrs.

But all I am saying is, its rare to have somethign expensive, that is so trivial to add a layer that supports it.

Barney Carroll
@barneycarroll
Apr 08 2016 13:09
I'm looking to modify logic / I need to change styling become easier exercises to focus on
Justin
@WreckedAvent
Apr 08 2016 13:09
@mindeavor I agree, but react is specifically designed to be only one part of the app
James Forbes
@JAForbes
Apr 08 2016 13:10
@mindeavor I agree too, I think the "batteries included - but nothing more", is what makes mithril such a pleasure to use
Justin
@WreckedAvent
Apr 08 2016 13:10
Unfortunately having to choose to use react then willingly drop in all of the other stuff you actually need to make an app contributes to that dreadful "javascript fatigue"
Barney Carroll
@barneycarroll
Apr 08 2016 13:10
@WreckedAvent it's one of those things where you really want the perpetuators to explain what kinds of applications they develop
Gilbert
@gilbert
Apr 08 2016 13:10
@WreckedAvent yeah, that's what I'm saying. It's designed to be not enough out of the box
James Forbes
@JAForbes
Apr 08 2016 13:10
haha
Barney Carroll
@barneycarroll
Apr 08 2016 13:11
This is what I was saying yesterday
Justin
@WreckedAvent
Apr 08 2016 13:11
@barneycarroll for react or redux?
Barney Carroll
@barneycarroll
Apr 08 2016 13:11
Redux is ultimately just a way of deferring all complexity to one big bottleneck
Justin
@WreckedAvent
Apr 08 2016 13:11
in theory redux is just an event bus
Gilbert
@gilbert
Apr 08 2016 13:12
Redux was also a pain. Too much code and logic for just wanting to do a simple GET request
James Forbes
@JAForbes
Apr 08 2016 13:12
There is a continuum between removing regex and react though
Barney Carroll
@barneycarroll
Apr 08 2016 13:12
There's a circular reasoning that it's awesome because React feels more holistic as a result
@mindeavor exactly
James Forbes
@JAForbes
Apr 08 2016 13:13
And removing regex is WAY over to the left and react is way over to the right
Barney Carroll
@barneycarroll
Apr 08 2016 13:13
And you get more circular reasoning
Justin
@WreckedAvent
Apr 08 2016 13:13
what's this talk of removing regex?
Barney Carroll
@barneycarroll
Apr 08 2016 13:13
All I wanted was a simple get / push and a few local variables, this is massive overkill
Oh but it's meant for ambiguous big applications
James Forbes
@JAForbes
Apr 08 2016 13:13
@WreckedAvent I was just curious how much faster every call to m would be if it didn't check a regex we may not even be using
Gilbert
@gilbert
Apr 08 2016 13:14
Sorry @JAForbes, I don't mean this as a main argument. I'm mostly venting at this point
James Forbes
@JAForbes
Apr 08 2016 13:14
@mindeavor venting is good!
Barney Carroll
@barneycarroll
Apr 08 2016 13:15
I've finally written up my model for this big application — it's colossaly unwieldy and I need to do masses of work to accommodate the slightest change in view model logic
James Forbes
@JAForbes
Apr 08 2016 13:15
@barneycarroll that's when you know you've made it!
Barney Carroll
@barneycarroll
Apr 08 2016 13:15
Oh well your model is probably incoherent, stop overcomplicating things
Sorry this is my illustrating the fact that Redux defers your problems
Gilbert
@gilbert
Apr 08 2016 13:16
I think redux and the like are necessary for React because of its one decision to rerender on setState instead of rerender everything (like Mithril does)
Barney Carroll
@barneycarroll
Apr 08 2016 13:18
@mindeavor that's a good point
But it's important to note the circularity of all this logic
James Forbes
@JAForbes
Apr 08 2016 13:19
With my experiments with single state objects in entity component systems, it was great because it was so easy to completely change the state of a level interactively via the repl. Also serialization was trivial, and undo redo was trivial.
Barney Carroll
@barneycarroll
Apr 08 2016 13:19
Mithril's global redraw is a feature not a bug
James Forbes
@JAForbes
Apr 08 2016 13:19
But I'm never tried redux or anything like that for a web app
Barney Carroll
@barneycarroll
Apr 08 2016 13:19
You discover this as soon as you build something of any significant scale
But people would often come to Mithril and feel they really wanted all those extra API methods
@JAForbes those are all good points
Gilbert
@gilbert
Apr 08 2016 13:20
The idea of single state object is great! Redux is just super verbose
Stephan Hoyer
@StephanHoyer
Apr 08 2016 13:20

You discover this as soon as you build something of any significant scale

can confirm this!

Gilbert
@gilbert
Apr 08 2016 13:20
Redux probably came from Elm, which has the exact same app structure built in
Barney Carroll
@barneycarroll
Apr 08 2016 13:21
The problem with many of these idioms is that they come from the idea of a single holistic model
Gilbert
@gilbert
Apr 08 2016 13:21
But Elm actually benefits because it has static typing! And—needless to say—JS doesn't!
James Forbes
@JAForbes
Apr 08 2016 13:22
And in Elm you don't really know you're dealing with a single state object, its more a language level implementation detal.
Justin
@WreckedAvent
Apr 08 2016 13:22
theoretically you shouldn't either in react, you should be composing smaller "reducers" together
James Forbes
@JAForbes
Apr 08 2016 13:22
The model is isolated to the module in Elm, at least in my research, people can correct me
Gilbert
@gilbert
Apr 08 2016 13:22
yea, and you also get nice things like pattern matching
Barney Carroll
@barneycarroll
Apr 08 2016 13:23
If you have a model which is :posts/:comments, and all that stuff is on the server, and the server has a verbiage around the model that matches the view requirements 1:1 — then it's really contrived to say you want to be able to separate out the elements of state
That would just be introducing complexity!
But the beauty of the modern web is that the same backend can have any number of front-ends
James Forbes
@JAForbes
Apr 08 2016 13:23
Elm is brilliant, after using it for a day or 2 I was sincerely ready to throw away JS. But then I tried to get the webgl module to work and the package manager really frustrated me, and I decided to wait another year.
Barney Carroll
@barneycarroll
Apr 08 2016 13:23
You can mash up APIs to produce incredibly powerful UIs
James Forbes
@JAForbes
Apr 08 2016 13:23
But using Elm really sold me on the idea of JS being a compilation target (only)(eventually)
Justin
@WreckedAvent
Apr 08 2016 13:25
elm's interop was not too great last I checked
James Forbes
@JAForbes
Apr 08 2016 13:27

There was a WebGL package, it was experimental sure, but the error messages for the package manager were so vague, and Elm is all about "great error messages". Meanwhile npm is just great, so I'm waiting.

But I will leave JS one day, now I know this

Gilbert
@gilbert
Apr 08 2016 13:29
Static typing is too good to ignore. I can't wait until a web language does it properly
Justin
@WreckedAvent
Apr 08 2016 13:29
I mean with JS writ large
James Forbes
@JAForbes
Apr 08 2016 13:29
maybe not Elm, but something
Justin
@WreckedAvent
Apr 08 2016 13:29
IF you can only communicate with JS through little special adapters, you're DOA
James Forbes
@JAForbes
Apr 08 2016 13:29
@WreckedAvent I really liked the whole ports idea. But I didn't get to try it much
Barney Carroll
@barneycarroll
Apr 08 2016 13:30
A friend had a great time building a little CRUD interface in Elm
James Forbes
@JAForbes
Apr 08 2016 13:30
If you use the phrase DOA you're DOA :P
Barney Carroll
@barneycarroll
Apr 08 2016 13:30
Project was really fun
Then came the task of deploying it on the client's server
Oh well
James Forbes
@JAForbes
Apr 08 2016 13:30
Sorry @WreckedAvent DOA annoys me because I remember everyone mindlessly saying DOA DOA DOA after Steve Jobs killed Flash 5 years too early.
Justin
@WreckedAvent
Apr 08 2016 13:32
elm's compiler and error messages are great
The walled garden is not
James Forbes
@JAForbes
Apr 08 2016 13:32
But in all seriousness the special adapters thing is a good thing, it wouldn't make sense to just call a JS function or access a property, because everything is a stream/async.
Just like its a good thing everything is async in NodeJS all the way down
Justin
@WreckedAvent
Apr 08 2016 13:33
and that's kind of a problem when almost no JS is designed as a stream
James Forbes
@JAForbes
Apr 08 2016 13:33
Well, there are many great stream libraries, and observables are looking to be part of es7 right?
and most of JS is already async
so I think it was a good bet
Gilbert
@gilbert
Apr 08 2016 13:33
Static typing needs some kind of walled garden
James Forbes
@JAForbes
Apr 08 2016 13:34
that too
Leo Horie
@lhorie
Apr 08 2016 13:34
re: removing regex, I have two versions of m written, one I call strictHyperscript which has the signature m(tagString, attrsObj, childrenArray), no CSS selectors, no variadic support
Gilbert
@gilbert
Apr 08 2016 13:34
Otherwise you get unsound type systems like TypeScript and Flowtype
James Forbes
@JAForbes
Apr 08 2016 13:34
@lhorie much difference?
Justin
@WreckedAvent
Apr 08 2016 13:34
JS' typing model is itself unsound
Leo Horie
@lhorie
Apr 08 2016 13:35
on my benchmark, for 100,000 nodes, I was getting ~45ms with current m, vs ~4ms with optimized m vs ~3ms with strictHyperscript
Justin
@WreckedAvent
Apr 08 2016 13:35
I use the css selectors all of the time for a quick creation of a div with a certain class name, but I didn't even know about varadic children
Gilbert
@gilbert
Apr 08 2016 13:35
By sound I mean mathematically proven to have zero type errors when the type checker says your code is good
Leo Horie
@lhorie
Apr 08 2016 13:35
strangely, plain objects were also giving me ~4ms
Justin
@WreckedAvent
Apr 08 2016 13:36
@lhorie when the result is only 3-4 ms long there's likely a margin of error there
Leo Horie
@lhorie
Apr 08 2016 13:36
well, that's the aggregate after many many many runs
James Forbes
@JAForbes
Apr 08 2016 13:37
yeah definitely in the noise
Leo Horie
@lhorie
Apr 08 2016 13:37
results would fluctuate +/- 2ms between runs, possibly due to gc etc
Gilbert
@gilbert
Apr 08 2016 13:39
In my uninformed opinion, even 45ms for 100k nodes seems really good to me
James Forbes
@JAForbes
Apr 08 2016 13:39
@lhorie can it get much faster than 4ms for 100,000 nodes?
Leo Horie
@lhorie
Apr 08 2016 13:39
so on one hand, strictHyperscript is consistently faster than both optimized m and plain objects somehow, but on the other hand, the run time for 100,000 elements falls within margin of error range
James Forbes
@JAForbes
Apr 08 2016 13:40
Did memory usage differ much across the different tests? @lhorie
Leo Horie
@lhorie
Apr 08 2016 13:41
@JAForbes not for the vnode structure I tried. Plain object gave me that much also, and that has zero javascript-space computations
I only looked at times, not memory. But that's a good idea to put in my todo list
James Forbes
@JAForbes
Apr 08 2016 13:41
How homogenous are the nodes?
Barney Carroll
@barneycarroll
Apr 08 2016 13:42
^ That's the mistake all the tests make
Leo Horie
@lhorie
Apr 08 2016 13:42
100,000 of the same thing
Barney Carroll
@barneycarroll
Apr 08 2016 13:42
100,000 identical things with one property fluctuating randomly
Haha
Snap :)
James Forbes
@JAForbes
Apr 08 2016 13:43
It would be interesting to see the difference with a polymorphic structure, seeing as how V8 optimizes hidden classes, but most web apps will be polymorphic
Leo Horie
@lhorie
Apr 08 2016 13:44
the thing is that merely changing the number of attributes can significantly change the run time at this level, so I think it's pretty much at the limit
I'd expect that m("div.foo" + i) would perform on par w/ current m since it gets none of the memoization benefits, but that's not a realistic bench either
I also ran empty loops for control, which gave me in the range of ~0.04ms
James Forbes
@JAForbes
Apr 08 2016 13:46
So 0.05ms is the goal? :P
Leo Horie
@lhorie
Apr 08 2016 13:46
lol, no, empty loop is the overhead of the benchmark
James Forbes
@JAForbes
Apr 08 2016 13:47
Would it help if we all donated real world m output
stored it in a repo somewhere?
Leo Horie
@lhorie
Apr 08 2016 13:47
(meaning, benching 100,000 items inherently also benches the loop)
for now I have the dbmon tree to optimize for. It does well with strict usage, but it's not doing as great w/ selector usage
still need to figure out why
Barney Carroll
@barneycarroll
Apr 08 2016 13:49
dbmonster is a meaningless stress test
James Forbes
@JAForbes
Apr 08 2016 13:49
Right now I'm trying to optimize zipping up s3 folders and uploading them with Amazon Lambda. Its so funny how unpredictable it is. Sometimes it gets to 100mb, sometimes 2.7GB. The same folder each time
Barney Carroll
@barneycarroll
Apr 08 2016 13:49
It's incredibly similar to what Tom Dale & co proudly demonstrated HTMLBars with
1000s of otherwise identical elements with one attribute changing constantly
James Forbes
@JAForbes
Apr 08 2016 13:50
Chaos theory ruins everything
Barney Carroll
@barneycarroll
Apr 08 2016 13:50
They did it faster than any of the other libs at the time
Leo Horie
@lhorie
Apr 08 2016 13:50
I'm aware dbmon is meaningless in terms of reflecting real life usage
Barney Carroll
@barneycarroll
Apr 08 2016 13:51
Fast forward 1.5 years and people have found out the hard way they need to ditch Ember for those other frameworks because that's totally irrelevant to the concerns of web apps
Gilbert
@gilbert
Apr 08 2016 13:51
I do believe v8 optimized out empty loops
Barney Carroll
@barneycarroll
Apr 08 2016 13:51
This is what you want
Gilbert
@gilbert
Apr 08 2016 13:52
optimizes
Leo Horie
@lhorie
Apr 08 2016 13:52
but dbmon is useful to bench micro-optimizations by running them a bazillion times
Barney Carroll
@barneycarroll
Apr 08 2016 13:52
Riiiiight
Leo Horie
@lhorie
Apr 08 2016 13:52
I suspected v8 was removing empty loops, hence benching them, but it did have a time cost
it would be harder to measure perf changes from code tweaks using threaditjs than dbmon, is what I'm saying
Barney Carroll
@barneycarroll
Apr 08 2016 13:54
I see
Bear in mind that optimisations that work well in those scenarios are generally not applicable to real world application development
Leo Horie
@lhorie
Apr 08 2016 13:56
in the spectrum of synthetic-vs-real-life benchmarks, you have vdom bench < dbmon < threaditjs
Barney Carroll
@barneycarroll
Apr 08 2016 13:56
V8 optimisations on repetitive structures may indicate that it's generally a really good idea to stick to pure hyperscript
Leo Horie
@lhorie
Apr 08 2016 13:57
vdom bench only looks at element diff, so it's useful to isolate perf issues related to the diff algo
Barney Carroll
@barneycarroll
Apr 08 2016 13:57
But if you're dealing with a handful of deeply nested structures that change dramatically, that kind of optimisation is going to be utterly irrelevant
You wouldn't want those insights to influence how you set about modelling your view at all
Leo Horie
@lhorie
Apr 08 2016 13:57
dbmon uses classes like in real world, so it's good to measure perf for the things that vdom bench is not looking
Barney Carroll
@barneycarroll
Apr 08 2016 13:57
utterly irrelevant
Obviously you shouldn't be taking me literally
Leo Horie
@lhorie
Apr 08 2016 13:58
and then finally we have threaditjs / todomvc benches, to look at how it would behave in a real-life-ish scenario
Barney Carroll
@barneycarroll
Apr 08 2016 13:58
Of course it's essential to be able to isolate the different levels of perf concern
Leo Horie
@lhorie
Apr 08 2016 13:59
it's just that starting from threaditjs off the bat, it's really hard to figure out where the problems are coming from
Barney Carroll
@barneycarroll
Apr 08 2016 14:00
Right
Leo Horie
@lhorie
Apr 08 2016 14:01
honestly, even having those 3 bench tools is not really enough. I had to whip up a different bench for the hyperscript optimization work, and even that is vastly incomplete
the other appeal of vdom bench and dbmon is that they are fairly standardized, so it's easy to compare against other libs and set goalposts for where performance could be, based on what others can achieve
Barney Carroll
@barneycarroll
Apr 08 2016 14:03
Of course
Context
James Forbes
@JAForbes
Apr 08 2016 14:09
Also good to set hard limits on expectations. So if 4ms is performance with monomorphic lists, then approaching 4ms with threaditjs is a really good sign. But without the unrealisitic test, there is no sense of what is a "good" time.
Leo Horie
@lhorie
Apr 08 2016 14:10
but to go back to ember, I think the issue is what I said before about focusing too much on compsci and not so much on comp engineering. It's incredibly easy to get a huge regression in perf with something as simple as a flipped cond1 && cond2. If they are not looking at this stuff obsessively, then it's very likely they will step into a deopt trap while writing out their beautiful algorithm
James Forbes
@JAForbes
Apr 08 2016 14:10

To test this Lambda thing I'm going to try uploading generated garbage data, and downloading random files from s3, just to isolate what the hard limits are. Right now I don't know if 2.7 gb is good or bad for the process, because I don't know the upload/download rate.

If I can get 7gb with garbage data, then I know 2.7 gb is probably not good enough

Leo Horie
@lhorie
Apr 08 2016 14:13
I think that was the issue w/ glimmer: they had a fast proof of concept engine, but then in the process of making it robust, they probably used something deeply expensive like a call to Object.prototype.toString.call or a deprioritized null check
Leo Horie
@lhorie
Apr 08 2016 14:22
nowadays, I don't think one can make a competitive templating engine (in perf terms) without caring about monomorphism
so if you wanted computer science in mithril, there ya go @barneycarroll :)
Stephan Hoyer
@StephanHoyer
Apr 08 2016 14:35
Anyone of you attending jsunconf eu this year?
Barney Carroll
@barneycarroll
Apr 08 2016 14:36
Fraid not @StephanHoyer
By monomorphism, Leo, are you talking about things like getting rid of variadic m input etc?
Leo Horie
@lhorie
Apr 08 2016 14:42
@barneycarroll by that I mean what the underlying JIT opcode looks like. Javascript engines are optimizing monsters and can generate vastly different code for very similar source code. Hidden classes are one example
Barney Carroll
@barneycarroll
Apr 08 2016 14:44
Sorry how does that relate to monomorphism
Leo Horie
@lhorie
Apr 08 2016 14:44
another example that I've come across is having some chain of checks and then getting a deoptimization on the first check because its code path allows the input value to be many different types
Barney Carroll
@barneycarroll
Apr 08 2016 14:44
Recurring predictable structures can be optimised into generics?
James Forbes
@JAForbes
Apr 08 2016 14:44
@StephanHoyer wrong side of the planet for me :(
Leo Horie
@lhorie
Apr 08 2016 14:45
basically you want to try to make the engine infer a single type as soon as possible so it can generate code that is optimized for that data type
Barney Carroll
@barneycarroll
Apr 08 2016 14:47
And you do that by providing consistent objects
Leo Horie
@lhorie
Apr 08 2016 14:47
if it has to back out of the optimized code and try to reoptimize for another data type, then perf suffers
yes, consistent objects are one step. Another is in your branching logic.
if you put a !== null upfront then the remaining code can be JITed to assume non-nullable input, for example
Barney Carroll
@barneycarroll
Apr 08 2016 14:49
Right, heavily overloaded functions are a nightmare because anything could be happening under the hood
Leo Horie
@lhorie
Apr 08 2016 14:49
yep, exactly
James Forbes
@JAForbes
Apr 08 2016 14:50
I wonder how much overlap there would be with the branching logic, and typescripts new code path analysis
Leo Horie
@lhorie
Apr 08 2016 14:50
so generally you want to go from highly overloaded to highly monomorphic code branches as soon as possible
@JAForbes I wouldn't be surprised if they mostly overlap, the underlying compsci concepts are pretty much the same
James Forbes
@JAForbes
Apr 08 2016 14:52
It'd be fascinating to have some kind of editor plugin that hints if your code will be deoptimized based on the same logic
Leo Horie
@lhorie
Apr 08 2016 14:52
I'd even go as far as attribute angular 2 perf to typescript's typedness aligning to the requirements for making JIT engines happy
James Forbes
@JAForbes
Apr 08 2016 14:53
wow
Barney Carroll
@barneycarroll
Apr 08 2016 14:53
@JAForbes this is the kind of thing JSHint is really annoying with :)
Leo Horie
@lhorie
Apr 08 2016 14:53
(though I'm sure the team being compiler geeks probably has something to do with it too)
James Forbes
@JAForbes
Apr 08 2016 14:54
@barneycarroll I didn't even know deopt hints were a thing in JSHint!
Leo Horie
@lhorie
Apr 08 2016 14:54
that's new to me too
they are? o.O
Barney Carroll
@barneycarroll
Apr 08 2016 14:55
They're really clumsy and dumb because it's JSHint
James Forbes
@JAForbes
Apr 08 2016 14:57
I always wondered if we'd ever get to the point where TS would provide guarantees to the JS engine to save on warming up hot paths first.
I know it's proprietary, but MS has been quite good lately with OSS, maybe they could create some kind of type emitting spec
Edge is using Chrome's debugging protocol now, which blew my mind
Like Ts could go "Hey V8, this function is optimized, don't even check. It just simple ints
spacejack
@spacejack
Apr 08 2016 14:59
Isn't that 'strong mode' more or less?
James Forbes
@JAForbes
Apr 08 2016 14:59
Or "Don't box that!", "Everything in this list is the same hidden class"

@spacejack not sure, I think its different. I think strong mode was about determining types within the engine wasn't it?

I'm thinking this would just accept things to be true, it would trust the compiler whether it was Elm or TS.

But I have no clue...

Barney Carroll
@barneycarroll
Apr 08 2016 15:03
Chrome's debugging protocol is awesome
Hot function swapping!
James Forbes
@JAForbes
Apr 08 2016 15:03
Yeah its amazing
spacejack
@spacejack
Apr 08 2016 15:03
yeah I don't think strong mode relied on any kind of annotations... but would require that you stick to some guidelines like don't change types.
Leo Horie
@lhorie
Apr 08 2016 15:04
afaik strong mode was basically strict mode for ES6
spacejack
@spacejack
Apr 08 2016 15:05
using nonexistent class properties would throw errors I think
Leo Horie
@lhorie
Apr 08 2016 15:05
basically the chrome team suspected that by adding some constraints to the language, they would be able to use some optimizations and reduce bugs
spacejack
@spacejack
Apr 08 2016 15:06
the int/float thing would be tough though... how do you do divides
Barney Carroll
@barneycarroll
Apr 08 2016 15:06
Like a small step in the direction of wasm at massive cost
Leo Horie
@lhorie
Apr 08 2016 15:06
they said bug reduction materialized but perf gains did not, so they were no longer going to pursue strong mode
spacejack
@spacejack
Apr 08 2016 15:06
yeah it's abandoned last I heard
Leo Horie
@lhorie
Apr 08 2016 15:12
I wanted to try to get code to be asm.js compliant, but I couldn't figure out what the linter output was saying
anyone have any experience w/ that?
spacejack
@spacejack
Apr 08 2016 15:32
yeesh, don't you have to pre-allocate everything in typed arrays?
Leo Horie
@lhorie
Apr 08 2016 15:53
I'm not sure. I read it somewhere you could do dynamic allocations
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:05
@spacejack In asm.js structures, yes
@lhorie I'm actually taking many of the optimization problems into account for how I'm conceptualizing my own vdom framework.
Leo Horie
@lhorie
Apr 08 2016 18:07
anyone seen this? https://frzr.js.org/
taking it for a spin
Barney Carroll
@barneycarroll
Apr 08 2016 18:09
Better than DOMVM on the OOP front
Justin
@WreckedAvent
Apr 08 2016 18:09
@lhorie someone posted it to the JS subreddit but I didn't pay it much attention
Leo Horie
@lhorie
Apr 08 2016 18:11
trying to write a dbmon for it. It's not intuitive how to write the code for that, which is a turn-off.
Barney Carroll
@barneycarroll
Apr 08 2016 18:12
It looks like a toolkit for writing your own custom APIs
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:12
That at least seems like it at least tries to keep things simple. I do agree that it doesn't do a good job on helping people figure out how to write code for it, though.
Barney Carroll
@barneycarroll
Apr 08 2016 18:12
Which a lot of people really enjoy
Pat Cavit
@tivac
Apr 08 2016 18:12
writing code for that looks like a straight-up nightmare
also the perf numbers I get for it from http://pakastin.fi/perf/ are WAY higher than quoted
maybe my browser's just a baddy
Leo Horie
@lhorie
Apr 08 2016 18:13
I'm trying to port the mithril dbmon to it, but I'm stuck on how to write the update function
Pat Cavit
@tivac
Apr 08 2016 18:13
react 15 is just as fast as frzr in firefox dev edition
Leo Horie
@lhorie
Apr 08 2016 18:13
maybe I should try porting from something else
Barney Carroll
@barneycarroll
Apr 08 2016 18:13
@tivac I've met plenty of people who would just be delighted knowing they had to maintain all their state via methods they have to write themselves
Pat Cavit
@tivac
Apr 08 2016 18:13
¯\_(ツ)_/¯
Barney Carroll
@barneycarroll
Apr 08 2016 18:14
That's basically DOMVM's selling point
Leo Horie
@lhorie
Apr 08 2016 18:14
@tivac yeah, I'm getting ~600ms per run on frzr bench, not 100ms
Pat Cavit
@tivac
Apr 08 2016 18:14
same, glad it's not just me
@barneycarroll ಠ_ಠ
Leo Horie
@lhorie
Apr 08 2016 18:14
wasn't aware riot was that bad, though
Pat Cavit
@tivac
Apr 08 2016 18:14
riot is terribad
like 2x or more slower
Justin
@WreckedAvent
Apr 08 2016 18:14
the first run on that per page it's at ~400 or so then gradually lowers down to about ~160
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:15
But that first run, though...
Justin
@WreckedAvent
Apr 08 2016 18:15
riot sits there and locks my page
... so
Oh, it's just doing things
Wow, that's bad
@isiahmeadows yes, I agree, initial speed is just as important
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:16
Adds to the list of reasons I won't touch Riot unless I have to.
Pat Cavit
@tivac
Apr 08 2016 18:16
riot had a regexp-based html parser for a template engine, last I looked at it
maybe it's gotten better
Justin
@WreckedAvent
Apr 08 2016 18:16
If I was going to write html-based view today it'd probably be vue
Pat Cavit
@tivac
Apr 08 2016 18:17
but the fact that anyone ever thought that was ok made it an immediate "never ever" in my book
Justin
@WreckedAvent
Apr 08 2016 18:17
Vue components all in one file is neato
Leo Horie
@lhorie
Apr 08 2016 18:17
the author says on reddit he's a riot contributor and that it's gotten more complicated over time
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:17
In my opinion, that first load is arguably more important than subsequent renders.
Barney Carroll
@barneycarroll
Apr 08 2016 18:17
@isiahmeadows what makes you say that?
Justin
@WreckedAvent
Apr 08 2016 18:17
@isiahmeadows which is ultimately the reason for my break with knockout. Love how simple it is but initial paints are just so painful, especially on mobiles
That and the whole idea of "unobtrusive" JS enhancement has all but died out by now
Barney Carroll
@barneycarroll
Apr 08 2016 18:19
@WreckedAvent I wouldn't say that
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:19
@barneycarroll First impressions matter a lot. If your browser hangs on initial load, you're probably not going to like the site.
Justin
@WreckedAvent
Apr 08 2016 18:19
@barneycarroll unobtrusive? I can't think of any JS libraries that work to it today
that are still popular and don't suck
Barney Carroll
@barneycarroll
Apr 08 2016 18:20
@isiahmeadows I've got plenty of apps I'm happy to let load
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:20
@WreckedAvent I wouldn't agree with "all but died". Unobtrusive JavaScript and progressive enhancement requires coding discipline, and libraries don't usually help you as much with that.
Barney Carroll
@barneycarroll
Apr 08 2016 18:20
If I'm just following a link to read some text or look at a picture, it's awful
Justin
@WreckedAvent
Apr 08 2016 18:21
It's all but impossible with libraries like mithril unless you're willing to jank the entire page out from under the user and replace it with another rendered one
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:21
@barneycarroll Well, would you be happy letting Facebook taking 5-10 seconds to load?
Pat Cavit
@tivac
Apr 08 2016 18:21
@WreckedAvent there's a PR that enabled mithril to rehydrate a server-rendered DOM
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:22
@WreckedAvent Pages don't have to be that dynamic.
Pat Cavit
@tivac
Apr 08 2016 18:22
I'd still like to see that land since we're doing universal JS on a few projects and I don't love the re-render :-\
Justin
@WreckedAvent
Apr 08 2016 18:22
@isiahmeadows then you don't need progressive enhancement :wink2:
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:22
@tivac it'll have to be redone.
Pat Cavit
@tivac
Apr 08 2016 18:22
iirc someone already re-did it for 0.2.3
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:22
@tivac Where is it?
Pat Cavit
@tivac
Apr 08 2016 18:22
lhorie/mithril.js#977
aucelum
@aucelum
Apr 08 2016 18:22
Is anyone else trying Mithril along with Closure Compiler in Advanced mode?
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:23
@WreckedAvent It still helps.
Barney Carroll
@barneycarroll
Apr 08 2016 18:23
@WreckedAvent that's what no Javascript is like
Justin
@WreckedAvent
Apr 08 2016 18:24
server-side rendering wasn't what I was talking about anyway.
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:24
@tivac The reason it hasn't gotten accepted is it's still causing regressions.
Barney Carroll
@barneycarroll
Apr 08 2016 18:25
How's about this for a fun little exercise
Pat Cavit
@tivac
Apr 08 2016 18:25
yeah, I've been looking for free time to get it cleaned up but no luck yet
Barney Carroll
@barneycarroll
Apr 08 2016 18:26
Slightly less ambitious
Make Mithril render to iframes
Say it's for mobile performance reasons
Isiah Meadows
@isiahmeadows
Apr 08 2016 18:26
@barneycarroll Progressive enhancement is useful for pages that contain dynamic content, but themselves aren't inherently dynamic, and the static content doesn't depend on the dynamic content.
Justin
@WreckedAvent
Apr 08 2016 18:27
Progressive enhancement can be useful in all scenarios. If you're writing up a post to send to a form, that doesn't need to be rendered by JS, but maybe if you have JS enabled then when you type @ you get an auto completion of people in the thread.
It was a really big thing for a while in ASP.NET MVC applications but it's quietly going away in favor of SPA-everything angular apps
Bradley Stafford
@bradstaff
Apr 08 2016 18:53
Unrelated idea: A prog-rock band called Progressive Enhancement.
Barney Carroll
@barneycarroll
Apr 08 2016 18:53
I'm familiar with the concept, thanks
Leo Horie
@lhorie
Apr 08 2016 18:57
alright, so I did manage to get it implemented. The good news is that frzr is indeed fast, on par w/ inferno and mithril rewrite on dbmon
Pat Cavit
@tivac
Apr 08 2016 18:59
link?
Leo Horie
@lhorie
Apr 08 2016 18:59
the bad news is that I found 2 bugs in the process of writing it, and I needed to do some ugly DOM traversal in updates
hold on, let me put it up somewhere
Pat Cavit
@tivac
Apr 08 2016 18:59
kk
Leo Horie
@lhorie
Apr 08 2016 19:00
oh I might have spoken too soon. I just noticed a bug in my implementation... popup is missing content...
ok fixed
Metin Akat
@loxs
Apr 08 2016 19:13
hi, does Mithril somehow disable my external CSS file?
in general, it seems like I can't add CSS in any way other than the style property when defining the view
Bradley Stafford
@bradstaff
Apr 08 2016 19:15
class or className don't work?
Leo Horie
@lhorie
Apr 08 2016 19:15
no, it doesn't
so yeah, code is here http://lhorie.github.io/frzr-dbmon/frzr/app.js @tivac
it's kinda ugly overall imho
Pat Cavit
@tivac
Apr 08 2016 19:19
the need to save out references everywhere so you can mount into children is terrible
Leo Horie
@lhorie
Apr 08 2016 19:20
yeah, that's one of the ugly points
Pat Cavit
@tivac
Apr 08 2016 19:20
this.el = m("div", null,
    m("table", { class: "table table-striped latest-data" },
        this.tbody = m("tbody")
    )
);
this.rows = new frzr.List(Row)
frzr.mount(this.tbody, this.rows)
that is unacceptably ugly imo
Leo Horie
@lhorie
Apr 08 2016 19:20
the other is that it only supports variadic args, so you get that ugly double concat + apply to make it work
Pat Cavit
@tivac
Apr 08 2016 19:21
yeah that row function is way gnarly
Leo Horie
@lhorie
Apr 08 2016 19:22
so sure it works, but I can't see myself possibly writing production code like that
Justin
@WreckedAvent
Apr 08 2016 19:40
@loxs do you have a gist or something? I only use mithril with external css
this.rows = new frzr.List(Row) is this some kind of observable?
Justin
@WreckedAvent
Apr 08 2016 19:45
I wonder why it wouldn't just let you call the freezer el function with one of your "component classes"
m("tbody", null, m(Row)) or such, instead of that ugly mount shenangians
Leo Horie
@lhorie
Apr 08 2016 19:52
yeah, that seems like a low hanging fruit @WreckedAvent
Justin
@WreckedAvent
Apr 08 2016 19:53
seems like kind of an obvious thing if you're going to organize everything through "component classes"
Leo Horie
@lhorie
Apr 08 2016 19:54
I guess the issue would be that if you inline into m(Row), you'd not be able to call update on it later on
Justin
@WreckedAvent
Apr 08 2016 19:56
sounds like they didn't think that one through too much
Leo Horie
@lhorie
Apr 08 2016 19:56
I left him some feedback on the reddit thread. He says it's late where he lives so I guess we'll have to wait til tomorrow to see what he says
Justin
@WreckedAvent
Apr 08 2016 19:57
though I guess you could do something like ...
m("tbody", null, m((this.row = new Row(), this.row.el)))
but that's dreadful
Evgeniy Labutin
@LabEG
Apr 08 2016 20:04

@lhorie how about divide mithril components to difference modules and difercence files?

import {m, Defered, Request, Route, and others} from 'mithril';

and for old style

var m = m || {};
m.request...
var m = m || {};
m.defered...
Pat Cavit
@tivac
Apr 08 2016 20:07
@LabEG I started on that but was waved off as the rewrite is already modular
lhorie/mithril.js#913
Justin
@WreckedAvent
Apr 08 2016 20:08
might as well give it a meaningful name if you're doing ES6:
import {Render as m, Route} from 'mithril'
oof. Ember does not do well on the dbmon
Pat Cavit
@tivac
Apr 08 2016 20:28
I sure hope not
Leo Horie
@lhorie
Apr 08 2016 20:35
when did glimmer land anyways?
Pat Cavit
@tivac
Apr 08 2016 20:35
a while ago, wasn't it? I thought this most recent emberconf was all about glimmer2
merged into master may 5, 2015
so almost a year old
Bryce
@drew111b
Apr 08 2016 20:48

I have spent all morning trying to get m request objects working for my get request to a rest endpoint. It is not working for me, as I need an 'Authentication' header.

This works:

curl -u name:password -i -X GET http://127.0.0.1:5000/$URL

and it sends

Authorization: Basic bmFtZTpwYXNzd29yZA==
Content-Length: 
User-Agent: curl/7.35.0
Host: 127.0.0.1:5000
Accept: */*
Content-Type:

I want my mithril code to do the same thing. Using xhr.setRequestHeaderadds to Access-Control-Request-Headers, but how do I add to the regular headers?

Leo Horie
@lhorie
Apr 08 2016 20:49
@drew111b via config: function(xhr) {xhr.setRequestHeader(...)}
@tivac I just tried updating to canary, but it blows up :(
Leo Horie
@lhorie
Apr 08 2016 20:50
maybe @barneycarroll could shed some light as to how to make ember dbmon work with latest version
Pat Cavit
@tivac
Apr 08 2016 20:51
@lhorie no see ember's ALWAYS SAFE TO UPDATE
XD
Metin Akat
@loxs
Apr 08 2016 20:56
@WreckedAvent I think I'll write to the mailing list... It's completely blowing my mind right now
wow, I think I may have found it
is it possible that because (as per tutorial) my main view returns the whole <html><body> etc. tags
that it completely obliterates everything previously defined in the html and head tags?
so no css is left
Arthur Clemens
@ArthurClemens
Apr 08 2016 21:00
if you overwrite the head, yes
Metin Akat
@loxs
Apr 08 2016 21:00
wow
Arthur Clemens
@ArthurClemens
Apr 08 2016 21:00
isn’t it obvious?
Bryce
@drew111b
Apr 08 2016 21:01

@lhorie That is what I thought would be. My code is this:

    response = m.request(
        method: "GET"
        url: "http://#{location.hostname}:5000/#{URL}"
        config: (xhr) ->
            xhr.setRequestHeader("Authorization", "Basic bmFtZTpwYXNzd29yZA==")
            xhr.setRequestHeader("Access-Control-Allow-Origin", "*")
    )

but it is sending out

Origin: http://localhost
Content-Length: 
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
Connection: keep-alive
Access-Control-Request-Headers: access-control-allow-origin,authorization
Host: localhost:5000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Access-Control-Request-Method: GET
Accept-Language: en-US,en;q=0.5
Content-Type: 
Accept-Encoding: gzip, deflate

Here is it changing Access-Control-Request-Headersinstead of just being a straight header.

I must be missing something glaringly obvious, but for the life of me I can't find it.
Any help is immensely appreciated.

Metin Akat
@loxs
Apr 08 2016 21:01
now it is, but I spent about 3-4 hours debugging
before I realized it
Arthur Clemens
@ArthurClemens
Apr 08 2016 21:02
@drew111b I guess it depends on your server setup. I am using
config: (xhr) => {
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    const t = token();
    if (t) {
        xhr.setRequestHeader('Authorization', 'Bearer ' + t);
    }
},
Metin Akat
@loxs
Apr 08 2016 21:05
what is the right way to insert my application in an already existing <body> tag but while replacing its (placeholder) content?
Pat Cavit
@tivac
Apr 08 2016 21:06
it looks like it's adding CORS headers because you're going across-domain
dunno if you can do that w/ the Authorization header
Arthur Clemens
@ArthurClemens
Apr 08 2016 21:07
your server must be set up to accept CORS
@loxs mount it to an element, for instance document.querySelector(‘#app’)
Metin Akat
@loxs
Apr 08 2016 21:07
thanks
Arthur Clemens
@ArthurClemens
Apr 08 2016 21:08
use route instead of mount for multipage
Bryce
@drew111b
Apr 08 2016 21:12
@ArthurClemens This seems to be the issue. I thought I handled it, but this blueprint did not have it (server side). Thank you.