These are chat archives for mithriljs/mithril.js

4th
Apr 2016
James Forbes
@JAForbes
Apr 04 2016 01:10
@barneycarroll re: storybook, have you seen this: https://www.youtube.com/watch?v=G7Z_g2fnEDg ?
Grant Miner
@llambda
Apr 04 2016 02:37
This message was deleted
Isiah Meadows
@isiahmeadows
Apr 04 2016 02:47
@barneycarroll @llambda @JAForbes What are your all's thoughts on Idris?
Barney Carroll
@barneycarroll
Apr 04 2016 05:36
  • Cumulative universes
I'm sold!
Isiah Meadows
@isiahmeadows
Apr 04 2016 05:36

It's a pure functional research language that targets both JS and C. It has the capacity to formally verify programs (i.e. it's can work as a proof assistant), like Agda and Coq, but unlike most of those, it's intended to be a pragmatic, general-purpose language first, and proof assistant second. Its syntax is inspired by Haskell, it allows very powerful type inference, and it has a stronger, more powerful, and often safer type system than even Haskell.

The dependent types and formal proof verification ability can push whole classes of bugs to compile-time errors. You can formally verify that a number satisfies some constraint, with almost 0 runtime overhead. Also, types can be first-class values because of the notion of dependent types. Matter of fact, here's a couple of the builtin types (with the actual definitions mod a compiler directive):

-- Idris snippet
-- Z = 0, S = natural successor
data Nat = Z | S Nat

data Vect : Nat -> Type -> Type where
  Nil : Vect Z a
  -- Literally an infix type constructor
  (::) : (x : a) -> (xs : Vect k a) -> Vect (S k) a

It is also possible to formally verify that the program, or specific parts of it, are guaranteed to terminate (i.e. comprised of only total functions). This can also eliminate another whole class of bugs, since we all have probably dealt with a rogue infinite while loop at some point.

One interesting thing of note is that, for pragmatic reasons, Idris is eager by default, and you have to be explicitly lazy. This is because one of the long term goals is to make it useful for low-level system code like formally verified device drivers, where you also want predictable performance. Its strong purity (more than even Haskell) and aggressive term erasure does help this tremendously.

It also has built-in syntactic macro support through extensible syntax.


(For those who don't know: Dependent types are types whose definition can depend on their value, like the difference between a "string" and a "fixed-length string of length 5". Proof assistants like Agda and Coq are commonly used in math research to automatically verify proofs, making research easier by spending less time error-checking. GADTs, or generalized ADTs, are a generalization of your usual parametric ADTs, as shown below.)

-- Parameteric ADT
data Maybe a = Just a | Nothing

map :: (a -> a) -> Maybe a -> Maybe a
map f (Just x) = Just $ f x
map f Nothing = Nothing

-- Generalized ADT - can return even specializations of `Expr a`
data Expr a where
  I :: Int -> Expr Int
  B :: Bool -> Expr Bool
  Add :: Expr Int -> Expr Int -> Expr Int
  Mul :: Expr Int -> Expr Int -> Expr Int
  Eq :: Expr Int -> Expr Int -> Expr Bool

eval :: Expr a -> a
eval (I n) = n
eval (B b) = b
eval (Add e1 e2) = eval e1 + eval e2
eval (Mul e1 e2) = eval e1 * eval e2
eval (Eq  e1 e2) = eval e1 == eval e2
Barney Carroll
@barneycarroll
Apr 04 2016 05:38
Excellent
Finally, a type system that gives back more than you type in! ;)
Isiah Meadows
@isiahmeadows
Apr 04 2016 05:39
:+1:
Barney Carroll
@barneycarroll
Apr 04 2016 05:39
WRT eager evaluation, I'm not sure I've ever worked with anything that's lazy by default on a language level
mutations in javascript =D
Isiah Meadows
@isiahmeadows
Apr 04 2016 05:40
@barneycarroll I have a little, since I've messed with Haskell, and Scala can optionally have call-by-name semantics, which results in arguments being evaluated lazily.
Barney Carroll
@barneycarroll
Apr 04 2016 05:40
Ha
Cool
Isiah Meadows
@isiahmeadows
Apr 04 2016 05:41
This message was deleted
Messed a little with Haskell, that is.
Barney Carroll
@barneycarroll
Apr 04 2016 05:44
This is a type system I'd be happy to engage with
Also great to have whitespace sensitivity
Little things like that are so great for focus
Isiah Meadows
@isiahmeadows
Apr 04 2016 05:52

Idris seem exciting to me. It's 100% pure, it has extensible syntax in a fully typesafe way, among other things. One example is if ... then ... else ..., which is purely language-level:

ifThenElse : (b : Bool) -> (t : Lazy a) -> (e : Lazy a) -> a
ifThenElse True t e = t
ifThenElse False t e = e
syntax if [test] then [t] else [e] = ifThenElse test t e

Another is that dependent types would really help with a lot of things. The fact dependent types and syntax/DSL extensibility is baked into the very essence of the language is very inviting to me.

