Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Bor González Usach
    @bgusach
    Hello there, just have a small question that kind of prevents me from doing some toy applications and starting to grasp this SAM thing. When using functions to create the views (instead of templates or JSX, etc), how do define the event handlers? In the examples I have seen some stuff like return '<button onclick=somefunction(somedata)>', but I don't see that going a long way: what if I don't have a reference (even within a namespace) in the global scope? Thanks.
    Gunar Gessner
    @gunar
    @bgusach using functions that return html is an implementation that @jdubray likes but is not at all necessary for SAM. I myself find it hard to use after knowing about React/VirtualDom.
    Jean-Jacques Dubray
    @jdubray
    There is no requirement whatsoever to do so, or even use HTML at all. This is just a pattern that simply states that the view is created as a function of the model, in a similar way to React.js. The same thing could be achieved in Objective-C/Swift, Java (Android SDK), ...
    Bor González Usach
    @bgusach
    I know, but for me it is about HTML and JS. And I really prefer good old javascript over a yet another framework (actually I found about SAM because of a comment on a blog post about the gazillion tools you need for JS development). And I think that it is easier to grasp the essence of something instead of getting distracted with yet-another-cool-thing (that cycle.js for instance)
    Jean-Jacques Dubray
    @jdubray
    a big THANK YOU!!
    Bor González Usach
    @bgusach

    So no easy fix for my problem? :D

    By the way @jdubray, what are your opinions about Ember? It offers some solutions to some of your problems. For instance, the models on the client don't have to match exactly what you are retrieving from the server. First you have a so-called "adapter" that can modify the data before it comes in or gets out, and then (and most importantly) your client models can have computed properties, e.g. if you have a Person model, and the age is coming from the server, you can define a property that computes on the fly "young" or "old" based on the age attribute.

    Jean-Jacques Dubray
    @jdubray

    sorry, I am not sure I fully understand your question.

    what if I don't have a reference (even within a namespace) in the global scope? Thanks.

    You'd have to dispatch the action in some ways, passing the corresponding parameters. Have you seen the example with Cycle.js?

    Jean-Jacques Dubray
    @jdubray
    Since the view is "generated" from the State which knows the allowed actions (and how to reach them) I don't see how you would not "have a reference".
    Bor González Usach
    @bgusach

    @jdubray the problem I see is that, if I have a function myAction, and I want it to be bound to the onclick, I have to write (as a string) something like onclick="myAction". But that will only work if that function is reachable from the global scope, which is something you want to avoid at all costs when developing serious JS applications.

    If I pack my whole application within an object that acts as a namespace, for instance MYAPP, and I expose my function there, I could write onclick="MYAPP.myAction", but still it would be better not to do so, and somehow bind the handler in another way.

    Gunar Gessner
    @gunar
    @jdubray I've put your Rocket example in a Fiddle. I've added a new button "Dummy Action" to test the nap() function. As I imagined, as your nap() doesn't know if it already has set a timer or not, it may set multiple timers i.e. running any other action during the countdown sets another timer. The end result is the same as these multiple timers don't interfere with one another, still, this could become a problem scaling. I don't like having to store a flag (mutate the state) just to indicate that a timer has been set. Do you know of any other solution?
    Jean-Jacques Dubray
    @jdubray
    @bgusach when you consider that the view is "generated" (as in code generation), then there is no need whatsoever to bind handlers another way. You are thinking that someone writes the code, when in reality someone wrote the generator that wrote the code.
    That's the absolute beauty of V = f(M)
    sorry, I am an old MDSE guy (can't help it)
    @gunar yes and no, because remember, unlike Redux / Sagas, SAM sequences precisely action-model-state. If you look at Redux thunks, they write a "script" regardless of the control state reached. That is fundamentally flawed. That is why I wanted to talk to Dan originally, because Redux is so close, but at the same time, it's leading people in the wrong direction. We are back to the usual action-oriented spaghetti.
    Front-End Architecture is such a perfect use case for SAM, because precisely it is a state machine. That's why FEA failed for the past 40 years, because we all ignored the state machine beneath.
    Jean-Jacques Dubray
    @jdubray
    SAM works, because its semantics are precise enough. State machines don't work when you start writing (S1, A,B,C, S2)
    Because After A, B may not be allowed, you can't arbitrarily write it that way
    Gunar Gessner
    @gunar
    Yes it's awesome not to have to worry about entering invalid states, but imagine a very complex app sending numerous actions, that'd trigger many timers. From a SAM perspective that's not a problem at all, but has performance costs on the browser. But I guess that's beyond the scope of this discussion.
    Jean-Jacques Dubray
    @jdubray
    Performance, IMHO is never a problem these days. Whenever there is a performance bottleneck we always found a way to fix it (virtual-Dom for instance).
    Remember, you also don't have to follow the exact semantic of SAM if you know what you are doing. In other words, that's what we have been doing for decades, writing state machines as a series of actions. The problem is that we rarely know what we are doing and SAM provides just enough constrains to eliminate most problems without much overhead.
    Algorithms tend to not require patterns like SAM, so I am not suggesting that we start using SAM everywhere all the time. I am saying however that SAM semantics (TLA+) work everywhere all the time, so when you see value over more "optimized code" you should go back to the basics of SAM.
    Jean-Jacques Dubray
    @jdubray
    That's what AWS is doing when they use TLA+. They write some code, but it's buggy, and the only way for them to find the bug is to "simulate" their code with TLA+. However for optimization reasons, they would not write it following the TLA+ semantics
    Does that make sense?
    Gunar Gessner
    @gunar
    "Simulate"? They rewrote parts of their software in TLA+ patterns just to better understand the system?
    Jean-Jacques Dubray
    @jdubray
    yes, this is what TLA+ is, it's not a programming language, it is a formal method to analyze code
    Since I learned about TLA+, I have looked at ways to use the semantics as you code so you have less bug to analyze later...
    I am lazy :-)
    Gunar Gessner
    @gunar
    Awesome
    Jean-Jacques Dubray
    @jdubray
    But again, that's not a way to write all your code.
    I'll never make that claim
    adonirammedeiros
    @adonirammedeiros
    @jdubray how do you compose larger SAM components with small ones? There's some way to do this?
    Jean-Jacques Dubray
    @jdubray
    It works at the view level, view can call actions at any level. comp
    I can't claim you can nest n-level, but 2-3 levels should be ok.
    Would that work for you?
    adonirammedeiros
    @adonirammedeiros
    The way you describe it seems that I will use the actions from low levels in high level views. I wondering about composing views too. For example, I have a SAM components handling different things with different views and I need to compose then on a larger SAM component that orchestrate then.
    Bor González Usach
    @bgusach
    @jdubray, I think you did not understand what I said about attaching handlers to DOM Nodes built by string concatenation... anyway, it is just an implementation detail for HTML, nothing to spend too much time on.
    Gunar Gessner
    @gunar
    @bgusach you could try checking out how react does it. perhaps even Inpecting a React app through Developer Console could give you a hint. I'm curious too so let me know if you find something interesting.
    @adonirammedeiros so you don't want your low level views/actions to know about higher order SAM cycles?
    Hmm... perhaps the inner Model could be a part of the outer Model. Sharing parts of the Store.
    Gunar Gessner
    @gunar
    I (we?) haven't yet thought about SAM "components" , but rather as an architecture for whole apps.
    Gunar Gessner
    @gunar
    @bgusach I think that because React uses var el = createElement - instead of creating elements on the fly with strings - it can do e.g. el.onClick = ...
    you could do that - and I've done it before - if you give the node an id (e.g. <button id="send">) and then attach all event handlers after view rendering (e.g. document.getElementById('send')). Remember to have unique IDs.
    I don't see another solution atm. Either that or using global references.
    Bor González Usach
    @bgusach
    @gunar, yes most of libraries create DOM Nodes via createElement, and then with the DOM Node you just have to set onClick or append an event listener. The idea of the IDs is not very practical in my opinion... somehow you have to keep track of the IDs and then attach the handlers. Looks like more work and not so clean information workflow (normally you would like to append the handlers when creating the code for the view). I have found the minimalistic library hyperscript quite nice, and the virtual-bom library is based upon this, which makes easier moving from raw re-rendering to a virtual dom approach.
    Jean-Jacques Dubray
    @jdubray

    @bgusach I was responding to this question:

    The idea of the IDs is not very practical in my opinion... somehow you have to keep track of the IDs and then attach the handlers.

    This is where code generation makes it rather trivial compared to handcoding it.

    Wiring HTML to actions otherwise has nothing to do with SAM.
    If we take a simple example, say a login panel:
    <input id="username" type="text" value="username">
    <input id="password" type="password" value="password">
    <button class="button" id="login">Login</button>
    Your handler is going to look like that (assuming the function V = S(M) is computed on the client):
    $('#login').click(function() {
            var view  = document.getElementById("view") ;
            var session = $.post( "https://www.nomvc.com/actions/v1/logmein", { username: $( "#username" ).val(), password:$( "#password" ).val() } ) ;
                session
                    .done(function( model ) {
                        view.innerHTML = state.render(model) ;})
                    .fail( function(data) {
                        view.innerHTML = state.render({error: "server error"}) ; })
        }) ;
    Jean-Jacques Dubray
    @jdubray

    The State element is generating both the state representation with the knowledge of the actions. So there is no conceptual difficulty in aligning the two.

    id="login"

    can be generated not handcoded

    Bor González Usach
    @bgusach
    @jdubray your example is fine, but I really don't think that is elegant in a general case. Let's say we have a model with some items, and for each item you want to create a button: with the IDs approach you iterate through the model, generate the HTML string, then you attach it to your DOM top root node via innerHTML and then once rendered, you iterate again through the model so that you know some IDs, fetch DOM elements by ID, and then append handlers. I really would not do that. It looks way easier just to generate the DOM nodes with createElementcalls, bind the events, and return the DOM object instead of a string. Anyway, as you have commented, this is not an architecture issue...
    adonirammedeiros
    @adonirammedeiros
    @gunar if my low level components know about high level components they become attached to the context and I lose component reusability. I think about components that know a little bit about each other, just to allow the composition. I looking for something like mithril (I know mithril is a framework and SAM is a pattern), hmvc or pac. I like SAM idea. I try to imagine how I can reuse components in different contexts with little to no "friction". Putting a lower level Model inside a higher level Model, can lead me to put a lower level Action inside a higher level Action and so on. Based on @jdubray example (if I understand correctly) I think the Action can be used like "public interface" of a SAM component.