These are chat archives for jdubray/sam

31st
Aug 2017
Janne Siera
@jannesiera
Aug 31 2017 07:07
@jdubray it is impossible to type something in there at a normal speed. There is a delay after every time you type a character where you have to wait a bit u until you can type a new one. This is on my phone in the codependent.
Codepen*
Victor Noël
@victornoel
Aug 31 2017 07:35
it works ok in chrome, but once I type space, I loose focus on the first field…
Janne Siera
@jannesiera
Aug 31 2017 08:57
On my laptop it runs fine. On my phone it's just lagging a lot. The vue sample works fine on my phone. And my phone is quite high end...
Daniel Neveux
@dagatsoin
Aug 31 2017 12:03
Tested on safari ios (iphone se) works fine.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 12:46
@victornoel sorry, corrected the problem ...
Victor Noël
@victornoel
Aug 31 2017 12:46
:)
Jean-Jacques Dubray
@jdubray
Aug 31 2017 12:48
yes, I didn't see much problem with the speed. It doesn't feel different than typing here. I am sure if the bit of HTML was bigger, you'd start seeing some difference. I'll write a sample today without the focus using hash-dom.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 12:59

I also want to bring your attention on this code snippet:

model.lastCharIsSpace = model.tweet[model.tweet.length - 1] === ' '
if (model.lastCharIsSpace) {
        model.translated = false
}

I am not a specialist of RP by any measure, but I need to detect detect when to initiate a translation. You could think that lastCharIsSpace (and hence translated) is a computed property, but you really want to know about it in the context of processing a new tweet proposal, not in general, otherwise the translation would occur at for other types of proposal (@dagatsoin do you have an opinion?)