Isiah Meadows
@isiahmeadows
Apr 04 2016 06:09
I will throw out, though, that dependent types and proofs can get complicated quickly, and from laziness/time constraints/etc., many programmers don't use that inherent power to formally verify their code, and occasionally resort to believe_me to satisfy the proof checker. They also have a tendency to produce boilerplate, and there is no Template Haskell equivalent for Idris.
Barney Carroll
@barneycarroll
Apr 04 2016 06:24
Right
Isiah Meadows
@isiahmeadows
Apr 04 2016 06:24
Idris does look promising, though.
Barney Carroll
@barneycarroll
Apr 04 2016 06:25
That's endemic though, esp in TDD and class-centric code
It depends on how dogmatic you are about convention over praxis
I can see this being a nightmare for the mindset that thinks every feature is there to be used ;)
"Today I'm going to write a dropdown in Idris. 6 complex types and 3 new language features should do the job."
Isiah Meadows
@isiahmeadows
Apr 04 2016 06:33
Actually, I'm partially incorrect in Idris not having anything like Template Haskell - it has ways to generate templated code to a limited extent. But yeah...it's not really for those who feel every feature must be used. You have to first accept that most language features are optional. Matter of fact, my two latest major changes to Techtonic were converting it back to plain JS and nixing almost all inheritance/OO. The API is now templated off of a default-exported object, and only errors inherit.
It's now a bit Lua-like and C-like in that I avoid classes entirely.
@barneycarroll
Isiah Meadows
@isiahmeadows
Apr 04 2016 06:49
The idioms in that project are a little atypical, but I'm growing happy with it.
Barney Carroll
@barneycarroll
Apr 04 2016 06:49
JS and nixing almost all inheritance/OO
Gratz!
Isiah Meadows
@isiahmeadows
Apr 04 2016 06:50
Ish...I did use parasitic inheritance for the tests, but that was literally a necessity. I pretty much stopped using prototypes, though.
I mean the test ADTs.
This is what I did. It's technically parasitic, but it's the kind usually done with mixins.
This message was deleted
Isiah Meadows
@isiahmeadows
Apr 04 2016 07:03
Other than that, I didn't really use any inheritance. In terms of traditional OO, I avoided it. Despite it racking up about 3.1k lines now minus tests (now that I've DRYed the shit out of it), 2.6k if you want to count what's on npm, I'm pretty happy how this is scaling for the job.
If you want to include everything, tests, docs, etc., it's almost 10k lines.
Stephan Hoyer
@StephanHoyer
Apr 04 2016 09:25
Hi, anyone already integrated Facebook/twitter share buttons with mithril?
Stephan Hoyer
@StephanHoyer
Apr 04 2016 09:30
BTW on the picture from @LabEG: We in germany call this "Eierlegende Wollmilchsau" which is roughly translated to "egg-laying wool-milk-sow" ;)
that may help,
Arthur Clemens
@ArthurClemens
Apr 04 2016 09:41
@StephanHoyer Share buttons, I am curious about that too. On the (not mithril) website we have a lot of FB HTML tags and I wondered if there’s a workaround for that.
FB doesn’t read javascript
Branie
@BransonGitomeh
Apr 04 2016 09:42
'class myComponent extends m. component' when can i get to do that
Stephan Hoyer
@StephanHoyer
Apr 04 2016 09:54
@BransonGitomeh thanks, we will try
think we will make a OS-module, if we are done with it
Branie
@BransonGitomeh
Apr 04 2016 11:15
class myComponent extends m. componentwhen can i get to do that
Branie
@BransonGitomeh
Apr 04 2016 12:05
looks so cool on react docs... :-)
Evgeniy Labutin
@LabEG
Apr 04 2016 12:20
you are can not extended function =D
Branie
@BransonGitomeh
Apr 04 2016 12:27
hmm im guesing it would require an entire rewrite where m.component is a class right....then with that we can shake out the classes in mithril that we dont use in our apps...
but is it even worth the effort, naah
Hitesh Joshi
@hiteshjoshi
Apr 04 2016 13:18
Hello,
I am developing a simple SPA, but need nested view/route functionality. Meaning, change only specific part of the DOM when a URL is changed. I am thinking to use URI.js https://github.com/medialize/URI.js But just wondering if anyone can recommend any good technique for this?
dontwork
@dontwork
Apr 04 2016 13:19
hi @hiteshjoshi
you may find this code useful
see how i use it in the second file
Hitesh Joshi
@hiteshjoshi
Apr 04 2016 13:23
@dontwork thanks man!
dontwork
@dontwork
Apr 04 2016 13:23
:shipit:
Hitesh Joshi
@hiteshjoshi
Apr 04 2016 13:23
Looks promising. Guess I will create wrap function for every module that needs something similar, eg dashboard, profile etc.
Thats the magic of vanilla js :) love this m
dontwork
@dontwork
Apr 04 2016 13:24
there may be a better way for your use case
i may just put each part of the ui into components and on different parent components have different children
so the main component might have people and pages, but the other maincomponent might have people and calendar
and then in the top level component do a redraw = diff or whatever it is
as using routing cause full redraw
Hitesh Joshi
@hiteshjoshi
Apr 04 2016 13:27
Yes true.
thats what I was thinking.
"i may just put each part of the ui into components and on different parent components have different children" -> this
dontwork
@dontwork
Apr 04 2016 13:28
good stuff!
Hitesh Joshi
@hiteshjoshi
Apr 04 2016 13:28
thanks man!
dontwork
@dontwork
Apr 04 2016 13:28
no probs
Barney Carroll
@barneycarroll
Apr 04 2016 13:31
@BransonGitomeh this is the same line I pull whenever anybody asks for classes as a 'feature': what would you expect that subclass to even do? Is there any functionality or convenience you're hoping for, or do you just really like those extra characters? ;)
@hiteshjoshi follow @dontwork's advice — looks like you'd save yourself a lot of potential complexity by doing that
Stephan Hoyer
@StephanHoyer
Apr 04 2016 13:33
  1. create a class
  2. extend it
  3. ???
  4. PROFIT
dontwork
@dontwork
Apr 04 2016 13:33
@barneycarroll and usually itd end in more complexity
Barney Carroll
@barneycarroll
Apr 04 2016 13:33
4b. Profit somehow fails to materialise
dontwork
@dontwork
Apr 04 2016 13:33
ha
Barney Carroll
@barneycarroll
Apr 04 2016 13:33
  1. Introduce polymorphism
Return to 4b
dontwork
@dontwork
Apr 04 2016 13:33
ive always wondered if there is a better way to only having certain parts of the view change but either way you need to have routes and those routes need to load both from other pages and from a full reload
Barney Carroll
@barneycarroll
Apr 04 2016 13:35
The thing is Mithril bears the responsibility for not changing views if… well if the views don't change
If you second guess that and introduce your own logic to work around Mithril, you loose the ability to rationalise the application lifecycle logic according to Mithril expectations
dontwork
@dontwork
Apr 04 2016 13:37
exactly
i guess sometimes it just seems weird to still think of 'pages' in an spa
Barney Carroll
@barneycarroll
Apr 04 2016 13:38
The normal avenues of debugging, extending, modifying application logic become hideously complicated because you have to rationalise how your custom logic is invalidating Mithril's idiomatic approach… and then as soon as requirements change or a new feature crops up, or you find a bug… you're on your own!
@dontwork yeah that's true
DOMVM is an interesting approach on this level
It's pretty much implicit with virtual DOM libraries that you have a single active DOM tree where one component at the top determines the whole application, with most logic defered to sub components
DOMVM prefers the old wisdom of stateful object components you treat as separate entities without that single tree flow of logic
Barney Carroll
@barneycarroll
Apr 04 2016 13:43
So you're using virtual DOM to express views, but your application architecture is much more traditional — the relationship between components is not at all procedural and you need to explicitly invoke methods on them according to their own individual APIs
As if we were dealing with Backbone or a good old fashioned mess of jQuery widgets
In my opinion, this misses the point of what makes componentized virtual DOM so useful as a programming idiom
Namely that there's a simple procedural flow to application logic that isn't dependent on custom APIs you have to write and maintain and tie together yourself as your application grows
And that you can rationalise the entire application state at any given point in time
It's basically the dichotomy between functional programming and traditional object oriented programming
Stephan Hoyer
@StephanHoyer
Apr 04 2016 13:47
:+1:
Barney Carroll
@barneycarroll
Apr 04 2016 13:50
The case for DOMVM and this idea that you would want to avoid the simple logic of component A invoking components B and C using a universal interface… is basically that you trust your own internal wisdom as to performance concerns and application architecture aesthetics more than you trust the library and the open source community at large
If you're concerned about performance, you should be able to get a measure of the bad performance — either conceptually or by means of proof — and ask yourself or the community how you can resolve that to a level of satisfaction you're happy with
If you can't do that, chances are the premise can't even be validated, at which point you run the risk of setting up deviations to the normal flow of logic in the application that you won't be able to justify in hindsight. That's really really bad from a maintenance perspective.
Grant Miner
@llambda
Apr 04 2016 15:24
@isiahmeadows looks interesting!
Isiah Meadows
@isiahmeadows
Apr 04 2016 15:42

@barneycarroll This is one of the reasons why I'm making mutable components first-class citizens with the toy framework I'm currently sketching out. It's going to be similar to Mithril's rewrite, but you can create a mutable component with a parent binding that encapsulates its state, and manages everything how it feels is best fit. Matter of fact, the DOM components are themselves mutable components.

(I'm using the call constructor proposal for exposition only.)

const adders = {
    onclick(binding, f) {
        if (typeof f === "function") binding.onclick = f
    },
    // other DOM properties...
}

const checkers = {
    onclick: (binding, f) => f === binding.onclick,
    // other DOM properties...
}

export default class DivNode {
    call constructor(selector) {
        return m.part(DivNode, parseSelector(selector))
    }

    constructor(props, children) {
        this.props = props
        this.binding = binding

        for (const prop of Object.keys(adders)) {
            adders[prop](this.binding, props[prop])
        }
        return false
    }

    shouldUpdate(props) {
        for (const prop of Object.keys(checkers)) {
            if (props[prop] == null) return true
            if (!checkers[prop](this.binding, props[prop])) return true
        }
        return false
    }

    patch(updates) {
        for (const update of updates) {
            switch (update.type) {
            case "add":
                this.binding.appendChild(update.node.binding)
                break;

            // etc...
            }
        }
    }
}
@llambda It is. I've briefly considered toying around with the language for a while.
Their website is http://www.idris-lang.org/
Isiah Meadows
@isiahmeadows
Apr 04 2016 16:31
A couple interesting things are that type constructors can be inline operators and matchers, unlike most languages, even most functional ones. For example:
-- Nat = {x | x >= 0}, Z = 0, S = natural successor
infixr 5 ::

data Vect : Nat -> Type -> Type where
    Nil  : Vect Z a
    (::) : a -> Vect k a -> Vect (S k) a

append : Vect n a -> Vect m a -> Vect (n + m) a
append Nil       ys = ys
append (x :: xs) ys = x :: app xs ys

-- Example
append vec1 vec2
Leo Horie
@lhorie
Apr 04 2016 17:30
@isiahmeadows I'm not really following. How does that help w/ reducing cognitive load? It sounds like it would increase it
Isiah Meadows
@isiahmeadows
Apr 04 2016 17:31
In reference to what? I'm sorry, but my brain is elsewhere ATM.
Leo Horie
@lhorie
Apr 04 2016 17:31
your mutable component snippet
Isiah Meadows
@isiahmeadows
Apr 04 2016 17:33
That's actually a conceptual version of the <div> component. Also, I made a few mistakes in that.
I'm still in the conceptual stages.
What I'm working to do is make the components render themselves instead of the library rendering them. The library is merely diffing trees and creating patch sets for them.
Isiah Meadows
@isiahmeadows
Apr 04 2016 17:40
@lhorie I haven't actually written any of the core algorithm, though. I'm still solidifying the API.
Also, it's currently low priority for me.
Leo Horie
@lhorie
Apr 04 2016 17:41
I don't mean that there are coding mistakes in the snippet. I mean that if the entire system is built on the premise that the component writer can configure everything, I think all the configuration would make it difficult to adopt, compared to the current crop of libs
the appeal of current libraries is that they are doing a lot of that plumbing for you, and they reached fast-enough-for-99%-use-cases speed
Pat Cavit
@tivac
Apr 04 2016 17:49
"Don't make me think"
Leo Horie
@lhorie
Apr 04 2016 17:50
@tivac exactly
I think @barneycarroll has some good points re: the earlier convos about domvm. Granular redraws are a powerful feature, but I think they should come w/ a here-be-dragons sign, not made front and center in the API.
Jake Howerton
@jakehow
Apr 04 2016 18:01
@lhorie is there a branch or issue for the 'rewrite' thats been discussed? or is it still in conceptual stage?
Pat Cavit
@tivac
Apr 04 2016 18:02
@jakehow nothing yet
few scattered bits of info here & there
Leo Horie
@lhorie
Apr 04 2016 18:02
@jakehow no branch yet. Still working on some core things
why? Do you have a wishlist? :)
Pat Cavit
@tivac
Apr 04 2016 18:11
my wishlist is to see what it looks like so we can figure out what to do w/ our current mithril code ;)
Branie
@BransonGitomeh
Apr 04 2016 18:12
@tivac :+1:
Pat Cavit
@tivac
Apr 04 2016 18:12
worried about the level of changes required to support new/faster/better version of mithril, and what that means for current/near-future mithril projects
Jake Howerton
@jakehow
Apr 04 2016 18:14
@lhorie yeah my q is in that direction, what are the big conceptual changes that necessitate a rewrite. How does it impact how apps get written
i think there are issues for some of the stuff I'd be interested in seeing though (ES6/TS class compat, standard promise impl, fetch?)
some implementation of tasks for side effects like http://ember-concurrency.com/#/docs/task-function-syntax would be cool
Barney Carroll
@barneycarroll
Apr 04 2016 18:27
@isiahmeadows I'm not at all sure which typical concerns that's addressing
Leo Horie
@lhorie
Apr 04 2016 18:27
@tivac it's a bit hard to say at this point, since components aren't done (actually not even started).
Pat Cavit
@tivac
Apr 04 2016 18:28
That's fair, I'll just continue poking at regular intervals.
Barney Carroll
@barneycarroll
Apr 04 2016 18:29
Yes, it's possible to through up any kind of structure with any amount of mutability and types and obscure APIs — especially when you're doing it without a use case other than "these language features are interesting in and of themselves"
Leo Horie
@lhorie
Apr 04 2016 18:29
m.request is mostly backwards compatible as of now, with the caveat that the promise implementation is injectable (and tests are using native implementation)
build/parseQueryString are now following what Node/PHP expect (mostly as it relates to arrays)
Pat Cavit
@tivac
Apr 04 2016 18:31
We're finalizing plans for GW2 UI tech for the next... while/forever
and it's looking likely that most of it will be web tech
so then we gotta figure out if we want to continue using mithril or explore something else
Jake Howerton
@jakehow
Apr 04 2016 18:31
i know its a pain and not sure if the community is big enough but building projects on mithril would be an easier decision if you/ the community figured out how to increase the bus number also :)
Pat Cavit
@tivac
Apr 04 2016 18:31
98% chance we continue w/ mithril
@jakehow good news is that mithril is small enough that it's quickly learnable
I broke the entire thing apart into ES6 modules on a lark in less than a day a while back
Leo Horie
@lhorie
Apr 04 2016 18:32
for m.route, I have a lower level API that is independent of the rendering/component system. Thinking of adding an adapter for 0.2.x API
render changes are what I mentioned a few weeks ago (nodes are cito-like, fragment support, create/update/remove events)
Pat Cavit
@tivac
Apr 04 2016 18:34
is redraw still global?
Leo Horie
@lhorie
Apr 04 2016 18:35
@tivac planning to make it configurable
Barney Carroll
@barneycarroll
Apr 04 2016 18:36
@lhorie how come this rewrite came to be so large in scope?
Isiah Meadows
@isiahmeadows
Apr 04 2016 18:39
@lhorie I'm actually planning on having two perspectives: your typical immutable components that Mithril, React, and many others have, and then your mutable components. What I'm doing is making the API not care what the underlying representation is, leaving it to the component author what that representation is. I will supply components for the DOM, so people don't have to write their own. But if you want to model canvas stuff, or port this to Android APIs, it should only require writing a new renderer for it. You should also be able to use these inside other components, integrating right in the middle, instead of just at the end points.
Barney Carroll
@barneycarroll
Apr 04 2016 18:41
@isiahmeadows what parts of this are you having difficulty with the current crop?
Because writing a virtual DOM framework without the DOM bit is pretty trivial
The difficulty is in establishing an API that's succinct enough to make intuitive sense for a diverse enough audience while striking a good balance of powerful state controls and simple piping logic
Barney Carroll
@barneycarroll
Apr 04 2016 18:47
I don't get how introducing a variety of types and mutability addresses anything pertinent
Isiah Meadows
@isiahmeadows
Apr 04 2016 18:48
@barneycarroll My experience with Mithril is that it's difficult to test it's actually working, and it occasionally gets in your way stem you want to integrate with mutable APIs like with Bootstrap. My experience with React is that it's needlessly complicated in many cases, and even though it can integrate with things a little more deeply, and it grants more fine grained control.
I would like to see mutability to still be able to work fundamentally without changing the immutability of the idiomatic API.
Barney Carroll
@barneycarroll
Apr 04 2016 18:54
So the solution to ensuring compatibility with 3rd party mutating APIs is not causing changes whose end result is a destruction of state in the DOM
If you're relying on a Select2 insurance to be fully accountable within a Mithril application, initialise it in a config callback and then don't use Mithril to screw around with the parts of the view it relies upon
Then you use the draw loop to pass in data and use that same config to translate between data in and Select2 methods internally
This isn't so much a dogmatic application development philosophy as common sense
Limit the points of failure between 2 independent APIs by limiting their contact with each other
The object oriented philosophy says everything must have contact with everything at some point, so let's just write more and more exponentially more complicated objects
Barney Carroll
@barneycarroll
Apr 04 2016 19:00
But it doesn't solve the fundamental problem you're talking about, which is the notion that you choose to depends upon 2 APIs that are unaware of each other by default
The way to deal will that scenario pragmatically is by limiting their potential points of interaction, not creating new opportunities for them
Can you give me a user / author story and accompanying pseudo code to show how mutability is useful here?
I'll get the ball rolling with a couple of scenarios whereby somebody could end up screwing up their Mithril + Select integration
Barney Carroll
@barneycarroll
Apr 04 2016 19:07
In the first case, they use a Mithril view to create some DOM, initialise Select using that DOM as reference, but then continue using the Mithril API to persist changes to the underlying DOM when Select thought it was in control. Select and Mithril both have internal models of state that end up at odds, and neither API behaves properly because changes are being made in one that aren't persisted in the other. Solution: make the Mithril view render once and defer all subsequent mutations to the Select API
In the second case, it turns out we actually do want Mithril to be able to make some decisions about how the DOM is populated, because as it happens the Select API is actually incapable of mutating in the way we desire
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:09
@barneycarroll To be perfectly honest, my vdom idea is more like the library analogue to a moonshot. Mostly just an idea I want to explore.
Barney Carroll
@barneycarroll
Apr 04 2016 19:10
So what we do is acknowledge that shortcoming and isolate the problem case such that we teardown the existing Select instance and create new DOM from scratch along with a new Select instance.
I'm still not getting what the moon is in this analogy
Leo Horie
@lhorie
Apr 04 2016 19:11
@barneycarroll re: scope size, there's lots of reasons
Barney Carroll
@barneycarroll
Apr 04 2016 19:11
Like, what problems would you like it to solve?
Leo Horie
@lhorie
Apr 04 2016 19:13
for one thing, I feel like a lot of cruft has been accumulating in the current codebase (both in terms of design and implementation)
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:13
@barneycarroll I mean "moonshot" in a similar sense to Google's infamous ones, where Google Glass and Project Loon came from. So far, the latter was only realized by Facebook, and the former has many third party vendors with not-very-interoperable devices (which Google can help fix).
@lhorie I agree with current Mithril.
Barney Carroll
@barneycarroll
Apr 04 2016 19:14
If the moon is made of cheese, that sounds worth checking out. But if it's just loads of APIs, I'd shut down the space race. "Lack of APIs" is somewhere in the high 9000s in my list of things that need solving in web tech
Leo Horie
@lhorie
Apr 04 2016 19:14
e.g. m.route implementation is somewhat difficult to follow with all the crazy recursion
and design-wise, to be frank, things like two separate onunload things is dumb
Barney Carroll
@barneycarroll
Apr 04 2016 19:15
@lhorie that last one is going to be difficult
I think m route is pretty decent, and I'm not sure there's a huge amount that can be done in that space without getting opinionated in ways that would be difficult to work against
Leo Horie
@lhorie
Apr 04 2016 19:17
API-wise, m.route is ok imho. The internals are the messy part
m.request is a bit overcomplicated internally as well
Barney Carroll
@barneycarroll
Apr 04 2016 19:18
@isiahmeadows right, it's about what interesting questions might be asked if these things were available as opposed to what problems we have now that might be addressed
@lhorie don't you think the best thing to do with request is just to ditch it as an orthogonal concern?
I know a couple of people are really happy with the fact that Mithril got a basic XHR API that addressed some basic internal concerns in a single package of 8kb
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:20
@lhorie I have mentioned somewhere (I think a GitHub issue?) that you could implement m.route with its exact API completely independent of core, using m.mount.
@barneycarroll Yeah, but it's a moot point with fetch.
Leo Horie
@lhorie
Apr 04 2016 19:21
well, personally, I'm in the camp that thinks xhr is core to web development
Barney Carroll
@barneycarroll
Apr 04 2016 19:22
But keeping those people happy while producing something which is powerful enough for the slightly ambitious cases and is as good or better than dedicated APIs while retaining the 'one neat little package' ideal… sounds impossible
Leo Horie
@lhorie
Apr 04 2016 19:22
fetch is nice as an API, except it lacks abort, progress, jsonp
Barney Carroll
@barneycarroll
Apr 04 2016 19:23
@isiahmeadows yes I remember that, it's interesting how a small amount of relatively trivial abstraction makes all the difference
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:24
@barneycarroll re: my vdom idea: Pretty much. I'm thinking "what if you could integrate at any point, and expose an immutable API with a mutable implementation?"
Barney Carroll
@barneycarroll
Apr 04 2016 19:24
Well WRT fetch / m.request
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:24
I caught that.
And I agree.
Such a wrapper for XHR specifically is almost trivial to write, though.
Leo Horie
@lhorie
Apr 04 2016 19:25
the new lower level m.mount in rewrite now calls a callback, so you can call render or use React or whatever you want
Barney Carroll
@barneycarroll
Apr 04 2016 19:25
You're totally right Leo in that fetch is not a plain and simple upgrade of XHR
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:25
Leo, what does that callback do?
Barney Carroll
@barneycarroll
Apr 04 2016 19:26
The problem you get with m request is similar to that of startComputation — the cognitive burden of ditching this thing that is just giving you headaches doing something it really shouldn't be doing… is really really tough for people
Leo Horie
@lhorie
Apr 04 2016 19:26
gets called on route match with path (resolved and unresolved) and params as arguments, (or another callback gets called on no-match)
Barney Carroll
@barneycarroll
Apr 04 2016 19:27
Ah so you're moving to functional routes? Nice!
Leo Horie
@lhorie
Apr 04 2016 19:28
yeah one conceptual problem from current mithril is how everything is so tied to rendering
Barney Carroll
@barneycarroll
Apr 04 2016 19:28
That proved invaluable in my work with Moria
Leo Horie
@lhorie
Apr 04 2016 19:28
rewrite is aiming to make it all decoupled
Barney Carroll
@barneycarroll
Apr 04 2016 19:28
Wow
To try and keep the convenience of "this has everything you need to build simple SPAs out of the box" while allowing for "but if any given part of this doesn't work for you to van switch it out"…
aucelum
@aucelum
Apr 04 2016 19:30
is the rewrite endeavor public (mithril.js#next) ?
Barney Carroll
@barneycarroll
Apr 04 2016 19:30
@lhorie I hope we get to at least peak at documention before a version release
Leo Horie
@lhorie
Apr 04 2016 19:30
@aucelum no, #next is the 0.2.x stream
Barney Carroll
@barneycarroll
Apr 04 2016 19:31
IMO that's the hardest thing to get right, especially when there are known legitimate alternatives…
Leo Horie
@lhorie
Apr 04 2016 19:32
"if it ain't documented, it ain't done" :)
Barney Carroll
@barneycarroll
Apr 04 2016 19:32
@lhorie do you like any of the popular XHR abstractions?
Leo Horie
@lhorie
Apr 04 2016 19:32
such as?
Barney Carroll
@barneycarroll
Apr 04 2016 19:32
fetch, superagent
Leo Horie
@lhorie
Apr 04 2016 19:34
fetch is incomplete imho as per my comment above, I haven't used superagent
Barney Carroll
@barneycarroll
Apr 04 2016 19:34
The thing that I worry about with this is that it's a huge problem. It's the fundamentals of web connectivity. My defeatist attitude is that it's plain wrong for Mithril as a library to aim to fill those shoes.
Leo Horie
@lhorie
Apr 04 2016 19:35
for mithril to have an xhr api?
why?
Barney Carroll
@barneycarroll
Apr 04 2016 19:35
But I mean, jQuery's API for that is great. They've had so much developer attention with so many demanding users for so long that they've worked out a really great thing that's workable right.
Whereas with Mithril m request is very difficult to use well if your use case isn't the projected path of least resistance
Leo Horie
@lhorie
Apr 04 2016 19:37
are you talking about the late redraws by default semantics?
Barney Carroll
@barneycarroll
Apr 04 2016 19:37
For me it seems like a waste of time to suggest that you need to provide your own alternative API for how to communicate with remote sources
Considering how much else is going on that's so relevant to how we think of building modern applications, and how much agility you have in dealing with those… deciding to write the perfect XHR API from scratch just seems like a massive task that's not only highly unlikely to get it right but also not necessary
aucelum
@aucelum
Apr 04 2016 19:38
I've never used mithril's XHR stuff (I usually use a priority pool of cancellable and prioritized XHR objects). I'm happy with just something that takes a promise resolution and doesn't require me to write .then(m.redraw) at the last step. There's so much async stuff besides XHR (FileReader, FileSystem, new audio APIs...)
Barney Carroll
@barneycarroll
Apr 04 2016 19:39
@aucelum that's an interesting angle
Leo Horie
@lhorie
Apr 04 2016 19:40
well like I said, the API is mostly the same for m.request. I basically took the MDN page for XMLHttpRequest and copied the argument names. And rewrite's m.request is not tied to rendering
Barney Carroll
@barneycarroll
Apr 04 2016 19:40
But that's all m request is really, an API for XHR (that can also do JSONP) that calls m redraw on completion by default
Evgeniy Labutin
@LabEG
Apr 04 2016 19:41
@aucelum +
Barney Carroll
@barneycarroll
Apr 04 2016 19:41
@aucelum it sounds like you're saying you'd prefer a convenience API that just consumed any promise and called m redraw as a side effect
Web development 2016 state of the union: how to talk to a server using HTTP? We're working on it
;P
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:43
@aucelum I'd just take an existing API and wrap it:
export default function fetch() {
    return fetch.apply(undefined, arguments).then(m.redraw)
}
Leo Horie
@lhorie
Apr 04 2016 19:44
@isiahmeadows I think it's a bit more complicated than that (i.e. thennable composition)
that's a wart in current mithril too that I'm hoping to fix with the decoupled modules approach
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:45
So .then(() => m.redraw())? (I also meant window.fetch.apply(window, arguments))
I would prefer to explicitly redraw, though.
Leo Horie
@lhorie
Apr 04 2016 19:46
I mean fetch().then(doSomeStuff).then(whyIsMyUINotUpdated)
Barney Carroll
@barneycarroll
Apr 04 2016 19:46
@aucelum like instead of having whateverAsyncFunction().then( function( yes, no ){ m.redraw(); return yes || throw no} something like andRedraw( whateverAsyncFunction)
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:46
@lhorie Oh... .then(() => m.redraw(true)). My bad.
Barney Carroll
@barneycarroll
Apr 04 2016 19:47
Yeah but @lhorie this isn't a problem that's specific to figuring out the perfect API for requesting remote resources
aucelum
@aucelum
Apr 04 2016 19:47
@barneycarroll Yup. Don't know if that should be part of mithril though (is it generally useful?) Just write a wrapper otherwise
@isiahmeadows A simple wrap that is all I usually do. But I am not an experienced library author and can't anticipate complex needs
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:47
This?
export default function fetch() {
    return window.fetch.apply(window, arguments).then(() => m.redraw(true))
}
Leo Horie
@lhorie
Apr 04 2016 19:48
@barneycarroll I think the talking to server part is mostly figured out by now, it's more a question of how to compose async stuff that is being discussed now
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:48
@lhorie I find it easier to limit assumptions to simpler primitives.
And yes, that's the current talk right now.
Leo Horie
@lhorie
Apr 04 2016 19:49
@isiahmeadows I meant chaining a .then after your exported fetch (thus calling redraw before the rest of the then)
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:49
@lhorie Oh. My bad.
Evgeniy Labutin
@LabEG
Apr 04 2016 19:50
not need wrap system fetch
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:50
@lhorie That's what the current Mithril API does, though. The only reason it works is because it takes advantage that resolving promises is synchronous.
Barney Carroll
@barneycarroll
Apr 04 2016 19:50
@LabEG agreed
Leo Horie
@lhorie
Apr 04 2016 19:51
@isiahmeadows yep, but it's a wart nonetheless
and there are ways to break it from app space
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:51
I agree. That's also why I'd prefer to explicitly redraw. That guess is hard to get right.
Barney Carroll
@barneycarroll
Apr 04 2016 19:52
@lhorie that's what I'm saying. Break it out completely
Async is hard
Everybody struggles with it
Leo Horie
@lhorie
Apr 04 2016 19:52
yeah like I said, it's already broken out in rewrite :)
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:52
@lhorie :+1:
Justin
@WreckedAvent
Apr 04 2016 19:52
@isiahmeadows have you heard of livescript, if you're interested in the more functional stuff or idris? Mithril and livescript is a very nice combination.
Evgeniy Labutin
@LabEG
Apr 04 2016 19:53
example, i use next optimization on manies requests
Leo Horie
@lhorie
Apr 04 2016 19:53
I think calling redraw upon data change a la redux makes more sense fwiw
Barney Carroll
@barneycarroll
Apr 04 2016 19:53
We can debate whether Promises are fit for purpose or whether async / await are good ideas, but ultimately is Mithril's rewrite really going to be blocked by coming up with its own solution to all of this?
Leo Horie
@lhorie
Apr 04 2016 19:55
right now the major bottleneck is components. in my books, new m.request is dev complete and tested
Barney Carroll
@barneycarroll
Apr 04 2016 19:55
@lhorie it's great that you'd have broken out as a take it or leave it module, as and when that happens — but I was hoping the more general sense of 'separation of concerns' meant Mithril's rewrite might focus on more local concerns rather than aiming to solve this can of worms it's own way
Oh cool
I take it all back then :)
Justin
@WreckedAvent
Apr 04 2016 19:56
why are components a bottleneck?
Leo Horie
@lhorie
Apr 04 2016 19:56
I mean that they are not implemented yet in rewrite
whereas request, route, build/parseQueryString are written and tested
Isiah Meadows
@isiahmeadows
Apr 04 2016 19:58
@WreckedAvent My Techtonic test framework (WIP) was written in LiveScript previously. This is the last commit before I rewrote it in JS again. The reason I dropped it was because the stack traces were incredibly unhelpful when you're already having to deal with a lot of mutable internal state.
Barney Carroll
@barneycarroll
Apr 04 2016 19:59
@lhorie hey I don't mean to be mean, but carrying on my devil's advocate role: what do you think about URIjs?
Leo Horie
@lhorie
Apr 04 2016 20:01
@barneycarroll I looked at it for a bit, but ended up using Node/PHP backends as my testbeds instead for build/parseQueryString
Barney Carroll
@barneycarroll
Apr 04 2016 20:01
""
@isiahmeadows are you happy with Typescript at the moment?
Justin
@WreckedAvent
Apr 04 2016 20:01
Hmm, stacktraces haven't really been an issue for me. The syntax works very well for mithril views.
Leo Horie
@lhorie
Apr 04 2016 20:01
most notoriously, a=1&a=2 syntax breaks in PHP, so I went w/ the a[0]=1&a[0]=2 syntax instead
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:02
@barneycarroll I don't use it ATM. Mainly because I don't need it.
Barney Carroll
@barneycarroll
Apr 04 2016 20:02
Oh Jesus the whole issue of how to represent an array as a string in a URI
Justin
@WreckedAvent
Apr 04 2016 20:02
Typescript is useful in very large and complicated libraries like angular
quite a bit less so for mithril
Leo Horie
@lhorie
Apr 04 2016 20:02
@barneycarroll yeah... fun times
I also went ahead and fixed array parsing
Barney Carroll
@barneycarroll
Apr 04 2016 20:03
@lhorie I am a big fan of Rodney Rehm who wrote URIjs
Leo Horie
@lhorie
Apr 04 2016 20:03
(not that anyone will notice, going by the issue tracker...)
Barney Carroll
@barneycarroll
Apr 04 2016 20:04
He was the guy that railed about the "Lightweight Antipattern" that I cite once in a while
Leo Horie
@lhorie
Apr 04 2016 20:04
oh it's the same guy? TIL.
Justin
@WreckedAvent
Apr 04 2016 20:04
@isiahmeadows there's also funscript, but it's hard to find a more functional JS compile-to that doesn't live off in its own little island like elm and purescript
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:05
@WreckedAvent LiveScript isn't as bad with Mithril, though. Mithril from an external API standpoint is more declarative, so functional languages shine with that. But when implementing those declarative APIs, you often need complex state management with imperative manipulations, which functional languages can get in the way on occasion.
Barney Carroll
@barneycarroll
Apr 04 2016 20:05
But I seem to remember that actually URIjs wasn't very graceful when changing between standard array expressions
Justin
@WreckedAvent
Apr 04 2016 20:05
@barneycarroll "Lightweight antipattern" sounds a lot like "lightweight code considered harmful"
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:05
I've heard of FunScript, but I don't see anything particularly valuable in that specifically.
Justin
@WreckedAvent
Apr 04 2016 20:06
It covers ML -> JS
Leo Horie
@lhorie
Apr 04 2016 20:06
I think build/parseQueryString testing is pretty thorough now. I couldn't come up w/ any cases that broke the tests
Justin
@WreckedAvent
Apr 04 2016 20:06
F# also has some interesting things like type providers and async workflows
But haskell has captures more imaginations than ML does
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:06
@WreckedAvent I know, and I'm familiar with F#. I haven't done much with it, but that's because I don't use Windows.
Leo Horie
@lhorie
Apr 04 2016 20:07
funny thing, I thought I had found a broken case for a[][]=1&a[][]=2 but it turned out that this syntax breaks in both Node and PHP anyways
Justin
@WreckedAvent
Apr 04 2016 20:07
Oh! Well, I often have to explain and justify why F# exists whenever I bring it up
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:07
As for Haskell, it just happens to have a super high learning curve.
Cabal is annoying IMHO.
Justin
@WreckedAvent
Apr 04 2016 20:08
yes, one of the reasons I like F# actually. Typeclasses are very neat but hard for mere mortals to comprehend
Barney Carroll
@barneycarroll
Apr 04 2016 20:08
@WreckedAvent yeah that's basically it. It was written at a time when there was a surfeit of people trying to write and popularise their own "I can do that in less bytes!" JS code and explained that something which aims to address 75% of use cases in 1/10 the size is irresponsible
Justin
@WreckedAvent
Apr 04 2016 20:08
I spent more time trying to explain monads in terms of promise to everyone else who had to read the code than actually writing the code
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:08
That platform problem is the only reason why I haven't dived deeper into F#.
I've implemented monads in JS, though.
Barney Carroll
@barneycarroll
Apr 04 2016 20:08
@WreckedAvent haha
Justin
@WreckedAvent
Apr 04 2016 20:08
@isiahmeadows sure, Promises
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:09
I mean I've implemented a Maybe monad a few times.
Justin
@WreckedAvent
Apr 04 2016 20:09
I'm quite interested in generators because they can provide very convenient bind syntax
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:09
The more basic monads are very simple to implement IMHO
Barney Carroll
@barneycarroll
Apr 04 2016 20:09
That's my favourite developer cultural tick: somebody explains that they have the perfect solution while everybody else just fails to grok it…
Justin
@WreckedAvent
Apr 04 2016 20:10
Monads are very simple, just people keep talking about them in horribly abstract ways
Haskell has this IO monad which beginners spend like weeks just trying to figure out
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:10
Pretty much, sadly.
Justin
@WreckedAvent
Apr 04 2016 20:10
Whereas if described like a Promise 'a - where you can enter, but never leave, I found people catch on more quickly
Evgeniy Labutin
@LabEG
Apr 04 2016 20:10
OOP is best =D
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:11
Easy way to explain the IO monad: it's a wrapper type that allows you to interact with the outside world, where you can't otherwise.
Barney Carroll
@barneycarroll
Apr 04 2016 20:11
You enter and something else will come back
Justin
@WreckedAvent
Apr 04 2016 20:11
Also, Fsharp got support for .NET core at some point, so you might be able to work with that on non-windows
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:11
You can only interact with the outside world through that IO monad.
Justin
@WreckedAvent
Apr 04 2016 20:12
IO 'a is same deal, you can enter but never leave. It's just very abstract
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:12
@WreckedAvent I know F# works on Linux, now, but I'm waiting on NuGet.
Justin
@WreckedAvent
Apr 04 2016 20:12
.NET core has a cross-platform nuget installer
I'm not aware if it's worth a damn but it's there
watchy watchy video
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:13
Must be recent enough that I haven't seen it.
Barney Carroll
@barneycarroll
Apr 04 2016 20:13
The thing with Promises is that you need to distinguish between what the internal state machine needs to know and what you need to know
Issues of trust
Don't make a Promise you can't keep
Justin
@WreckedAvent
Apr 04 2016 20:13
At about ~5:35 he makes a call to dotnet restore
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:14
@barneycarroll That's why it's called a "promise"
Barney Carroll
@barneycarroll
Apr 04 2016 20:14
In my reading circles, that's still a really hard thing to grok
I think the dominance of Node in the JS ecosystem is largely to blame for that
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:15
@WreckedAvent Have you heard of BuckleScript, a JS->OCaml backend? I'm aware of Js_of_ocaml, but this one seems more promising in terms of performance.
Barney Carroll
@barneycarroll
Apr 04 2016 20:16
They use privileged environments and native CJS to achieve things the front end couldn't achieve, and they favour passed in callbacks as a result
But that's really not good enough for a holistic attitude to potentially remote processes
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:17
@barneycarroll Here's a way of explaining the concept of Promises to the more imperatively minded: you're making a promise that you'll try to get something and return it to them (i.e. call .then, and if you can't, you'll let them know why you couldn't (i.e. call .catch).
Barney Carroll
@barneycarroll
Apr 04 2016 20:18
That's really good as a one paragraph description
The problem is people thinking "Well I could also do this with less bytecode" and ending up in a responsibility mess
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:19
The difference is that you can still plan what to do with that thing you requested, even if you couldn't get that thing. It's almost like a try-catch for async code.
Promises are easier to break down into human language than callbacks.
Leo Horie
@lhorie
Apr 04 2016 20:20
I think most people grok the basics, but don't know about returning promises and catch-all behavior
Barney Carroll
@barneycarroll
Apr 04 2016 20:20
@lhorie where is my error?!
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:21
The catch also functions as "if something went wrong with how I handled it, here's what I need to do to recover, if possible."
Barney Carroll
@barneycarroll
Apr 04 2016 20:21
@isiahmeadows another great quote
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:21
Thanks :smile:
Barney Carroll
@barneycarroll
Apr 04 2016 20:22
It's ultimately a question of who's handling what
Leo Horie
@lhorie
Apr 04 2016 20:22
@barneycarroll waiting for proper error propagation to land in node. Chrome does it properly
Barney Carroll
@barneycarroll
Apr 04 2016 20:22
Back in ES5 writing a function was so much boilerplate
Justin
@WreckedAvent
Apr 04 2016 20:22
I hadn't heard of bucklescript yet
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:22
I think the biggest problem with how most programmers try explaining concepts to each other is that they get too stuck in the abstract. If you make it concrete, it's easier to conceptualize.
@barneycarroll
Barney Carroll
@barneycarroll
Apr 04 2016 20:23
Yeah you're right
Justin
@WreckedAvent
Apr 04 2016 20:23
That's my problem with IO 'a @isiahmeadows
Barney Carroll
@barneycarroll
Apr 04 2016 20:23
The problem is in devising credible problem cases that don't distract the reader with orthogonal concerns
Justin
@WreckedAvent
Apr 04 2016 20:24
It's an obscenely abstract solution to a very abstraction problem
@lhorie the biggest problem I've seen people have with promises is understanding they can flat-map and the old "my errors are swallowed!"
Barney Carroll
@barneycarroll
Apr 04 2016 20:24
TBF consistent error handling has been a minefield
Justin
@WreckedAvent
Apr 04 2016 20:25
but now chrome throws failed promises w/o a failure, so that might help
yes, but without promises, error handling is tedious as all get out
Barney Carroll
@barneycarroll
Apr 04 2016 20:25
Like Leo says, it's only recently that a browser has started doing this right
Leo Horie
@lhorie
Apr 04 2016 20:25
FF does it too, albeit on a timeout
Justin
@WreckedAvent
Apr 04 2016 20:25
myNodeFn(function(err, res) { if (err) throw err; });
yeesh
Barney Carroll
@barneycarroll
Apr 04 2016 20:26
Trying to explain the theoretical cognitive gains when you can't replicate that in your target environment… that's difficult
Meanwhile there's a lot of pushback in core JS community
Justin
@WreckedAvent
Apr 04 2016 20:27
At least you can see a before/after with promises to see how much code you'd have to write compared to nested callbacks. Things like IO 'a add complexity to things most programmers already know ... and it's usually more verbose in do notation
of what @barneycarroll ?
Barney Carroll
@barneycarroll
Apr 04 2016 20:28
All the core callback-based API was working just fine, thank you very much
Justin
@WreckedAvent
Apr 04 2016 20:28
At least things like setTimeout are trivial to uplift
Leo Horie
@lhorie
Apr 04 2016 20:29
I don't think I've seen many people prefer callbacks to promises, to be honest
Barney Carroll
@barneycarroll
Apr 04 2016 20:29
But if you look at eg file system methods with Node
Justin
@WreckedAvent
Apr 04 2016 20:29
The node community is different
Barney Carroll
@barneycarroll
Apr 04 2016 20:29
Async is the default
Justin
@WreckedAvent
Apr 04 2016 20:30
In browsers, the new stuff seems to be (rightfully) promise-based
Evgeniy Labutin
@LabEG
Apr 04 2016 20:30
async +
Justin
@WreckedAvent
Apr 04 2016 20:30
like fetch
Barney Carroll
@barneycarroll
Apr 04 2016 20:30
Yeah
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:31
@WreckedAvent Think of IO Car as basically allowing you to manipulate Cars in areas where you're interacting with the outside world. Normally, you're only allowed to manipulate Cars, but in order to get that data from the user, you can only get it as IO Cars. Then, you can do whatever you like with those cars, like getting all the Passengers from those Cars. After that, you can display it to the user, and get an IO () in return. This signifies you've given something to the outside world without getting anything back.
Barney Carroll
@barneycarroll
Apr 04 2016 20:31
So what do you reckon about async & await?
Justin
@WreckedAvent
Apr 04 2016 20:31
I understand IO 'a just fine, I just hate trying to make people see any value in the abstraction
I'm glad generators are powerful enough to enable async/await, since that means they can work over monads just fine as wel
Barney Carroll
@barneycarroll
Apr 04 2016 20:32
Is this another case of being able to use keywords to extend privilege and other people getting worried about that? ;)
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:32
@WreckedAvent I know you understand the concept, but I'm giving ideas on how to make it more concrete for those who don't.
Barney Carroll
@barneycarroll
Apr 04 2016 20:34
Right so @WreckedAvent do you think that generators and yield mean async + await are just too much low level API for something which people can already get done good enough with fundamental concepts that are already excruciating to explain?
Justin
@WreckedAvent
Apr 04 2016 20:34
I do a lot of work in C#, which had a somewhat similar transition from call-back based to async + await
In my experience people treat it exactly as synchronous code
Barney Carroll
@barneycarroll
Apr 04 2016 20:35
Which is a blessing…?
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:35
@WreckedAvent And if you can only interact with the outside world in very limited circumstances, it's easier to test your code within its own little box.
Justin
@WreckedAvent
Apr 04 2016 20:35
Potentially, but it makes it harder for people to conceptualize some kinds of other async things, like parallelism
I don't see many people writing generators by hand. An async generator driver function would be non-trivial
Barney Carroll
@barneycarroll
Apr 04 2016 20:36
@isiahmeadows why does everything need to interact with the outside world? Doesn't that just make every piece of code immensely more complicated in theory?
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:36
@WreckedAvent @barneycarroll It IMHO is nice as an option. It's nice to be able to blend the two together when necessary.
@barneycarroll That's the whole point behind the IO monad. You don't.
Justin
@WreckedAvent
Apr 04 2016 20:36
It's fine, I don't have any problems against it, I just would have preferred more general sugar over generators
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:36
@barneycarroll It complicates things both in theory and in practice
Justin
@WreckedAvent
Apr 04 2016 20:37
then we would have gotten list comprehensions and do-like sugar for things like Maybe
Barney Carroll
@barneycarroll
Apr 04 2016 20:37
@WreckedAvent right. You seen any good proposals in that space?
Justin
@WreckedAvent
Apr 04 2016 20:37
nope!
Closest is fantasy land spec for various functional things, but that's not really a proposed ES thing
However, F# has a fantastic model
They're called computation expressions and it's how the language gets around not having haskell-style do syntax
also, the point of the IO 'a monad is to exactly restrict your real-world to when you need it, and no more, since real-world complicates things so much
since IO 'a "taints" code, you try to keep it basically isolated to just your app's entry point
Barney Carroll
@barneycarroll
Apr 04 2016 20:41
My overarching problem with programmer culture here is that you have a huge culture of people grasping for idiomatic solutions related to their everyday responsibilities and an elite class of conceptual programmers who operate on a higher level and can barely engage with the hoi paloi because they know solutions exist to their problems, it's just that people won't let them
@WreckedAvent like remote procedure calls?
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:47
Where I live, React is relatively unknown, if that says anything.
There isn't really much in terms of "there's only one way", but it's almost surprising this area isn't running 90% on legacy Java.
The two main languages around here, both mostly running on Windows, are Ruby and PHP.
Grant Miner
@llambda
Apr 04 2016 20:50
FWIW async/await and promises have become quite popular in Node
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:50
WordPress is used by some, but it's not everywhere. I'd estimate about half of PHP users use that.
Leo Horie
@lhorie
Apr 04 2016 20:50
my wife does new projects in angular 1 still. Grunt is a new thing for her projects
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:50
@lhorie Damn...
Grant Miner
@llambda
Apr 04 2016 20:52
What (re angular1/grunt)
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:52
@llambda I tried it with Bluebird, and I didn't really see much benefit. Granted, I tend to prefer expressiveness over clarity to an extent, so until async iterators get their for ... of equivalent, I'm not planning on rushing to them. I'm still using ES5 a large portion of the time because I don't need ES6 features.
re: async functions
Leo Horie
@lhorie
Apr 04 2016 20:53
that's bigcorp for ya (bank/telecomm consulting...)
Grant Miner
@llambda
Apr 04 2016 20:54
Have you tried Promise.map(items, async function) or Promise.each? I was also using ES5 mostly and only this weekend just started using Babel with async await. I was doing Promise.coroutine(function*()...) before
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:54
@lhorie IMHO vanilla JS is easier to work with.
Grant Miner
@llambda
Apr 04 2016 20:54
I have to admit async await simplified my codebase a lot. Mostly on Node backend
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:54
@llambda I've used that a little bit in Techtonic.
Pat Cavit
@tivac
Apr 04 2016 20:55
where are Promise.map/Promise.each from
Grant Miner
@llambda
Apr 04 2016 20:55
Bluebird
Pat Cavit
@tivac
Apr 04 2016 20:56
figured, was hoping they were part of a spec update to actual Promise
Grant Miner
@llambda
Apr 04 2016 20:56
Another nice feature is you can pass concurrency as a parameter.
yeah, es Promise is way underspecced :)
es promise doesn't even have finally :(
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:58
@tivac @llambda Bluebird is not only more user friendly, it's also much faster.
Barney Carroll
@barneycarroll
Apr 04 2016 20:58
@isiahmeadows when you want to write a FSM application (like a Mithril app) with login and sensitive login error handling and remote services… async await becomes invaluable
Isiah Meadows
@isiahmeadows
Apr 04 2016 20:59
Yeah. Most of my websites are static ATM, though, so I don't need it.
Barney Carroll
@barneycarroll
Apr 04 2016 21:00
Because the Promise principle of "don't put all your eggs in someone else's basket" aligns really neatly with "can we just talk about this single execution context" for a very sensitive code block that needs to manage a variety of concerns
Generators are great for managing sequences, but when you're dealing with ambitious web applications that make full use of the potential remote services offer, writing your own FSM API wrapper for every little thing is kind of the opposite of what you're looking for
Isiah Meadows
@isiahmeadows
Apr 04 2016 21:03
FSM? (I don't know that off-hand)
Barney Carroll
@barneycarroll
Apr 04 2016 21:04
Whereas if you're dealing with no significant backend dynamism… what problems are you solving by introducing new models? Are we trying to slowly develop idioms that will eventually many WordPress more cool? Seriously?
Oh Finite State Machine
Justin
@WreckedAvent
Apr 04 2016 21:07
I have inherent disdain for bluebird since they use terms like map for mapping over an array of promises
map over promises is called then and it makes me grumbly
Barney Carroll
@barneycarroll
Apr 04 2016 21:07
Execution context is handed over to a context which takes charge of the main Execution context but cannot refer to the external codebase except by saying "I'm done, your turn now" and then it dies
@WreckedAvent yeah that's a really interesting point of contention
IT'S SO INTUITIVE
but
Justin
@WreckedAvent
Apr 04 2016 21:08
but it's the wrong thing
Barney Carroll
@barneycarroll
Apr 04 2016 21:08
IT'S WRONG
and
Justin
@WreckedAvent
Apr 04 2016 21:09
and you can already do it just by using the array map
Barney Carroll
@barneycarroll
Apr 04 2016 21:09
YOU COULD ALREADY SO THAT WITH ANOTHER DOZEN BYTES
Justin
@WreckedAvent
Apr 04 2016 21:09
I WANT TO TALK IN CAPS TOO
Barney Carroll
@barneycarroll
Apr 04 2016 21:10
Italics are hard with Gitter mobile ;)
Pat Cavit
@tivac
Apr 04 2016 21:10
I LIKE YELLING
Isiah Meadows
@isiahmeadows
Apr 04 2016 21:11