that's also the kind of logic you would never put in the "action", now it becomes reusable each an action (whichever one) passes a "tweet" in its proposal
That's by far the part I like the most in SAM, I use it all the time, I can create "composite" proposals from variants of actions, which otherwise would be hard to replicate if I had monolithic event handlers.
That's my I insist on this many-to-many relationship between actions and acceptors
Fred Daoud
@foxdonut
Aug 31 2017 13:03
@jdubray interesting ... but for some reason you can't backspace when there is 1 character.
Also, you can't select all with Ctrl-A (or Cmd-A).
Jean-Jacques Dubray
@jdubray
Aug 31 2017 13:07
I can backspace just fine. Yes I implemented the focus in a way that prevents ctrl-a to work. I should have used start and end properly.
Fred Daoud
@foxdonut
Aug 31 2017 13:10
@jdubray you can backspace, but when there is just one character left, you can't erase that last character.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 13:11
I don't have that problem
Janne Siera
@jannesiera
Aug 31 2017 13:12
I also have the backspace problem on the first character. Also, still lagging on my phone.
I have a one plus 3 if you're interested
Fred Daoud
@foxdonut
Aug 31 2017 13:13
doesn't work on chrome nor firefox
on mac nor linux
Jean-Jacques Dubray
@jdubray
Aug 31 2017 13:17
I am on chrome windows10 rigth now. Interesting, I'll try to debug the problem on my Mac later today
I also want to bring your attention on that piece of code:
model.charactersRemaining = MAX_TWEET_LENGTH - proposal.tweet.length
should this calculation be done in the model or the action?
and then proposed to the model
The action might be a better place, because it's a bit closer to this particular UI. You could create a generic model that works with a larger capacity and use context specific rules for the max value.
It would also be easier to make decisions like if (model.charactersRemaining > proposal.charactersRemaining) ...
that's really the difference between the "next-step" value and the "current-step" value, the essence of TLA+
Jean-Jacques Dubray
@jdubray
Aug 31 2017 13:22
@foxdonut @jannesiera I see the same problem on Edge
sorry, I was cleaning up the code and removed !== undefined, that prevented the tweet acceptor to run...
:-)
Fred Daoud
@foxdonut
Aug 31 2017 13:28
Out of curiosity I tried it with picodom, it seems to handle the re-rendering of text input without problem.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 13:32
sure, I'd be surprised if they do not. I just need to do a small project to convince myself it's ok to use a vdom library, in other words, you don't lose too much control.
Fred Daoud
@foxdonut
Aug 31 2017 13:33
You know, thinking about this, if it were up to me, I would use JSX and picodom, simply because it's so tiny and the source code is actually readable and understandable.
Then, if for example performance was an issue, switching to another library such as Inferno would only involve changing the JSX configuration in one place, and the setup code in once place.
All the view code would not have to change at all. If I'm not mistaken, Inferno, Preact, picodom, and mithril all use the same attributes with JSX, i.e. onclick and oninput. Only React uses onClick and onChange.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 13:34
It's definitely on my list to try, no question about it.
Another big requirement for me is to be as close as possible to the HTML template I start from (which is met by JSX)
I still use a lots of JQuery based components (DataTables, Charts, Datepickers...) and they are not handled well with "modern" framworks. I remember last year how long it took us to find a decent datepicker that worked with Angular 2, not to mention file upload.
That's in part why I am so reluctant to lose control, the other part is simply pure dependency.
Paolo Furini
@pfurini
Aug 31 2017 17:12
Hi, I've recently seen this course on udemy: https://www.udemy.com/angular-ngrx-course/ and I'm curious about your opinion on ngrx store (sort of flux for angular?), and how that could be aligned to SAM principles (disclaimer: I don't know anything about ngrx, just curious about it)
EDIT: ngrx seems to be more like redux for NG than flux.. just saw that on official repo
Jean-Jacques Dubray
@jdubray
Aug 31 2017 17:16
yes, it's a Redux equivalent
The part that I don't like about Redux/Elm is that they encourage a bad behavior, they say to go from Application State1 to Application State2 you just need a pure function.
In theory, that works, anything works in programming.
In practice it's like putting a function box on top of a big event handler mess and claim that's better.
That's why Redux introduced Thunks, Sagas, now people start using MobX, and so many other moving parts I don't know about.
Paolo Furini
@pfurini
Aug 31 2017 17:19
Me either I don't know a thing on the latter
Jean-Jacques Dubray
@jdubray
Aug 31 2017 17:19
Redux and Elm love this approach because of time travel. I am not quite sure why, but some people feel that time travel is important to their workflow
Being a back-end guy, for me the ability to articulate API calls to the front-end is critical.
that's why I was happy to come up with SAM because I never have any question about how the back-end connects to the front-end.
After that people can use Angular, React, Vue, ES6... I don't have a strong argument from one other the other, except for history. For the last 20 years, people who have picked a framework have all lost the battle over time.
I lost my first company over NeXTStep when it was taken off the market in 1997.
Paolo Furini
@pfurini
Aug 31 2017 17:23
I was hoping that ngrx were more focused on actions, and that could be aligned on SAM principles.. I'm also against frameworks in general, but picking one can be beneficial for onboarding other devs
Jean-Jacques Dubray
@jdubray
Aug 31 2017 17:23
With ES6 I have no danger of JavaScript going away. It's a tiny bit more work say than Angular (though I am not completely sure about that), but nobody can take ES6 away.
The problem is that Redux, NgRx, Elm view actions as a "data structure"
Paolo Furini
@pfurini
Aug 31 2017 17:24
Ah, ok, I see the problem then
Jean-Jacques Dubray
@jdubray
Aug 31 2017 17:24
IMHO (and other people too think the same way), you should always use something like "thunks"
Otherwise you'll start mixing action logic with mutation logic
Since the reducer must be a pure function you can't do API calls in it. That's a big limitation
The programming model is not an innocent choice, it will decide a lot on how your code is structured later on.
I can't say SAM is perfect, but it rarely pushes me in a corner. It's really the opposite, each time I have taken a short cut, I regretted it.
It makes the decision process really simple for any developer. The "buckets" where you put your logic are straightforward.
Paolo Furini
@pfurini
Aug 31 2017 17:30
yes, sometimes when looking at these redux-like libraries, I think: it's only me, or this is artificially complicated
Fred Daoud
@foxdonut
Aug 31 2017 17:33
@jannesiera @pfurini I'm interested in hearing what you think of Meiosis
Paolo Furini
@pfurini
Aug 31 2017 17:34
I'm only a bit worried about new devs onboarding on existing projects.. sometimes I use remote devs, and it's easier to "align" them by saying "you must adopt these and these library/pattern, etc.", but a good documentation like "SAM pattern with Angular 4 - with complete example" should be good as well
Jean-Jacques Dubray
@jdubray
Aug 31 2017 17:36
yes, it's not much overhead, just a coding style for the most part. For instance using SAM inside an Angular component requires no library whatsoever and still brings quite a bit of benefit.
Paolo Furini
@pfurini
Aug 31 2017 17:36
@foxdonut I haven't had the chance to evaluate it, but it looks promising. Have you tried it in ionic 3 projects?
Jean-Jacques Dubray
@jdubray
Aug 31 2017 17:37
then you can have an application level SAM instance for all the API calls. It's really not a good idea to wire these API calls to your Angular components.
Paolo Furini
@pfurini
Aug 31 2017 17:58

Just out of curiosity, I'm trying to grasp something on ngrx. Here is an excerpt from an interesting article (sorry, it's a bit long, but I want your opinion):

On the other hand we are using ngrx/effects. What are they? Effects relate to the term side effects. It‘s a piece of code which needs to be executed after the ngrx action has been invoked. It’s basically a function which returns an observable.

Let’s say we need to perform an async call and change a piece of state with the given response. We would need to trigger an async call somewhere, dispatch an action to indicate loading, wait for the async response to dispatch another action for storing the data and indicate success or error response. All of these actions would end up in our sandbox.

This is where the effects come in place. Effects are used for handling async calls for our actions and chaining other actions when async calls end. This way we don’t need to bother with synchronizing the actions and async calls. To manipulate with application state we should deal with actions only. This way we made an asynchronous action to look more synchronous which is very natural because this is the way our brain works. We will be dispatching an actions from components to communicate with app core and http requests, web socket requests etc. will be firing in the background. The example of effect implementation is shown below:

@Effect()
doLogin$: Observable<Action> = this.actions$
  .ofType(actions.ActionTypes.DO_LOGIN)
  .map((action: actions.DoLoginAction) => action.payload)
  .switchMap(state => {
    return this.authApiClient.login(state)
      .map(user    => new actions.DoLoginSuccessAction(new User(user)))
      .catch(error => of(new actions.DoLoginFailAction()));
  });
The emphasis is put on this sentence: To manipulate with application state we should deal with actions only.
but they at least seem to deal with NAP using that ngrx/effects library
Fred Daoud
@foxdonut
Aug 31 2017 18:05
@pfurini I have not, I don't do much mobile development.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 18:48
@pfurini that's the insanity coming from the fact that the reducer has to be a pure function with no side effects.
so an API call cannot be part of the reducer (since actions are data structures, you can't put it there too)
so when you need to make an API call you need to do is outside the redux/render loop. It's almost like creating a mini-process which deals with it and then calls an action (as a data structure).
What is not shown here is that you have to have some ancillary state machine to keep track of what you are doing. So often you'd be setting model.fetching = true in the reducer.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 18:55
Compare that with SAM where an "action" can make an API call and present the result to the model. The model can also make API calls to create/update/delete records.

This whole insanity comes only from the fact that the core programming model is:

  • actions are data structures
  • reducers are pure functions

no other reason

make actions a pure function and the reducer a method on the model (which can mutate its properties) then you get SAM
Vertex21
@Vertex21
Aug 31 2017 19:03
@jdubray Does SAM only work in the js-backend/js-frontend scenario? Or can I apply the SAM concepts, say, if I wanted to program a GO backend and InfernoJS fontend?
Jean-Jacques Dubray
@jdubray
Aug 31 2017 19:04
It's a pattern, so it can be implemented in any technology, in any context (not just front-end)
@Vertex21 the idea is that each time you write an event-handler, you can use a SAM implementation to structure the code of the event handler.
Vertex21
@Vertex21
Aug 31 2017 19:05
Thank you.. sorry I got caught up reading a bunch of your articles and all the threads after and was thinking you were using just JS for everything
I'm not an amazing programmer by any means so it's taking me some time to wrap my head around everything I'm reading.
Jean-Jacques Dubray
@jdubray
Aug 31 2017 19:07
JS makes it easy to implement SAM (dynamic typing)
Vertex21
@Vertex21
Aug 31 2017 19:14
@jdubray I was just reading to try to understand that statement.. what is it about not having to declare variables that makes it easier to implement?
Jean-Jacques Dubray
@jdubray
Aug 31 2017 19:26
it's not variables, it's types. In JavaScript proposals can be anything you want it to be. It's a lot more work to create classes (Java) to carry all types of proposals.
Vertex21
@Vertex21
Aug 31 2017 19:45
Gotcha! thanks!
Paolo Furini
@pfurini
Aug 31 2017 19:51

This whole insanity comes only from the fact that the core programming model is:

  • actions are data structures
  • reducers are pure functions

ok, so now I understand clearly all that ceremonies.. I find them overly complicated, I prefer simplicity over complexity

it's not variables, it's types. In JavaScript proposals can be anything you want it to be. It's a lot more work to create classes (Java) to carry all types of proposals.

I somewhat agree, but I DO prefer stricter type checking, because lead to more maintainable code in the long term, especially with long-term projects, or bigger teams

Paolo Furini
@pfurini
Aug 31 2017 19:58
I can write literally double the amount of code without errors in Kotlin, or Swift, or C# (not java, really too much overhead) than JS, but that's my personal experience..
Jean-Jacques Dubray
@jdubray
Aug 31 2017 20:03
yes on average that's the amount of code you would need to get the same result done :-)
joke aside, it's ok, everyone is different, I really enjoy Javascript
Paolo Furini
@pfurini
Aug 31 2017 20:04
hehe.. maybe C#, but sometimes I need less code in Kotlin than in JS to do the same thing ;)
Jean-Jacques Dubray
@jdubray
Aug 31 2017 20:04
@pfurini yes, the Redux/Elm constraints are totally artificial
I really enjoy Dynamic Types since I started using Objective-C in 1990
In 1997-1999 I discovered XML and started to think in terms of "extensible data structures"
But XML is anemic, when I combine Javascript and JSON I feel I get something really powerful.
Janne Siera
@jannesiera
Aug 31 2017 20:36
@foxdonut I'm not sure about meiosis. Haven't really looked into it before. I think observables are interesting but I would only introduce them in the code for complex cases where they would really simplify things. Most of the time this doesn't seem to be the case. Also not sure about the advantages and disadvantages of fractal components.
Fred Daoud
@foxdonut
Aug 31 2017 22:27
@jannesiera if you look at the implementation of the pattern, it's not really "observables", just simple streams in one place, the vast majority of application code is just regular objects and functions. As for fractal components, they are achievable, but not necessarily required -- ultimately you decide how you want to structure components. This is what makes Meiosis unique: it's a pattern, not a library/API, and it is very flexible.