@barneycarroll

Oh Finite State Machine

Thanks :smile:

Justin
@WreckedAvent
Apr 04 2016 21:11
tbh I was thinking flying spaghetti monster but finite state machine makes way more sense
Isiah Meadows
@isiahmeadows
Apr 04 2016 21:12
@barneycarroll @WreckedAvent @tivac :laughing:
This message was deleted
Leo Horie
@lhorie
Apr 04 2016 21:12
lol
now I want a flying spaghetti monster API
Isiah Meadows
@isiahmeadows
Apr 04 2016 21:14
lol
Barney Carroll
@barneycarroll
Apr 04 2016 21:14
This execution context depends entirely upon you. It does not make any sense to create one to set you up and to create another for your eventual return. If you die, I die. Do your thing then tell me where you ended up.
As opposed to, I've got my own concerns — including the sanctity of the main thread — and I will arrange for you to come about but then depending on your actions something else may happen and that's kinda my responsibility but at this point whatever let's just see what happens
Justin
@WreckedAvent
Apr 04 2016 21:17
rock 'n roll
Barney Carroll
@barneycarroll
Apr 04 2016 21:17
Imperative async with a very limited API surface: good idea
Grant Miner
@llambda
Apr 04 2016 21:24
huh? map maps over an iterator and returns a promise
Justin
@WreckedAvent
Apr 04 2016 21:25
Only for iteratable monoids ie list and sequence
Over other monoids it applies a general transformation function to a particular context
mapping over functions is called function composition, for example
so the version of map over Promise 'a accepts a function and returns another promise after evaluating that function
We understand that as Promise#then
The bluebird then is just some weird thing designed to reduce boilerplate in one oddly-specific scenario
bluebird map*
Isiah Meadows
@isiahmeadows
Apr 04 2016 22:02
Bluebird's map is more like p.map = f => p.then(xs => Array.from(xs).map(f)). It's a bit specific, but that specific scenario is helpful.
If anything, Promise.each and Promise.map made this part about 2/3 the size it otherwise would be.
Justin
@WreckedAvent
Apr 04 2016 22:25
not saying it has no use, just the name is annoying
Particularly since it recommends installing itself as a variable called Promise
Isiah Meadows
@isiahmeadows
Apr 04 2016 22:29
Blame it on the JS community a few years ago for establishing the then idiom instead of map. Other languages have been inspired by JS as well for their promises and deferreds (e.g. Python).
Justin
@WreckedAvent
Apr 04 2016 22:31
Well, Promise#then isn't technically only a map, it's also bind, so calling it map would have been a mistake
That's why if you look at typescript definitions for then it always must be defined with two signatures - one that returns a promise, and one that returns any type
Isiah Meadows
@isiahmeadows
Apr 04 2016 23:04
Or more accurately, a recursive type (yes, that's possible with interfaces).
Justin
@WreckedAvent
Apr 04 2016 23:11
My point was more about the two definitions for then rather than it being defined recursively
Isiah Meadows
@isiahmeadows
Apr 04 2016 23:20
I'm referring to Promise needing to be a recursive type.