[elm-discuss] Re: Best practices for designing models in the Elm Architecture - lean or rich?

2017-07-25 Thread Kasey Speakman
I don't think it matters one way or another. Whatever you end up finding 
easier to maintain.

What I would do is explicitly represent the BMI as its own module, probably 
with an accompanying data type. In the module operations like 
`updateHeight` and `updateWeight`, you could make sure that the calculation 
is getting rerun. Update would call the module instead of directly setting 
individual properties. Then you have this logic encapsulated and 
centralized.

On Monday, July 24, 2017 at 8:23:44 PM UTC-5, Ray Toal wrote:
>
> This might be an opinion-based question so I can't ask it on 
> StackOverflow. :-)
>
> I have a trivial beginnerProgram using the Elm Architecture. It has two 
> text fields (HTML input elements), one for weight and one for height. The 
> onInput attributes of each generate a message. The update function accepts 
> the message and produces the new model.
>
> The question is: Should the model (a) consist of the width and height 
> only, or (b) also include the computed BMI (width / height^2)? If the 
> former, I compute the BMI in the view function; if the latter, I would 
> compute it in the update function.
>
> Does anyone have a lot of experience with Elm applications that would lead 
> them to believe that keeping models as small as possible and computing 
> derived data in the view function is better than making rich models? I 
> don't have enough experience with Elm to know. I sense that for a problem 
> as simple as mine it really doesn't matter (and I in fact got it working 
> both ways), but as I start scaling up my apps it would be nice to know if 
> there is best practice here (or not).
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Systemic problem in Object Oriented languages

2017-07-24 Thread Kasey Speakman

Submit a PR for a documentation change. GL

On Monday, July 24, 2017 at 12:50:12 PM UTC-5, Dave Ford wrote:
>
> A lot of my early work was centered around UIs which made heavy use of 
>> inheritance and mutation.
>>
> I really don't think this is related to the original question. The 
> original question was not about inheritance or mutation or even about OO. 
> It was about "this" and "combining data with logic". Which were described 
> as a "systemic problem".
>
> No one (yet) has convinced me that they are even remotely a problem. No 
> one has provided an example. Or any logic to support the claim.
>
> They have mentioned all sorts of other things that *are* problematic, 
> like inheritance and mutation. But I already knew those were problematic. I 
> also already knew that most OO languages also support mutation (although 
> mutation is discouraged in Kotlin). But this is not what the question was. 
>
> Sure, you could start naming off a dozen other things that are problematic 
> (like inheritance and mutation). But that has nothing to do with the 
> question.
>  
>
>> In OO, mutation is very easy to do because of `this`.
>>
> No. As mentioned earlier, "this" has nothing to do with immutability. 
> "this" is just an object variable like any other object variable.
>
> | Perhaps your experience with OO programming is atypical?
> The fact that "this" has nothing to do with immutability is unrelated to 
> my experience.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Separating model state structure from the view hierarchy

2017-07-24 Thread Kasey Speakman
What you described is something that is common to do in event-sourced 
systems. That is, each view maintains its own state and updates itself in 
response to system events (aka left fold events to state). These are often 
called "denormalizers" because the same data may be copied into multiple 
views to avoid lookups. In this case, the data store would simply be a list 
of all events that have occurred.

I have typically seen this done on the API, not on the UI, because 
persistence is usually involved. But I suppose you could look at Model as 
the resulting state from all UI events (aka Msg). But in Elm the events are 
thrown away (usually ) and 
only the resulting state remains.

You could make the Model just be a list of events -- `type alias Model = 
List Msg` -- instead of expressing a particular state. Then you can left 
fold events into whatever state you wanted. However, the longer the program 
operates, the more events accumulate. At some point there will be too many 
events to process in a reasonable time (or keep in memory). So to use an 
accounting term, you will have to "close out" some number of old events. 
That is, calculate the states based on them, and use those states as the 
starting point for further processing. Then discard old events to save 
space.

I don't know your problem domain, so I could not advise if this is an 
appropriate solution... just an idea. Again, typically something seen on 
the server-side. So not sure of other technical constraints you might face 
in JS.

On Friday, July 21, 2017 at 8:55:42 AM UTC-5, ajs wrote:
>
> I had an interesting discussion with several members on the #beginners 
> channel on Slack. It was suggested I post this out to the larger community 
> for input.
>
> As a quick background, I'm a professional Clojurescript developer for many 
> years, and have been through the early days of React (when it was just 
> wrapped as Om in Clojurescript), and then Reagent, and then the most 
> versatile and structured tool, Re-Frame, which has emerged as a leading 
> model of UI <-> Model interaction. I am now looking seriously at Elm on my 
> company's behalf and we are testing a prototype for a component in it.
>
> The Elm Architecture is often compared to Redux and Re-Frame. The overall 
> flow is similar, however there is a particular problem that plagued 
> Clojurescript's Om in the early days that was eventually worked out in 
> Re-Frame and in later versions of Om. This problem, however, does not 
> appear to have a solution in Elm, and I wish to outline it here. It is a 
> common problem that occurs in modelling a UI in a complex SPA, anything 
> truly non-trivial.
>
> The way the Elm Architecture works, and in the early Om, is that you have 
> a single piece of state that acts as the truth for your app, and then you 
> have view functions that receive parts of this state (or all of it), and 
> then they call children view functions and pass along parts of the state 
> they received. I have 2 Elm examples below, in a moment.
>
> The fundamental problem with this approach is that it creates a tight 
> coupling between the organization of your model data and that of your view 
> hierarachy. What the Om users realized is that a robust model should not 
> depend on the views for its structure. But the Elm Architecture kind of 
> requires that (as far as I can tell). Data models should not be structured 
> based on what works for a user interface; they need to honor the 
> requirements of the data, only. 
>
> A very large and prominent Om-based user-interface is that which CircleCI 
> uses. They wrote about this issue here:
>
> (skip to the heading "The Conundrum Of Cursors: Most Data Is Not A Tree.")
>  https://circleci.com/blog/why-we-use-om-and-why-were-excited-for-om-next/
>
> If the model does not fit the needs of the view hierarchy, then what 
> emerged in the old Om was the unfortunate side effect of passing the entire 
> model state through all view functions. I hear that this is not uncommon in 
> Elm as well.
>
> It has plagued many companies (including mine), which eventually led to a 
> much better way of data interacting with a UI in Re-Frame, which I will 
> summarize in a moment.
>
> The problem arises when a view child needs data in the central model that 
> its parent did not need or receive. The parents and ancestors should not 
> require awareness of specific model details that a distant child might 
> need. For example, a view function might have the job of displaying Screen 
> A or Screen B. It is passed a flag, perhaps, that tells it which screen to 
> build, and then it calls a view function for that screen. Simple as that; 
> it doesn't need to know that Screen B has a widget that contains a dropdown 
> menu that must show a list of items from somewhere in the central model, 
> and that it must also find and pass that list to the screen view function.  
>
> The other problem that 

[elm-discuss] Re: Systemic problem in Object Oriented languages

2017-07-24 Thread Kasey Speakman
Perhaps your experience with OO programming is atypical?

A lot of my early work was centered around UIs which made heavy use of 
inheritance and mutation. Being a novice, my own work followed this pattern 
too. A lot of UIs still work this way. React has to explicitly spell out 

 
for you not to modify state directly.

In OO, mutation is very easy to do because of `this`. Even when you know 
better it requires a lot of discipline to do what you "should" do rather 
than what is easy. Kudos on you for having that, but it is certainly not a 
universal.

On Thursday, July 20, 2017 at 2:55:54 AM UTC-5, Dave Ford wrote:
>
> There is a line from the docs that I am trying to understand: "Elm 
> encourages a strict separation of data and logic, and the ability to say 
> this is primarily used to break this separation. This is a systemic 
> problem in Object Oriented languages that Elm is purposely avoiding."
>
> What is the systemic problem being reference? Is it the [lack of] "separation 
> of data and logic" or "the ability to say this"?
>
> I have been programming in Java (an OO language) for a long time. I can 
> name dozens of systemic problems in the language. But the ability to say 
> "this" is not one of them. Nor is it the commingling of data and logic. 
>
> Please help me to understand what the author is talking about.
>
> Thanks.
>
> Side note: "this" *is* a problem in JavaScript. But not in OO generally.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Text box value displays inconsistently

2017-06-26 Thread Kasey Speakman
In addition to the other answers, I also spotted one other "gotcha" in your 
example you may want to be aware of.

Your checkbox does not render the "checked" attribute. Your browser tracks 
values for HTML form elements separately from Elm. Form values typically 
get overwritten with Elm values when the view is rendered. But in this 
case, nothing from Elm is setting whether the element should be checked. 
Try starting with `on = True` and the checkbox initially renders unchecked 
still.

On Thursday, June 22, 2017 at 6:42:19 PM UTC-5, Paul Freeman wrote:
>
> This is the first time I've posted to the community. I chose this group 
> over Slack or Reddit, so please nudge me if this problem would be better 
> suited in one of the other communities.
>
> Basically, I'm noticing an inconsistency in the text value displayed in 
> one of my text boxes. It is based on the type in the text box that follows 
> it. I've got it down to the simplest example I could find, which 
> demonstrates the error on http://elm-lang.org/try
>
> Here is the code:
>
> import Html exposing (Html, p, div, text, input, beginnerProgram)
> import Html.Attributes exposing (type_, value)
> import Html.Events exposing (onClick)
>
> main =
> beginnerProgram { model = { on = False }, view = view, update = update 
> }
>
>
> type alias Model =
> { on : Bool }
> 
> 
> type Msg
> = Toggle
>
>
> update msg model =
> { model | on = not model.on }
>
>
> view : Model -> Html Msg
> view model =
> div [] <| p [] [ text "On: ", input [ type_ "checkbox", onClick Toggle 
> ] []]
> :: (if model.on then
> [ p [] [ text "Foo: ", input [ value "foo" ] [] ] ]
> else
> []
>)
> ++ [ p [] [ text "Bar: ", input [ value "10.0"{-, type_ "number"-} 
> ] [] ] ]
>
>
> If the code is executed as shown, you will see a checkbox. When the box is 
> checked, a new input box appears and has the default value "foo" inside 
> it. But, if you include the commented code (in red), then the default value 
> "foo" is not shown when the box is checked. This is very odd since the 
> commented code is for a completely different text box.
>
> I'm happy to use a workaround, if anyone knows one, but so far I haven't 
> come across anything. Any thoughts are welcome.
>
> Thanks!
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Attributes not getting removed

2017-05-10 Thread Kasey Speakman
Saw that issue, almost commented. Using attribute is best work-around so 
far.

On Wednesday, May 10, 2017 at 2:40:07 AM UTC-5, Gusztáv Szikszai wrote:
>
> Already reported https://github.com/elm-lang/html/issues/124. My advice 
> would be to use `attribute "download" "value"` and it will be removed if 
> omitted.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Attributes not getting removed

2017-05-09 Thread Kasey Speakman
Ah yes, that's another good workaround.

It's definitely not rendering as I would expect. Probably a performance 
optimization that's gone awry.

I also tried download False, but that renders download="false". Which also 
triggers a download (!) instead of opening normally, so the Elm's download 
API must be askew.

On Tuesday, May 9, 2017 at 3:28:04 PM UTC-5, Witold Szczerba wrote:
>
> This is surprising… Looks like DOM↔VDOM diff does not remove missing (but 
> attached once) attributes? Or it ignores them because it does not want to 
> be too invasive?
>
> As a other workaround, you can have always two amchor tags: one with 
> "target", one without, and just switch the visibility of them (the 
> "onClick" could be attached to the wrapping span, or both can have same 
> one).
>
> Regards,
> Witold Szczerba
>
> On Tue, May 9, 2017 at 10:00 PM, Kasey Speakman <kjspe...@gmail.com 
> > wrote:
>
>> Hi, maybe someone has run into this.
>>
>> I'm noticing that download and target attributes are not getting removed 
>> from links even though subsequent renders are omitting them.
>>
>> Using this test code on http://elm-lang.org/try:
>>
>> import Html exposing (a, text, beginnerProgram)
>> import Html.Events exposing (onClick)
>> import Html.Attributes exposing (target, download)
>>
>> main =
>>   beginnerProgram { model = False, view = view, update = update }
>>
>> view model =
>>   a
>> [ onClick Toggle
>> , if model then
>> target "_blank"
>>   else
>> download True
>> ]
>> [ text "click" ]
>>
>> type Msg =
>>   Toggle
>>
>> update msg model =
>>   case msg of
>> Toggle ->
>>   not model
>>
>>
>> The initial view renders download="true".
>>
>> First click renders download="null" target="_blank". In Chrome at least, 
>> blank target is ignored and file is downloaded anyway simply for the 
>> presence of download attribute.
>>
>> Second click renders download="true" target.
>>
>> I thought omitting the attribute would result in it being absent in the 
>> rendered HTML, but not so.
>>
>> *Well, after I typed this out...*
>>
>> I found two work-around.
>>
>> 1) Wrap in a different parent element for each. For example, use div for 
>> one and span for the other.
>> 2) Using Html.Keyed.node to put an identity on each.
>>
>> Kasey
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Attributes not getting removed

2017-05-09 Thread Kasey Speakman
Hi, maybe someone has run into this.

I'm noticing that download and target attributes are not getting removed 
from links even though subsequent renders are omitting them.

Using this test code on http://elm-lang.org/try:

import Html exposing (a, text, beginnerProgram)
import Html.Events exposing (onClick)
import Html.Attributes exposing (target, download)

main =
  beginnerProgram { model = False, view = view, update = update }

view model =
  a
[ onClick Toggle
, if model then
target "_blank"
  else
download True
]
[ text "click" ]

type Msg =
  Toggle

update msg model =
  case msg of
Toggle ->
  not model


The initial view renders download="true".

First click renders download="null" target="_blank". In Chrome at least, 
blank target is ignored and file is downloaded anyway simply for the 
presence of download attribute.

Second click renders download="true" target.

I thought omitting the attribute would result in it being absent in the 
rendered HTML, but not so.

*Well, after I typed this out...*

I found two work-around.

1) Wrap in a different parent element for each. For example, use div for 
one and span for the other.
2) Using Html.Keyed.node to put an identity on each.

Kasey

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: File Uploads - as simple as I could manage

2017-05-08 Thread Kasey Speakman
That was one of the first things I found. I'm uploading to S3 too. But the 
API was a bit larger than I wanted to take on for my meager needs. Props to 
simonh1000 for leading the way.

On Sunday, May 7, 2017 at 8:25:23 AM UTC-5, Erik Lott wrote:
>
> You may want to see "file-reader" if you haven't seen it already:
> https://github.com/simonh1000/file-reader 
> 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] File Uploads - as simple as I could manage

2017-05-06 Thread Kasey Speakman
I don't think there are new native packages being approved. In fact, I 
think more are to get cut soon. We will just have to wait on Evan to put a 
File type into Elm and a Body type for it in the Http module (or something 
like that).

On Saturday, May 6, 2017 at 7:40:33 PM UTC-5, Witold Szczerba wrote:
>
> You are right, it wouldn't work as I've thought. Native done right is OK, 
> but the problem is someone has to "approve" the project or it won't be 
> available to others by Elm package. I wonder if it's actually doable. 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] File Uploads - as simple as I could manage

2017-05-06 Thread Kasey Speakman
Err, I should say I made a trade toward ease at the potential cost of 
safety by doing native instead of ports. I might make a different choice if 
the JS code were more complicated.

On Saturday, May 6, 2017 at 5:26:39 PM UTC-5, Kasey Speakman wrote:
>
> I believe you can use ports without native code to pass the event 
> reference as Value to JS and call the FileReader API, returning file as 
> String back to Elm. But that was more convoluted than I wanted to deal with.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] File Uploads - as simple as I could manage

2017-05-06 Thread Kasey Speakman
I believe you can use ports without native code to pass the event reference 
as Value to JS and call the FileReader API, returning file as String back 
to Elm. But that was more convoluted than I wanted to deal with.

On Saturday, May 6, 2017 at 5:12:23 PM UTC-5, Kasey Speakman wrote:
>
> I tried using both:
>
> import Json.Decode as Json
>
> -- the first JS File
> Json.at [ "target", "files" ] (Json.index 0 Json.value)
>
> -- the JS FileList
> Json.at [ "target", "files" ] Json.value
>
> Both of which came back as undefined after decoding. Maybe I was doing 
> something else wrong?
>
> Even one of these came through as Value, you can't do anything with it in 
> Elm. The Http module has no mechanism to send Value, only Strings 
> (multi-part also takes only Strings). For security reasons, the only way to 
> access the JS File contents (AFAIK) is through another JS API like XHR (to 
> send) or FileReader (to read the contents). There has to be some native 
> code involved to either get the contents or convert the file reference to 
> something that Elm can use.
>
> On Saturday, May 6, 2017 at 2:45:29 PM UTC-5, Witold Szczerba wrote:
>>
>> > I did actually try using decoders first to pull in the 
>> "e.target.files" property as a Value, but Elm just fails to decode it.
>>
>> How did you try to decode the "files"? There is a special function:
>> value -> Decoder Value
>> it does leave the structure "as is". I was wandering if it could work? 
>> The original "files" could be then assigned to the body, so Elm would not 
>> touch it at all. Would it possibly work?
>>
>> Regards,
>> Witold Szczerba
>>
>> 05.05.2017 7:32 PM "Kasey Speakman" <kjspe...@gmail.com> napisał(a):
>>
>>> After a bit of research on file uploads, I pared it down to the simplest 
>>> method I could find. Here is the recipe I came up with.
>>>
>>> https://gist.github.com/kspeakman/20708d5ff58b6ea75f9c3a82f6c793c3
>>>
>>> The FileUtils module essentially wraps the JS File object in Http.Body 
>>> as well as exposing common file info (name, size, contentType). Using 
>>> Http.Body makes it quite easy to send files with normal Http calls. 
>>> Unfortunately this does use native/kernel code, but this made it far easier 
>>> to work with in Elm than if I used ports. I did actually try using decoders 
>>> first to pull in the "e.target.files" property as a Value, but Elm just 
>>> fails to decode it.
>>>
>>> I also thought something like this could be a path forward to introduce 
>>> basic file uploads into Elm's core. It is not a general solution for all 
>>> binary formats. But it is a straightforward way to handle File objects from 
>>> JS.
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Elm Discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to elm-discuss...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] File Uploads - as simple as I could manage

2017-05-06 Thread Kasey Speakman
I tried using both:

import Json.Decode as Json

-- the first JS File
Json.at [ "target", "files" ] (Json.index 0 Json.value)

-- the JS FileList
Json.at [ "target", "files" ] Json.value

Both of which came back as undefined after decoding. Maybe I was doing 
something else wrong?

Even one of these came through as Value, you can't do anything with it in 
Elm. The Http module has no mechanism to send Value, only Strings 
(multi-part also takes only Strings). For security reasons, the only way to 
access the JS File contents (AFAIK) is through another JS API like XHR (to 
send) or FileReader (to read the contents). There has to be some native 
code involved to either get the contents or convert the file reference to 
something that Elm can use.

On Saturday, May 6, 2017 at 2:45:29 PM UTC-5, Witold Szczerba wrote:
>
> > I did actually try using decoders first to pull in the "e.target.files" 
> property as a Value, but Elm just fails to decode it.
>
> How did you try to decode the "files"? There is a special function:
> value -> Decoder Value
> it does leave the structure "as is". I was wandering if it could work? The 
> original "files" could be then assigned to the body, so Elm would not touch 
> it at all. Would it possibly work?
>
> Regards,
> Witold Szczerba
>
> 05.05.2017 7:32 PM "Kasey Speakman" <kjspe...@gmail.com > 
> napisał(a):
>
>> After a bit of research on file uploads, I pared it down to the simplest 
>> method I could find. Here is the recipe I came up with.
>>
>> https://gist.github.com/kspeakman/20708d5ff58b6ea75f9c3a82f6c793c3
>>
>> The FileUtils module essentially wraps the JS File object in Http.Body as 
>> well as exposing common file info (name, size, contentType). Using 
>> Http.Body makes it quite easy to send files with normal Http calls. 
>> Unfortunately this does use native/kernel code, but this made it far easier 
>> to work with in Elm than if I used ports. I did actually try using decoders 
>> first to pull in the "e.target.files" property as a Value, but Elm just 
>> fails to decode it.
>>
>> I also thought something like this could be a path forward to introduce 
>> basic file uploads into Elm's core. It is not a general solution for all 
>> binary formats. But it is a straightforward way to handle File objects from 
>> JS.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: List of all members of a union type

2017-05-06 Thread Kasey Speakman
Going back to the original question, why couldn't you use a list of records 
instead of a union type? Every time I dealt with states, I ended up needing 
more than just the name and ended up putting it in a database, which more 
naturally maps to a record.

type alias UsState =
{ name : String
, code : String
, licenseFormat : String
}

With the usage you describe so far, records seem a better fit. Unions are 
more valuable when you need to structure to code against rather than data.

You could still pick out specific states for special rules using something 
like:

states
|> List.filter (\state -> state.code == "AL")
|> List.head

HTH

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Collecting use cases for File, ArrayBuffer and TypedArrays/DataViews

2017-05-05 Thread Kasey Speakman
*Uploading files to AWS S3*

That's my only use case so far for binary-type APIs of JS. I first call my 
own API to get a signed upload link, then PUT a file at that link. My 
simple way to upload files using Elm's Http module can be found here 
.

I'm also delivering streaming media to the browser, but I'm doing that 
through existing JS libraries in an iframe.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] File Uploads - as simple as I could manage

2017-05-05 Thread Kasey Speakman
After a bit of research on file uploads, I pared it down to the simplest 
method I could find. Here is the recipe I came up with.

https://gist.github.com/kspeakman/20708d5ff58b6ea75f9c3a82f6c793c3

The FileUtils module essentially wraps the JS File object in Http.Body as 
well as exposing common file info (name, size, contentType). Using 
Http.Body makes it quite easy to send files with normal Http calls. 
Unfortunately this does use native/kernel code, but this made it far easier 
to work with in Elm than if I used ports. I did actually try using decoders 
first to pull in the "e.target.files" property as a Value, but Elm just 
fails to decode it.

I also thought something like this could be a path forward to introduce 
basic file uploads into Elm's core. It is not a general solution for all 
binary formats. But it is a straightforward way to handle File objects from 
JS.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Discovery: Model /= Database

2017-04-19 Thread Kasey Speakman
I'm probably slow, but in recent months I've discovered that trying to use 
Elm's Model like a database or cache (as I have previously seen suggested) 
has turned out to be pretty painful for me. An example database-minded 
model where a section could display *either* a list of employees *or* a 
list of courses.

type alias Model =
{ employees : List Employee
, courses : List Course
, loadingError : Maybe Http.Error
, route : MyRoute -- employee or course
}

The problem this runs into is having to worry about state management. I 
have to remember to "reset" or "turn off" things when they are not active. 
As my application grew, I had a lot of problems that boiled down to tedious 
state management details. My cached data didn't turn out to be all that 
useful because I usually had to reload it anyway, in case something changed.

Instead, I have been moving toward the model only representing the current 
state of my UI. The big difference here is the model representing the 
current *visual* elements and their data. This leads more to using union 
types to represent parts of the UI. When you switch to a different case of 
the union type, the data from the previous case is *dropped on the floor*. 
This leaves nothing to remember to "reset". RemoteData is a good 
micro-example of this. If there was an error fetching the data, when the 
user requests the data again, you switch back to Loading, the error message 
is dropped on the floor. No forgetting to hide it.

type RemoteData e a
= NotAsked
| Loading
| Failure e
| Success a

If it is really important to cache the data, I prefer to keep that as a 
persistence concern, not on Model. It can be part of the process for 
retrieving the data to first check my chosen cache before making a request 
for fresh data. For instance, first check local storage before making an 
HTTP call. (Currently, this scenario is easier with Native modules for lack 
of Local Storage API or being able to wait on port subscriptions. But it's 
still doable.)

So working towards a Model reflecting the visuals on the page has been an 
interesting challenge. I'm not claiming it's easier, but so far I've found 
it avoids a class of problems, and has led to some interesting discoveries 
in my own apps. One small example: I realized that my LoggedIn and 
NotLoggedIn routes should actually be separate "apps". Attempts to model 
this in a SPA fashion with the LoggedIn and NotLoggedIn routes as siblings 
always came up with the conundrum: how do I make it a compiler error for 
the model to be in LoggedIn mode but I receive a NotLoggedIn message, or 
vice versa? Even using TEA, I could not avoid this situation. Then I 
realized the only way to do that would be as separate apps. And that it was 
entirely possible to separate them. My "login page" turned out to be an 
entirely self-contained process: the user filling in info, obtaining a 
token, and saving it to local storage.

I post this in the slim hope it is helpful to someone.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Notify me when JWT expires

2017-04-12 Thread Kasey Speakman
I made this module yesterday to notify me when a JWT bearer token expires. 
Thought I would share in case anyone found useful, maybe make a package 
later.

https://gist.github.com/kspeakman/bd13d5b922a6abfcbb480a907161030c

Basic usage (ignoring JWT parse errors) is:

jwtString
|> Jwt.onExpired Logout
|> Result.withDefault Cmd.none

This should be run one time. I run either on program init (jwt loaded from 
local storage and passed in through flags) or when token is received on 
login. When the expiration time comes, it will send back whatever message 
you specify (e.g. Logout).

Our use cases currently don't have users repeatedly logging in/out or 
swapping logins, so I'm not dealing with canceling the expiration 
notification. If I needed to deal with this for now, I would probably just 
refresh the page on logout to kill the sleeping process (which is just 
Javascript's `setTimeout`). Or ignore notifications from old tokens (match 
token signature?).

I used a couple of internal functions from elm-jwt 
 for converting JWT back to proper 
Base64.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Compiler option to disable camel-case record property requirement?

2017-03-29 Thread Kasey Speakman
Short of language changes, you could:

* Use the infamous encoders/decoders to emit/parse pascal case.
* Use a header on the HTTP request to instruct the server to assume camel 
case for the request.

Without pre-existing clients, I have the server emit camelCase (a 
serializer configuration option). In a happy surprise, deserialization was 
already case-insensitive (in JSON.NET) so I didn't have any trouble using 
my pascal case objects there.

On Wednesday, March 29, 2017 at 10:41:36 AM UTC-5, Stein Setvik wrote:
>
> Would you consider adding an option for users to disable the camel-case 
> requirement for record properties in the compiler?
>
> Our use case:
> We have a large legacy system we'd like to bring Elm into that uses pascal 
> case throughout (all database fields and all places they're referenced in 
> the backend and frontend).
>
> We are planning on updating to camel case; however, it will be a 
> complicated change and is ~9 months out.
>
> We'd like to look at Elm before then, but the camel case requirement is 
> creating a performance hit because we have to clone all objects and rename 
> all pascal cased properties before shipping them over ports to Elm.
>
> Example:
> We migrated a results view for realtime search (Algolia) in a product 
> catalog. The result view updates in real-time with every keystroke, and the 
> JS transformation of the data before sending it to Elm is weighty enough to 
> delay and slow the rendering of the results in a noticeable way.
>
> Thoughts?
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: 'Native' -> 'Kernel': a msgpack example

2017-03-27 Thread Kasey Speakman

>
> But compared to other compile-to-js languages, Elm is seemingly the one 
> that puts the most the hurdles ahead of easily using the libraries 
> available in the world's most popular language.


You are correct. Elm is harder to interop than most other compile-to-js 
platforms. That's because Elm tries to guarantee that all user code is pure 
(as in pure functions). This makes Elm apps continue to be evolvable and 
refactorable despite adding new features. Using native code throws away 
Elm's guarantees, so it is discouraged. Using ports (the blessed way to 
interop) maintains the guarantees at the border, but it has trade-offs as 
you've noted in the original post.

Unfortunately, interop is a hard problem to solve while keeping Elm's 
benefits intact. WIP.

On Sunday, March 26, 2017 at 2:57:11 PM UTC-5, Simon wrote:
>
> Ok, I hope that this is just a naming change, but spent too much time in 
> politics not to fixate on choice of language issues!
> But compared to other compile-to-js languages, Elm is seemingly the one 
> that puts the most the hurdles ahead of easily using the libraries 
> available in the world's most popular language.
>
>
>
> On Saturday, 25 March 2017 02:52:20 UTC+1, Kasey Speakman wrote:
>>
>> Yeah, I regretted posting that 2nd half. I don't use any native modules 
>> myself except the one to return decoders out of ports. And I was getting by 
>> without it via ports, although somewhat less optimally. Maybe some people 
>> really need native stuff, though. I haven't. (And I'm willing to monkey 
>> patch what I use native for now if need be.)
>>
>> On Friday, March 24, 2017 at 1:48:01 PM UTC-5, Kasey Speakman wrote:
>>>
>>> Indeed, the post mentions renaming Native to Elm.Kernel and ending the 
>>> native module whitelist (sortof). Expectation management.
>>>
>>> User native module blocking was not mentioned. In our current Javascript 
>>> ecosystem such a thing would make Elm non-viable.
>>>
>>> Well, except that repo-forking and monkey-patching exist.
>>>
>>> On Friday, March 24, 2017 at 6:42:34 AM UTC-5, Rupert Smith wrote:
>>>>
>>>> On Thursday, March 23, 2017 at 8:15:51 PM UTC, Simon wrote:
>>>>>
>>>>> It's pretty clear that these practices are frowned upon, but the shift 
>>>>> to 'kernel' sounds like a plan to squeeze the pragmatic programmer's 
>>>>> options further. I hope that's not the case.
>>>>>
>>>>
>>>> I think all that is happening is that Native is being renamed to Kernel 
>>>> to reduce confusion. At the moment when we say 'Elm' and 'native' in the 
>>>> same sentence we could mean an Elm Native module used to implement its 
>>>> kernel, or native javascript code through ports.
>>>>
>>>> I can't be certain of the details but I think your function would just 
>>>> be re-written as:
>>>>
>>>> var _user$project$Kernel_Msgpack = function() { ... }
>>>>
>>>> But you won't be able to publish it officially and will have to use 
>>>> elm-github-install.
>>>>
>>>> It makes sense to me anyway, the 'kernel' needs to be carefully managed 
>>>> as the language takes shape.
>>>>
>>>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: 'Native' -> 'Kernel': a msgpack example

2017-03-24 Thread Kasey Speakman
Yeah, I regretted posting that 2nd half. I don't use any native modules 
myself except the one to return decoders out of ports. And I was getting by 
without it via ports, although somewhat less optimally. Maybe some people 
really need native stuff, though. I haven't. (And I'm willing to monkey 
patch what I use native for now if need be.)

On Friday, March 24, 2017 at 1:48:01 PM UTC-5, Kasey Speakman wrote:
>
> Indeed, the post mentions renaming Native to Elm.Kernel and ending the 
> native module whitelist (sortof). Expectation management.
>
> User native module blocking was not mentioned. In our current Javascript 
> ecosystem such a thing would make Elm non-viable.
>
> Well, except that repo-forking and monkey-patching exist.
>
> On Friday, March 24, 2017 at 6:42:34 AM UTC-5, Rupert Smith wrote:
>>
>> On Thursday, March 23, 2017 at 8:15:51 PM UTC, Simon wrote:
>>>
>>> It's pretty clear that these practices are frowned upon, but the shift 
>>> to 'kernel' sounds like a plan to squeeze the pragmatic programmer's 
>>> options further. I hope that's not the case.
>>>
>>
>> I think all that is happening is that Native is being renamed to Kernel 
>> to reduce confusion. At the moment when we say 'Elm' and 'native' in the 
>> same sentence we could mean an Elm Native module used to implement its 
>> kernel, or native javascript code through ports.
>>
>> I can't be certain of the details but I think your function would just be 
>> re-written as:
>>
>> var _user$project$Kernel_Msgpack = function() { ... }
>>
>> But you won't be able to publish it officially and will have to use 
>> elm-github-install.
>>
>> It makes sense to me anyway, the 'kernel' needs to be carefully managed 
>> as the language takes shape.
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: 'Native' -> 'Kernel': a msgpack example

2017-03-24 Thread Kasey Speakman
Indeed, the post mentions renaming Native to Elm.Kernel and ending the 
native module whitelist (sortof). Expectation management.

User native module blocking was not mentioned. In our current Javascript 
ecosystem such a thing would make Elm non-viable.

Well, except that repo-forking and monkey-patching exist.

On Friday, March 24, 2017 at 6:42:34 AM UTC-5, Rupert Smith wrote:
>
> On Thursday, March 23, 2017 at 8:15:51 PM UTC, Simon wrote:
>>
>> It's pretty clear that these practices are frowned upon, but the shift to 
>> 'kernel' sounds like a plan to squeeze the pragmatic programmer's options 
>> further. I hope that's not the case.
>>
>
> I think all that is happening is that Native is being renamed to Kernel to 
> reduce confusion. At the moment when we say 'Elm' and 'native' in the same 
> sentence we could mean an Elm Native module used to implement its kernel, 
> or native javascript code through ports.
>
> I can't be certain of the details but I think your function would just be 
> re-written as:
>
> var _user$project$Kernel_Msgpack = function() { ... }
>
> But you won't be able to publish it officially and will have to use 
> elm-github-install.
>
> It makes sense to me anyway, the 'kernel' needs to be carefully managed as 
> the language takes shape.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Is a decoder the right level of abstraction for parsing JSON?

2017-03-18 Thread Kasey Speakman
Yes, but it requires me to keep decoder/encoder files, and fiddle with them
every time my types change. What a waste of time.

Using this method, I don't have to do anything extra when types change. Nor
keep extra files.

On Sat, Mar 18, 2017 at 11:43 AM Noah Hall <enali...@gmail.com> wrote:

> Http://json2elm.com. auto generating json "codecs" (decoders and
> encoders) has existed for more than a year already.
>
> On Friday, March 17, 2017, Kasey Speakman <kjspeak...@gmail.com> wrote:
>
> Another update. I figured out how to get the encoders and decoders out of
> the ports using a native module. So I no longer have to actually send
> things across ports (still have to declare them). I can also now use Elm's
> Http module.
>
> Here's a gist of what it takes:
>
> https://gist.github.com/kspeakman/3f9521b0921b352c7d656261ec0a8fa6
>
> On Saturday, February 18, 2017 at 2:22:32 AM UTC-6, Kasey Speakman wrote:
>
> An update. I'm using the ports approach to deal with JSON (and also
> sending the HTTP request). For several months, I've had a small but
> critical app in production using that. Another project in development is
> too. In the process, I have run across two additional caveats with this
> approach.
>
>1. *Ports don't convert undefined properties to Maybe.Nothing.* It's
>an open issue from Jan 2016.
><https://github.com/elm-lang/core/issues/476>
>For a Maybe property, the JSON must have the property present and set
>to null. Otherwise error. This is particularly annoying when you store the
>data as JSON and pass it back to the client as-is. To work around this
>issue, I either have to waste space storing nulls in the database or waste
>(CPU/response) time server-side to inject nulls in the response.
>
>2. *Cmd.map can't be used with this method.*
>Using Http module, you can use Cmd.map to take some data from the
>request and give it to the response Msg. Using ports, you can't do that.
>I've noticed this when the data is easy to provide for a request, but after
>the response comes back it is less convenient to dig out of the model (e.g.
>behind a case statement).
>
> Neither of these are blockers for me, just nuisance issues. It still beats
> maintaining codecs.
>
> I've seen rumblings about tools for code-gen'ing JSON codecs for us (maybe
> elm-format? <https://github.com/avh4/elm-format/issues/194> There also
> exists elm-swagger, but I don't use swagger.). I dunno though. Where
> possible, I tend to avoid code-gen because it's for handling a really
> tedious problem. And if the code-gen fails, then I have to handle a really
> tedious problem. (XSD/WSDL flashbacks.)
>
> All it would really take for a profound QoL improvement are a couple of
> "special" functions on Http that handle data exactly like ports do now...
> just saying.
>
> --
>
> You received this message because you are subscribed to the Google Groups
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elm-discuss+unsubscr...@googlegroups.com.
>
>
> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Elm Discuss" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/elm-discuss/XW-SRfbzQ94/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> elm-discuss+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Is a decoder the right level of abstraction for parsing JSON?

2017-03-17 Thread Kasey Speakman
Another update. I figured out how to get the encoders and decoders out of 
the ports using a native module. So I no longer have to actually send 
things across ports (still have to declare them). I can also now use Elm's 
Http module.

Here's a gist of what it takes:

https://gist.github.com/kspeakman/3f9521b0921b352c7d656261ec0a8fa6

On Saturday, February 18, 2017 at 2:22:32 AM UTC-6, Kasey Speakman wrote:
>
> An update. I'm using the ports approach to deal with JSON (and also 
> sending the HTTP request). For several months, I've had a small but 
> critical app in production using that. Another project in development is 
> too. In the process, I have run across two additional caveats with this 
> approach.
>
>1. *Ports don't convert undefined properties to Maybe.Nothing.* It's 
>an open issue from Jan 2016. 
><https://github.com/elm-lang/core/issues/476>
>For a Maybe property, the JSON must have the property present and set 
>to null. Otherwise error. This is particularly annoying when you store the 
>data as JSON and pass it back to the client as-is. To work around this 
>issue, I either have to waste space storing nulls in the database or waste 
>(CPU/response) time server-side to inject nulls in the response.
>
>2. *Cmd.map can't be used with this method.*
>Using Http module, you can use Cmd.map to take some data from the 
>request and give it to the response Msg. Using ports, you can't do that. 
>I've noticed this when the data is easy to provide for a request, but 
> after 
>the response comes back it is less convenient to dig out of the model 
> (e.g. 
>behind a case statement).
>
> Neither of these are blockers for me, just nuisance issues. It still beats 
> maintaining codecs.
>
> I've seen rumblings about tools for code-gen'ing JSON codecs for us (maybe 
> elm-format? <https://github.com/avh4/elm-format/issues/194> There also 
> exists elm-swagger, but I don't use swagger.). I dunno though. Where 
> possible, I tend to avoid code-gen because it's for handling a really 
> tedious problem. And if the code-gen fails, then I have to handle a really 
> tedious problem. (XSD/WSDL flashbacks.)
>
> All it would really take for a profound QoL improvement are a couple of 
> "special" functions on Http that handle data exactly like ports do now... 
> just saying.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Unsafe mechanism

2017-03-14 Thread Kasey Speakman
Seems like mostly semantics, but ok I'll take your criticisms.

However, I didn't realize that Http had `toTask`. Thanks for letting me 
know that. :)

I'm still not using Http because I'm not wasting my time maintaining 
encoders/decoders. And since I have to go out to a port, I'm just using a 
fetch polyfill while there to perform the request.

On Monday, March 13, 2017 at 4:07:14 PM UTC-5, Zinggi wrote:
>
> Sorry, but there were many wrong / half truths in here, so I had to 
> respond ;)
>
> Elm does not allow user code to do side effects
>>
> This is wrong, that's what Task and ultimately Cmd are for. It's true that 
> there is no way to do *uncontrolled* side effects, e.g. a function that 
> sends an https request without having type Task/Cmd.
>
> In Haskell, a function with side-effects is marked as "unsafe" if it 
>> declares IO in it's signature
>>
> That's wrong. Functions returning IO are not unsafe, they are equivalent 
> to elms Task. They represent, just as in elm, a description of a 
> *controlled* side effect.
> Haskell can do IO in an unsafe way (by using unsafePerformIO :: IO a -> a), 
> but then the function no longer returns something of type IO.
> (unsafePerformIO should only be used in very rare, extraordinary 
> circumstances)
>
> There's no `Cmd.andThen` to chain together commands
>>
> Thats true, but there is Task.andThen. The Http library has a toTask 
> method for chaining. Most other libraries that perform side effects should 
> also have a way to use them as a Task
>
>
> I agree with point 2, decoders/encoders are a bit tedious.
> But it's not too bad, you can even generate them automatically: 
> https://eeue56.github.io/json-to-elm/
>
> Back to the topic: I'd also be in favor of the task based Javascript inter 
> op proposal.
> This could simplify scenarios like these quite a bit.
>
> On Monday, 13 March 2017 18:11:15 UTC+1, Kasey Speakman wrote:
>>
>> The landscape as I see it: Elm does not allow user code to do side 
>> effects (i.e. communication/IO). In Haskell, a function with side-effects 
>> is marked as "unsafe" if it declares IO in it's signature e.g. 
>> `readFileText: string -> IO string`. Since front-end IO is somewhat narrow 
>> in what is allowed, instead of marking this with IO, Elm provides "safe" 
>> wrappers to do the most common forms of front-end communication (i.e. 
>> HTTP). Most of the libraries mentioned expose an HTTP API.
>>
>> The problem then is that Elm's HTTP library is not quite up to par. The 
>> two largest problems I see right now:
>>
>> 1) There's no `Cmd.andThen` to chain together commands, so you can't 
>> package up multiple calls as one operation on the client side. This forces 
>> libraries to leak implementation details to the caller (e.g. pushing the 
>> in-between-calls state management to host application) and therefore makes 
>> them tedious to work with. I try not to design APIs where clients should 
>> need to make multiple calls, but it's needed for external APIs like the 
>> ones mentioned.
>>
>> 2) Dealing with JSON is too much boilerplate/hassle. Parsers are 
>> intractable for common usage (but perhaps still required for advanced 
>> usage). Elm needs a configurable automatic de/serializer built-in to 
>> support HTTP. Initially, it could just be parsers generated at compile-time 
>> (same as ports) for any declared type alias.
>>
>> I think alleviating these two issues would make it far easier and more 
>> desirable to actually create Elm libraries for external services which 
>> could be published on elm-package. I know I do not use Elm's built-in HTTP 
>> library for these reasons, and use ports instead on what could otherwise be 
>> a pure Elm app.
>>
>> On Monday, March 13, 2017 at 4:06:44 AM UTC-5, Oliver Searle-Barnes wrote:
>>>
>>> (prompted by discussion of firebase integration on elm-dev)
>>>
>>> Given that it would be really helpful to have more integration libraries 
>>> available for Elm (auth0, firebase, aws...) I've been wondering if the 
>>> current state of affairs is ideal for achieving:
>>>
>>> 1) Maximum number of integration libraries available for Elm
>>> 2) All of those implemented in pure Elm
>>>
>>> Currently the path to get there appears to be:
>>>
>>> 1) Use an existing javascript library and wrap it using ports
>>> 2) Reimplement the library in Elm
>>>
>>> 1 to 2 often represents a significant amount of development. Because 
>>> ports preclude a library from being published in 
&

[elm-discuss] Re: Unsafe mechanism

2017-03-13 Thread Kasey Speakman
The landscape as I see it: Elm does not allow user code to do side effects 
(i.e. communication/IO). In Haskell, a function with side-effects is marked 
as "unsafe" if it declares IO in it's signature e.g. `readFileText: string 
-> IO string`. Since front-end IO is somewhat narrow in what is allowed, 
instead of marking this with IO, Elm provides "safe" wrappers to do the 
most common forms of front-end communication (i.e. HTTP). Most of the 
libraries mentioned expose an HTTP API.

The problem then is that Elm's HTTP library is not quite up to par. The two 
largest problems I see right now:

1) There's no `Cmd.andThen` to chain together commands, so you can't 
package up multiple calls as one operation on the client side. This forces 
libraries to leak implementation details to the caller (e.g. pushing the 
in-between-calls state management to host application) and therefore makes 
them tedious to work with. I try not to design APIs where clients should 
need to make multiple calls, but it's needed for external APIs like the 
ones mentioned.

2) Dealing with JSON is too much boilerplate/hassle. Parsers are 
intractable for common usage (but perhaps still required for advanced 
usage). Elm needs a configurable automatic de/serializer built-in to 
support HTTP. Initially, it could just be parsers generated at compile-time 
(same as ports) for any declared type alias.

I think alleviating these two issues would make it far easier and more 
desirable to actually create Elm libraries for external services which 
could be published on elm-package. I know I do not use Elm's built-in HTTP 
library for these reasons, and use ports instead on what could otherwise be 
a pure Elm app.

On Monday, March 13, 2017 at 4:06:44 AM UTC-5, Oliver Searle-Barnes wrote:
>
> (prompted by discussion of firebase integration on elm-dev)
>
> Given that it would be really helpful to have more integration libraries 
> available for Elm (auth0, firebase, aws...) I've been wondering if the 
> current state of affairs is ideal for achieving:
>
> 1) Maximum number of integration libraries available for Elm
> 2) All of those implemented in pure Elm
>
> Currently the path to get there appears to be:
>
> 1) Use an existing javascript library and wrap it using ports
> 2) Reimplement the library in Elm
>
> 1 to 2 often represents a significant amount of development. Because ports 
> preclude a library from being published in http://package.elm-lang.org/ 
> and elm package doesn't support installing them from anywhere else there's 
> a social pressure to not implement effect managers or release libraries 
> that make use of ports. 
>
> Another path get to pure Elm libraries might be
>
> 1) Use an existing javascript library and wrap it using ports or native 
> functions
> 2) Release it as a library
> 3) Gradually migrate the library over to pure Elm with the help of any 
> members of the community that need it
>
> The concern here is obviously that your Elm code can now blow up and 
> there's no way of knowing which code is unsafe. 
>
> What if unsafe because a first class concept in Elm? You could mark 
> functions as "unsafe". Any function that calls an unsafe function would 
> also be required to be declared as unsafe  e.g.
>
>
> unsafe attemptAuth : LoginDetails -> Task String AuthStatus
> unsafe attemptAuth loginDetails =
> Native.WrappedLibrary.attemptAuth loginDetails
>
>
>
>
> type Msg
> = unsafe AuthResponse (Result String AuthStatus)
>
>
>
> unsafe update : Msg -> Model -> (Model, Cmd Msg)
> unsafe update msg model =
> case msg of
> AuthResponse status ->
>
>
>
>
> This would make it possible to do a first pass on integration by just 
> delegating to the javascript implementation. It's now very clear which of 
> your Elm code is safe and unsafe. Having that unsafe keyword not only let's 
> you know which code carries the Elm safety guarantees (if a function isn't 
> marked unsafe) but you now also have this unsafe keyword stinking up your 
> code encouraging you to reimplement it in pure Elm. You're using a shared 
> library now though so whenever you replace a javascript implementation with 
> a safe Elm version everyone benefits.
>
> What do you think, does this offer a practical route to a greater number 
> of pure Elm integration libraries?
>
>
>
>
>
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Is a decoder the right level of abstraction for parsing JSON?

2017-02-18 Thread Kasey Speakman
An update. I'm using the ports approach to deal with JSON (and also sending 
the HTTP request). For several months, I've had a small but critical app in 
production using that. Another project in development is too. In the 
process, I have run across two additional caveats with this approach.

   1. *Ports don't convert undefined properties to Maybe.Nothing.* It's an 
   open issue from Jan 2016. 
   For a Maybe property, the JSON must have the property present and set to 
   null. Otherwise error. This is particularly annoying when you store the 
   data as JSON and pass it back to the client as-is. To work around this 
   issue, I either have to waste space storing nulls in the database or waste 
   (CPU/response) time server-side to inject nulls in the response.
   
   2. *Cmd.map can't be used with this method.*
   Using Http module, you can use Cmd.map to take some data from the 
   request and give it to the response Msg. Using ports, you can't do that. 
   I've noticed this when the data is easy to provide for a request, but after 
   the response comes back it is less convenient to dig out of the model (e.g. 
   behind a case statement).

Neither of these are blockers for me, just nuisance issues. It still beats 
maintaining codecs.

I've seen rumblings about tools for code-gen'ing JSON codecs for us (maybe 
elm-format?  There also 
exists elm-swagger, but I don't use swagger.). I dunno though. Where 
possible, I tend to avoid code-gen because it's for handling a really 
tedious problem. And if the code-gen fails, then I have to handle a really 
tedious problem. (XSD/WSDL flashbacks.)

All it would really take for a profound QoL improvement are a couple of 
"special" functions on Http that handle data exactly like ports do now... 
just saying.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Seeking feedback: What Elm and Rust teach us about the future

2017-02-13 Thread Kasey Speakman
It would not require a macro system. The compiler already generates co/decs 
for type aliases passed through ports. But this is specific to the port 
keyword and not available for other purposes like using the Http module.

On Friday, February 10, 2017 at 2:08:51 PM UTC-6, OvermindDL1 wrote:
>
> That is just because Rust has a fairly powerful (but incomplete) macro 
> system, that is not something that would really belong in Elm.  ^.^
>
> On Friday, February 10, 2017 at 11:19:49 AM UTC-7, Kasey Speakman wrote:
>>
>> Largest paint point for me in Elm is not mentioned: JSON. Rust appears to 
>> have adequate facilities for this (Serde).
>>
>> Otherwise, looks good. It was interesting to learn more about Rust and 
>> the intersection of features with Elm.
>>
>> On Wednesday, February 8, 2017 at 2:22:11 AM UTC-6, Martin Cerny wrote:
>>>
>>> (This is a cross-post from r/elm and r/rust)
>>>
>>> Hi all,
>>> I wrote a blog post about the striking similarities between Elm and 
>>> Rust, and why I think it is no coincidence different languages took some 
>>> similar design paths. I'll be super happy to receive some feedback on the 
>>> post to let me improve it:
>>> https://dev.to/martincerny/what-elm-and-rust-teach-us-about-the-future
>>>
>>> Thanks
>>> Martin
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Seeking feedback: What Elm and Rust teach us about the future

2017-02-10 Thread Kasey Speakman
Largest paint point for me in Elm is not mentioned: JSON. Rust appears to 
have adequate facilities for this (Serde).

Otherwise, looks good. It was interesting to learn more about Rust and the 
intersection of features with Elm.

On Wednesday, February 8, 2017 at 2:22:11 AM UTC-6, Martin Cerny wrote:
>
> (This is a cross-post from r/elm and r/rust)
>
> Hi all,
> I wrote a blog post about the striking similarities between Elm and Rust, 
> and why I think it is no coincidence different languages took some similar 
> design paths. I'll be super happy to receive some feedback on the post to 
> let me improve it:
> https://dev.to/martincerny/what-elm-and-rust-teach-us-about-the-future
>
> Thanks
> Martin
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: fold function argument order

2016-12-15 Thread Kasey Speakman
Having the behavior you expect? So if you write List.foldl (++) "" ["a", 
"b", "c"], you *expect* to get "cba"? This does not produce what you 
visually see in the calling statement, nor what what is produced from by 
common definition of left fold (in case you want to argue about common 
definition, see above mentioned wikipedia article). How is that expected?

I certainly could consult the documentation before writing any given 
statement, but needing to do so to verify a common operation produces the 
expected result is a symptom of a problem.

This conversation is stagnating, saying the same things in different ways, 
arguing semantics and word meanings. So if there's no new information in 
the next post, the last word is yours. I do understand that your library 
would be affected by such a change. But I wouldn't worry about it, as I 
doubt this will get fixed anyway. In fact, it's this way because preference 
trumped other concerns during design. No disrespect to Evan... we've all 
been there.

On Thursday, December 15, 2016 at 4:40:21 PM UTC-6, Janis Voigtländer wrote:
>
> Well, both in terms of "described" and "expected", all it takes is to have 
> a look at the function's type. I personally often don't care much about 
> prose in function documentation. For this specific function, take a look at 
> the type (the placement of "a"s and "b"s) and that together with the "l" 
> mnemonic from the function's name describes pretty much exactly how list 
> elements will be combined. Or am I overlooking right now another way in 
> which a function of that polymorphic type could process a list from left to 
> right while producing some output? 
>
> And likewise, seeing that function signature and knowing that the function 
> is not the/a right-fold, there is only exactly one behavior I would expect 
> from it, and it's the one it indeed has. :-)
>
> (Of course, if the function had the implementation you want it to have, it 
> would also have a different type, and that type would be equally 
> descriptive for that other implementation's behavior, and would also raise 
> exactly the correct expectations for that implementation.)
>
> Am 15.12.2016 um 23:13 schrieb Kasey Speakman <kjspe...@gmail.com 
> >:
>
> It's not only a matter of preference, but getting the result that you 
> expect from the statement. Whether you look at visual expansion or the way 
> the operation is defined most other places, I'm not sure how it could be 
> considered working as described much less working as expected. Maybe it is 
> working as intended, but that's not a criteria I'm basing my statements on.
>
> On Thursday, December 15, 2016 at 3:04:31 PM UTC-6, Janis Voigtländer 
> wrote:
>>
>> The two examples you provide, the first is left-to-right on *both* input 
>>> and output. The other (Elm's) is not. Right fold is right-to-left on 
>>> *both* input and output. The lack of symmetry between the two 
>>> operations only reinforces the issue.
>>>
>>
>> I don't disagree with your preference for symmetry. I just pointed out 
>> that if one considers processing order on the input (only), there is no 
>> basis to say that Elm's foldl is wrong or not left-to-right. That one 
>> should consider both input and output order/nesting when pondering the name 
>> of this function seems not to have been a principle of the maker of that 
>> decision.
>>
>> -- 
> You received this message because you are subscribed to the Google Groups 
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to elm-discuss...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: fold function argument order

2016-12-15 Thread Kasey Speakman
It's not only a matter of preference, but getting the result that you 
expect from the statement. Whether you look at visual expansion or the way 
the operation is defined most other places, I'm not sure how it could be 
considered working as described much less working as expected. Maybe it is 
working as intended, but that's not a criteria I'm basing my statements on.

On Thursday, December 15, 2016 at 3:04:31 PM UTC-6, Janis Voigtländer wrote:
>
> The two examples you provide, the first is left-to-right on *both* input 
>> and output. The other (Elm's) is not. Right fold is right-to-left on 
>> *both* input and output. The lack of symmetry between the two operations 
>> only reinforces the issue.
>>
>
> I don't disagree with your preference for symmetry. I just pointed out 
> that if one considers processing order on the input (only), there is no 
> basis to say that Elm's foldl is wrong or not left-to-right. That one 
> should consider both input and output order/nesting when pondering the name 
> of this function seems not to have been a principle of the maker of that 
> decision.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: fold function argument order

2016-12-15 Thread Kasey Speakman
I also would not care for a foldHeadToTail function where the order of 
operations is unspecified. It would be unusable without knowing the order 
in some cases. I was just pointing out that it's more accurate to foldl's 
implementation, considering the modern body of work that already implements 
foldl differently.

On Thursday, December 15, 2016 at 1:57:57 PM UTC-6, Kasey Speakman wrote:
>
> The two examples you provide, the first is left-to-right on *both* input 
> and output. The other (Elm's) is not. Right fold is right-to-left on 
> *both* input and output. The lack of symmetry between the two operations 
> only reinforces the issue.
>
> On Thursday, December 15, 2016 at 1:51:26 PM UTC-6, Janis Voigtländer 
> wrote:
>>
>> I would like to point out that: I’m sure neither of us is too stupid to 
>> know what the other means. :-)
>>
>> And I don’t think there is no basis to discuss these aspects. In fact, 
>> here is a possible explanation of why this all seems so fuzzy: One could 
>> distinguish between “from left to right in terms of the input” and “from 
>> left to right in the output”. Then:
>>
>>- ((0 - 1) - 2) - 3 processes elements from left to right in terms of 
>>the input and happens to produce an expression that is nested from left 
>> to 
>>right in the output 
>>- 3 - (2 - (1 - 0)) processes elements from left to right in terms of 
>>the input and happens to produce an expression that is nested from right 
>> to 
>>left in the output 
>>
>> The distinction you make between “head to tail” and “left to right” (as 
>> if you would be fine with the current Elm behavior of foldl aka 
>> foldLeftToRight if it were simply called foldHeadToTail instead) is not 
>> one I can relate to.
>> ​
>>
>> 2016-12-15 20:31 GMT+01:00 Kasey Speakman <kjspe...@gmail.com>:
>>
>>> foldl doesn't say it folds head to tail (which would be accurate). It 
>>> says it folds from the left ("to the right" is understood... where else are 
>>> you going to go from the left?).
>>>
>>> I'm not going to quibble over what "left" is, nor what processing 
>>> something from the left to right means. If that's not understood between 
>>> us, then we don't have enough basis to discuss that aspect.
>>>
>>> But I would like to point out that: the fact that it is a source of 
>>> confusion only brings to the surface the imprecision of its name.
>>>
>>> On Thursday, December 15, 2016 at 1:05:14 PM UTC-6, Janis Voigtländer 
>>> wrote:
>>>>
>>>> And I do get the mathematically wrong answer on foldl when using 
>>>>> mathematically non-associative operations (like subtraction). That's 
>>>>> provided we agree on the definition of which side of the list is the 
>>>>> "left" 
>>>>> side.
>>>>
>>>> Well, still not quite for me. I’m sure we both agree what the “left” 
>>>> side of the list is. And still I don’t think there is an argument to make 
>>>> that hence Elm’ foldl‘s answer is mathematically wrong. The fact that 
>>>> we agree what the left side of the list is does not mean that foldl 
>>>> (-) 0 [1,2,3] needs to evaluate to ((0 - 1) - 2) -3. It can evaluate 
>>>> to 3 - (2 - (1 - 0)) without us disagreeing what is “left”. In other 
>>>> words, “leftiness” is not at issue here. Both ((0 - 1) - 2) -3 and 3 - 
>>>> (2 - (1 - 0)) do work “from the left”. They combine elements in the 
>>>> order in which they appear in the list *from left to right*. One could 
>>>> argue that the real thing at issue here is not what “left” means, but what 
>>>> “folding” means. You take it to mean to literally replace :: by (-) 
>>>> and you are only willing to argue about how the result is bracketed. But 
>>>> one can take “folding” to simply mean that stuff gets accumulated via an 
>>>> operator, and “left folding” then means that more-left-sitting elements 
>>>> get 
>>>> accumulated earlier. And Elm’s foldl is perfectly mathematically 
>>>> correct according to this meaning.
>>>>
>>>> Of course, that’s back to a point I made already the other day. There’s 
>>>> nothing “mathematically wrong” about Elm’s foldl unless one postulates 
>>>> “mathematically correct” to mean “ foldl needs to be the specific 
>>>> operation it is in Haskell etc.” But that’s not a mathematical argument.
>>>> ​
>>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Elm Discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to elm-discuss...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: fold function argument order

2016-12-15 Thread Kasey Speakman
The two examples you provide, the first is left-to-right on *both* input 
and output. The other (Elm's) is not. Right fold is right-to-left on *both* 
input 
and output. The lack of symmetry between the two operations only reinforces 
the issue.

On Thursday, December 15, 2016 at 1:51:26 PM UTC-6, Janis Voigtländer wrote:
>
> I would like to point out that: I’m sure neither of us is too stupid to 
> know what the other means. :-)
>
> And I don’t think there is no basis to discuss these aspects. In fact, 
> here is a possible explanation of why this all seems so fuzzy: One could 
> distinguish between “from left to right in terms of the input” and “from 
> left to right in the output”. Then:
>
>- ((0 - 1) - 2) - 3 processes elements from left to right in terms of 
>the input and happens to produce an expression that is nested from left to 
>right in the output 
>- 3 - (2 - (1 - 0)) processes elements from left to right in terms of 
>the input and happens to produce an expression that is nested from right 
> to 
>left in the output 
>
> The distinction you make between “head to tail” and “left to right” (as if 
> you would be fine with the current Elm behavior of foldl aka 
> foldLeftToRight if it were simply called foldHeadToTail instead) is not 
> one I can relate to.
> ​
>
> 2016-12-15 20:31 GMT+01:00 Kasey Speakman <kjspe...@gmail.com 
> >:
>
>> foldl doesn't say it folds head to tail (which would be accurate). It 
>> says it folds from the left ("to the right" is understood... where else are 
>> you going to go from the left?).
>>
>> I'm not going to quibble over what "left" is, nor what processing 
>> something from the left to right means. If that's not understood between 
>> us, then we don't have enough basis to discuss that aspect.
>>
>> But I would like to point out that: the fact that it is a source of 
>> confusion only brings to the surface the imprecision of its name.
>>
>> On Thursday, December 15, 2016 at 1:05:14 PM UTC-6, Janis Voigtländer 
>> wrote:
>>>
>>> And I do get the mathematically wrong answer on foldl when using 
>>>> mathematically non-associative operations (like subtraction). That's 
>>>> provided we agree on the definition of which side of the list is the 
>>>> "left" 
>>>> side.
>>>
>>> Well, still not quite for me. I’m sure we both agree what the “left” 
>>> side of the list is. And still I don’t think there is an argument to make 
>>> that hence Elm’ foldl‘s answer is mathematically wrong. The fact that 
>>> we agree what the left side of the list is does not mean that foldl (-) 
>>> 0 [1,2,3] needs to evaluate to ((0 - 1) - 2) -3. It can evaluate to 3 - 
>>> (2 - (1 - 0)) without us disagreeing what is “left”. In other words, 
>>> “leftiness” is not at issue here. Both ((0 - 1) - 2) -3 and 3 - (2 - (1 
>>> - 0)) do work “from the left”. They combine elements in the order in 
>>> which they appear in the list *from left to right*. One could argue 
>>> that the real thing at issue here is not what “left” means, but what 
>>> “folding” means. You take it to mean to literally replace :: by (-) and 
>>> you are only willing to argue about how the result is bracketed. But one 
>>> can take “folding” to simply mean that stuff gets accumulated via an 
>>> operator, and “left folding” then means that more-left-sitting elements get 
>>> accumulated earlier. And Elm’s foldl is perfectly mathematically 
>>> correct according to this meaning.
>>>
>>> Of course, that’s back to a point I made already the other day. There’s 
>>> nothing “mathematically wrong” about Elm’s foldl unless one postulates 
>>> “mathematically correct” to mean “ foldl needs to be the specific 
>>> operation it is in Haskell etc.” But that’s not a mathematical argument.
>>> ​
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: fold function argument order

2016-12-15 Thread Kasey Speakman
foldl doesn't say it folds head to tail (which would be accurate). It says 
it folds from the left ("to the right" is understood... where else are you 
going to go from the left?).

I'm not going to quibble over what "left" is, nor what processing something 
from the left to right means. If that's not understood between us, then we 
don't have enough basis to discuss that aspect.

But I would like to point out that: the fact that it is a source of 
confusion only brings to the surface the imprecision of its name.

On Thursday, December 15, 2016 at 1:05:14 PM UTC-6, Janis Voigtländer wrote:
>
> And I do get the mathematically wrong answer on foldl when using 
>> mathematically non-associative operations (like subtraction). That's 
>> provided we agree on the definition of which side of the list is the "left" 
>> side.
>
> Well, still not quite for me. I’m sure we both agree what the “left” side 
> of the list is. And still I don’t think there is an argument to make that 
> hence Elm’ foldl‘s answer is mathematically wrong. The fact that we agree 
> what the left side of the list is does not mean that foldl (-) 0 [1,2,3] 
> needs to evaluate to ((0 - 1) - 2) -3. It can evaluate to 3 - (2 - (1 - 
> 0)) without us disagreeing what is “left”. In other words, “leftiness” is 
> not at issue here. Both ((0 - 1) - 2) -3 and 3 - (2 - (1 - 0)) do work 
> “from the left”. They combine elements in the order in which they appear in 
> the list *from left to right*. One could argue that the real thing at 
> issue here is not what “left” means, but what “folding” means. You take it 
> to mean to literally replace :: by (-) and you are only willing to argue 
> about how the result is bracketed. But one can take “folding” to simply 
> mean that stuff gets accumulated via an operator, and “left folding” then 
> means that more-left-sitting elements get accumulated earlier. And Elm’s 
> foldl is perfectly mathematically correct according to this meaning.
>
> Of course, that’s back to a point I made already the other day. There’s 
> nothing “mathematically wrong” about Elm’s foldl unless one postulates 
> “mathematically correct” to mean “ foldl needs to be the specific 
> operation it is in Haskell etc.” But that’s not a mathematical argument.
> ​
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: fold function argument order

2016-12-15 Thread Kasey Speakman
Yes, I did confuse mathematically associativity with programming language 
associativity (which adds left and right distinctions for expression 
evaluation) in the previous post. I stand corrected.

A mathematically associative operation will work from either left or right 
when folding. But a non-associative operation's result depends on which 
direction it is processed. Foldl is expected to process left. If Elm's 
foldl where instead named foldHeadToTail, I could hardly argue it doesn't 
obey the contract it sets up. But its name and description in the 
documentation "Reduce a list from the left." makes it inaccurate and 
lacking "visually honesty" in the way you call it.

And I do get the mathematically wrong answer on foldl when using 
mathematically non-associative operations (like subtraction). That's 
provided we agree on the definition of which side of the list is the "left" 
side.

For bonus visual honesty, I also like the right fold syntax in languages 
that put the initial value as the last argument. It guides you to pick the 
correct fold for the operator, since it's easy to visualize the expansion. 
E.g.

List.foldBack (::) [1, 2, 3] []
==   1 :: 2 :: 3 :: []

I think the reason for all the right associativity in Elm is an emphasis on 
chaining/piping, which is inherently right-associative. E.g. step3 ( step2 
( step1 x) ) == x |> step1 |> step2 |> step3 == step1 >> step2 >> step3

I am keen on composition/piping myself, but ultimately pattern doesn't fit 
everywhere.

On Thursday, December 15, 2016 at 10:53:30 AM UTC-6, Janis Voigtländer 
wrote:

> I do know how foldl is in other languages. And that it is different in 
> those other languages than it is in Elm. And I even agree that it would be 
> better that foldl in Elm is as in other languages (or Haskell, 
> specifically). I think I even argued for this on this mailing list in the 
> past.
>
> But all this is not what my message to you was about. I pointed out that 
> you have no argument for this position that is of the form “… because of 
> mathematics”. All the argument you (or I) have is that other languages do 
> something different and that it would be nicer if Elm behaved like those, 
> also because what those do is easier to explain/visualize. You didn’t seem 
> to acknowledge that this is the only argument you have, before. Your latest 
> message suggests you now do see that this is the only argument you have. 
> (It’s a fine argument. But it’s only this one, not a stronger mathematical 
> argument as you previously tried to make exist.)
> ​
>
> 2016-12-15 16:27 GMT+01:00 Kasey Speakman <kjspe...@gmail.com 
> >:
>
>> I read the associativity article. You should examine this wikipedia 
>> article on fold 
>> <https://en.wikipedia.org/wiki/Fold_(higher-order_function)>.
>>
>> OCaml, F#, Haskell, Scala, Clojure, Elixir, etc. all have left folds as 
>> described in this article. Elm does not. I included a quote from it below.
>>
>> "The folding of the list [1,2,3,4,5] with the addition operator would 
>> result in 15, the sum of the elements of the list [1,2,3,4,5]. To a 
>> rough approximation, one can think of this fold as replacing the commas in 
>> the list with the + operation, giving 1 + 2 + 3 + 4 + 5."
>>
>> Elm would generate 5 + 4 + 3 + 2 + 1. Since + is associative it does not 
>> matter. But using -, Elm's result would be incorrect.
>>
>> So when you go from Elm on the front end to > language here> on the back end, Elm's current foldl syntax lays something 
>> on the floor for you to trip over.
>>
>> On Saturday, December 10, 2016 at 12:44:30 AM UTC-6, Janis Voigtländer 
>> wrote:
>>>
>>> Kasey, you keep talking as if there were a mathematical, semantic 
>>> concept of “left-associativity” (and the same for “right-associativity”). 
>>> But there isn’t. Or can you give a definition?
>>>
>>> A definition of the mathematical, semantic concept of “associativity” 
>>> is: “An operator is associative if applying that operator to a and b 
>>> (in that order) and then applying it to the result of that and c (in 
>>> that order) evaluates to the same result as applying it to a and to the 
>>> result of applying it to b and c (in those orders).” No corresponding 
>>> concept of “left-associativity” exists.
>>>
>>> Reaching for something like “left-associativity means that a op b op c 
>>> should be read as (a op b) op c“ means that you are talking of a 
>>> parsing convention, not a mathematical property of the operator.
>>>
>>> And all that is relevant because you are trying to make an argument 
>>

Re: [elm-discuss] Re: fold function argument order

2016-12-15 Thread Kasey Speakman
I read the associativity article. You should examine this wikipedia article 
on fold <https://en.wikipedia.org/wiki/Fold_(higher-order_function)>.

OCaml, F#, Haskell, Scala, Clojure, Elixir, etc. all have left folds as 
described in this article. Elm does not. I included a quote from it below.

"The folding of the list [1,2,3,4,5] with the addition operator would 
result in 15, the sum of the elements of the list [1,2,3,4,5]. To a rough 
approximation, one can think of this fold as replacing the commas in the 
list with the + operation, giving 1 + 2 + 3 + 4 + 5."

Elm would generate 5 + 4 + 3 + 2 + 1. Since + is associative it does not 
matter. But using -, Elm's result would be incorrect.

So when you go from Elm on the front end to  on the back end, Elm's current foldl syntax lays something 
on the floor for you to trip over.

On Saturday, December 10, 2016 at 12:44:30 AM UTC-6, Janis Voigtländer 
wrote:
>
> Kasey, you keep talking as if there were a mathematical, semantic concept 
> of “left-associativity” (and the same for “right-associativity”). But there 
> isn’t. Or can you give a definition?
>
> A definition of the mathematical, semantic concept of “associativity” is: 
> “An operator is associative if applying that operator to a and b (in that 
> order) and then applying it to the result of that and c (in that order) 
> evaluates to the same result as applying it to a and to the result of 
> applying it to b and c (in those orders).” No corresponding concept of 
> “left-associativity” exists.
>
> Reaching for something like “left-associativity means that a op b op c 
> should be read as (a op b) op c“ means that you are talking of a parsing 
> convention, not a mathematical property of the operator.
>
> And all that is relevant because you are trying to make an argument about 
> the behavior of some function being “mathematically wrong”, and basing that 
> on something like “because it does not respect left-associativity”, which 
> is moot given that there is no semantic property that you could state and 
> see violated.
>
> Similarly, you make a statement about “current foldl does not fold from 
> the left”, but haven’t defined semantically what it means to “fold from the 
> left”. One such definition could be “folding from the left means that the 
> left-most element is first combined with the second-left-most element 
> before any other elements are used”. In that sense, current foldl *is* 
> folding from the left. If you want to say that it is not, you have to 
> provide an alternative definition of the concept of “folding from the 
> left”. Can you? Can you tell us what it is?
>
> Aside: About the concepts of associativity, you may want to compare 
> https://en.wikipedia.org/wiki/Operator_associativity and 
> https://en.wikipedia.org/wiki/Associative_property, and to consider the 
> explicit pointer from the former to the latter as regards “the mathematical 
> concept of associativity”, as well as taking note of the fact that the 
> latter page does not mention anything like “left-associativity” and 
> “right-associativity” (because, I repeat, those do not exist as 
> mathematical, semantical-as-opposed-to-syntactical concepts).
> ​
>
> 2016-12-10 6:43 GMT+01:00 Kasey Speakman <kjspe...@gmail.com 
> >:
>
>> Minor term correction. String concatenation isn't left-associative (duh 
>> on my part). It's just not commutative (the order can't be swapped and 
>> still get the same answer, unlike addition/multi).
>>
>> On Friday, December 9, 2016 at 11:15:04 PM UTC-6, Kasey Speakman wrote:
>>>
>>> It's about associativity. Some operations have specific associativity 
>>> even when a and b are different types.
>>>
>>> Cons (::) is a great example of this. Cons is only right associative 
>>> even when `a` is Int and `b` is List Int. You cannot write `[] :: 1 :: 2 :: 
>>> 3`, because cons does not work from the left, but from the right: `1 :: 2 
>>> :: 3 :: []`.
>>>
>>> Switching to same type: subtraction and string concatenation are left 
>>> associative. Addition is (either-way) associative (order doesn't matter).
>>>
>>> When folding over a list, I need to know whether it will handle left- or 
>>> right-associative operators. The naming of foldl would suggest left. and 
>>> foldr would suggest right.
>>>
>>> Both fold functions in Elm are right associative (due to the a -> b -> b 
>>> folder definition). You can already define a left associative operation 
>>> with foldr using reverse and flip, so there's no reason for foldl to exist 
>>> except to be a convenience for using left associative operations. And it 
>>> do

Re: [elm-discuss] Re: fold function argument order

2016-12-09 Thread Kasey Speakman
Minor term correction. String concatenation isn't left-associative (duh on 
my part). It's just not commutative (the order can't be swapped and still 
get the same answer, unlike addition/multi).

On Friday, December 9, 2016 at 11:15:04 PM UTC-6, Kasey Speakman wrote:
>
> It's about associativity. Some operations have specific associativity even 
> when a and b are different types.
>
> Cons (::) is a great example of this. Cons is only right associative even 
> when `a` is Int and `b` is List Int. You cannot write `[] :: 1 :: 2 :: 3`, 
> because cons does not work from the left, but from the right: `1 :: 2 :: 3 
> :: []`.
>
> Switching to same type: subtraction and string concatenation are left 
> associative. Addition is (either-way) associative (order doesn't matter).
>
> When folding over a list, I need to know whether it will handle left- or 
> right-associative operators. The naming of foldl would suggest left. and 
> foldr would suggest right.
>
> Both fold functions in Elm are right associative (due to the a -> b -> b 
> folder definition). You can already define a left associative operation 
> with foldr using reverse and flip, so there's no reason for foldl to exist 
> except to be a convenience for using left associative operations. And it 
> doesn't event do that.
>
> I just said a bunch of words that probably nobody will bother (or has 
> time) to dig into to discover my point. So I'll leave you with this. Plug 
> this into Elm Hello World example 
> <http://elm-lang.org/examples/hello-html>.
>
> import Html exposing (text)
>
> main =
>  List.foldl (++) "" ["a", "b", "c"]
>   == List.foldr (++) "" ["c", "b", "a"]
>
>   |> toString
>   |> text
>
> Now ask yourself if you would expect the given outcome just by looking at 
> it.
>
> On Friday, December 9, 2016 at 4:17:50 PM UTC-6, Nick H wrote:
>>
>> I would disagree with "not expected in general." In general -- when a and 
>> b are different types -- Elm's API design guidelines should set you up to 
>> always expect a -> b -> b and never b -> a -> b. If the definition of foldl 
>> were changed to take the latter, it would be the only exception to this 
>> expectation.
>>
>> On Fri, Dec 9, 2016 at 7:03 AM, Kasey Speakman <kjspe...@gmail.com> 
>> wrote:
>>
>>> Ok, correction
>>>
>>> List.foldl (-) 0 [1, 2, 3]
>>> -- returns 2
>>> -- expands to 3 - (2 - (1 - 0)) = 2
>>>
>>> During my testing last night, I had a typo (foldr instead of foldl) when 
>>> I was testing the expansions. That was the center-building behavior.
>>>
>>> Using the form a -> b -> b is right-building regardless of the order the 
>>> list is traversed. Traversing from head to tail is equivalent to reversing 
>>> the list and building right. This is obviously broken for left-associative 
>>> only operations and not expected in general.
>>>
>>> On Friday, December 9, 2016 at 8:44:25 AM UTC-6, Kasey Speakman wrote:
>>>>
>>>> Sorry, that last bit was an example of what happens in Elm when folding 
>>>> with string concat (++). That's unexpected behavior from a left fold.
>>>>
>>>> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown 
>>>> quick The "
>>>>
>>>> On Friday, December 9, 2016 at 8:26:17 AM UTC-6, Kasey Speakman wrote:
>>>>>
>>>>> You're confusing pipe's syntax and infix. Pipe is defined like this:
>>>>>
>>>>> (|>) x f = f x
>>>>>
>>>>> And used like this
>>>>>
>>>>> x |> f == f x
>>>>>
>>>>> So pipe has an inherent flip because it is used to chain otherwise 
>>>>> right-building statements.
>>>>>
>>>>> e.g. 
>>>>>
>>>>> List.sum (List.filter isOdd [1, 2, 3])
>>>>>
>>>>> vs
>>>>>
>>>>> [1, 2, 3]
>>>>> |> List.filter isOdd
>>>>> |> List.sum
>>>>>
>>>>> Pipe is inherently right-building, so operations like subtract or 
>>>>> string concatenation are not suitable for it since they are only left 
>>>>> associative.
>>>>>
>>>>> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown 
>>>>> quick The 

Re: [elm-discuss] Re: fold function argument order

2016-12-09 Thread Kasey Speakman
It's about associativity. Some operations have specific associativity even 
when a and b are different types.

Cons (::) is a great example of this. Cons is only right associative even 
when `a` is Int and `b` is List Int. You cannot write `[] :: 1 :: 2 :: 3`, 
because cons does not work from the left, but from the right: `1 :: 2 :: 3 
:: []`.

Switching to same type: subtraction and string concatenation are left 
associative. Addition is (either-way) associative (order doesn't matter).

When folding over a list, I need to know whether it will handle left- or 
right-associative operators. The naming of foldl would suggest left. and 
foldr would suggest right.

Both fold functions in Elm are right associative (due to the a -> b -> b 
folder definition). You can already define a left associative operation 
with foldr using reverse and flip, so there's no reason for foldl to exist 
except to be a convenience for using left associative operations. And it 
doesn't event do that.

I just said a bunch of words that probably nobody will bother (or has time) 
to dig into to discover my point. So I'll leave you with this. Plug this 
into Elm Hello World example <http://elm-lang.org/examples/hello-html>.

import Html exposing (text)

main =
 List.foldl (++) "" ["a", "b", "c"]
  == List.foldr (++) "" ["c", "b", "a"]

  |> toString
  |> text

Now ask yourself if you would expect the given outcome just by looking at 
it.

On Friday, December 9, 2016 at 4:17:50 PM UTC-6, Nick H wrote:
>
> I would disagree with "not expected in general." In general -- when a and 
> b are different types -- Elm's API design guidelines should set you up to 
> always expect a -> b -> b and never b -> a -> b. If the definition of foldl 
> were changed to take the latter, it would be the only exception to this 
> expectation.
>
> On Fri, Dec 9, 2016 at 7:03 AM, Kasey Speakman <kjspe...@gmail.com 
> > wrote:
>
>> Ok, correction
>>
>> List.foldl (-) 0 [1, 2, 3]
>> -- returns 2
>> -- expands to 3 - (2 - (1 - 0)) = 2
>>
>> During my testing last night, I had a typo (foldr instead of foldl) when 
>> I was testing the expansions. That was the center-building behavior.
>>
>> Using the form a -> b -> b is right-building regardless of the order the 
>> list is traversed. Traversing from head to tail is equivalent to reversing 
>> the list and building right. This is obviously broken for left-associative 
>> only operations and not expected in general.
>>
>> On Friday, December 9, 2016 at 8:44:25 AM UTC-6, Kasey Speakman wrote:
>>>
>>> Sorry, that last bit was an example of what happens in Elm when folding 
>>> with string concat (++). That's unexpected behavior from a left fold.
>>>
>>> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick 
>>> The "
>>>
>>> On Friday, December 9, 2016 at 8:26:17 AM UTC-6, Kasey Speakman wrote:
>>>>
>>>> You're confusing pipe's syntax and infix. Pipe is defined like this:
>>>>
>>>> (|>) x f = f x
>>>>
>>>> And used like this
>>>>
>>>> x |> f == f x
>>>>
>>>> So pipe has an inherent flip because it is used to chain otherwise 
>>>> right-building statements.
>>>>
>>>> e.g. 
>>>>
>>>> List.sum (List.filter isOdd [1, 2, 3])
>>>>
>>>> vs
>>>>
>>>> [1, 2, 3]
>>>> |> List.filter isOdd
>>>> |> List.sum
>>>>
>>>> Pipe is inherently right-building, so operations like subtract or 
>>>> string concatenation are not suitable for it since they are only left 
>>>> associative.
>>>>
>>>> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown 
>>>> quick The "
>>>>
>>>> On Friday, December 9, 2016 at 1:05:56 AM UTC-6, Aaron VonderHaar wrote:
>>>>>
>>>>> What's confusing here is how currying works with infix operators.  
>>>>> It's idiomatic in Elm to have your accumulator be the last argument, and, 
>>>>> for instance, if you were writing your own data type, you would want to 
>>>>> write your functions so that they can be chained together easily:
>>>>>
>>>>> myMatrix
>>>>> |> scale 2
>>>>> |> subtract 5
>>>>> |> subtractMatrix 

[elm-discuss] Re: `Case of` branches grouping

2016-12-09 Thread Kasey Speakman
An example of what it could look like.

In F#, you can group cases together which have the same parameter type

match x with
| A i ->
// stuff1

| B s | C s | D s ->
// stuff2 on s

However you cannot group together cases with different parameters types

match x with
| A i | B s | C s | D s -> // error

However in F# multiple parameters to an ADT are tuples, and you can use 
underscore for the whole tuple.

On Friday, December 9, 2016 at 9:25:29 AM UTC-6, Petr Huřťák wrote:
>
> Hi,
>
> I would like hear some discussion on grouping of branches in `case of` 
> statement . Currently it is not possible to use one branch for multiple 
> conditions.
>
> Something along these lines:
>
> case someTypeValue of
> A ->
> -- code
>
> B ->
> C ->
> D ->
> -- different code
>
>
> Current alternative is this
>
> case someTypeValue of
> let
> stuff2 =
> -- code  
> in
> A ->
> -- different code
>
> B ->
> stuff2
>
> C ->
> stuff2
> 
> D ->
> stuff2
>
>
> Which is unnecessarily verbose and harder to read.
>
> One question is how this would work when there in cases where matched 
> patterns have some values attached to them
>
> case someTypeValue of
> A ->
> -- stuff1
>
>
> B _ ->
> C _ _ ->
> D _ _ _ ->
> -- stuff2
>
> How is this handled in other languages like OCaml or Haskell?
>
> NOTE: moved from 
> https://groups.google.com/forum/#!topic/elm-dev/DtUT2ieYTDo
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: fold function argument order

2016-12-09 Thread Kasey Speakman
Ok, correction

List.foldl (-) 0 [1, 2, 3]
-- returns 2
-- expands to 3 - (2 - (1 - 0)) = 2

During my testing last night, I had a typo (foldr instead of foldl) when I 
was testing the expansions. That was the center-building behavior.

Using the form a -> b -> b is right-building regardless of the order the 
list is traversed. Traversing from head to tail is equivalent to reversing 
the list and building right. This is obviously broken for left-associative 
only operations and not expected in general.

On Friday, December 9, 2016 at 8:44:25 AM UTC-6, Kasey Speakman wrote:
>
> Sorry, that last bit was an example of what happens in Elm when folding 
> with string concat (++). That's unexpected behavior from a left fold.
>
> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick 
> The "
>
> On Friday, December 9, 2016 at 8:26:17 AM UTC-6, Kasey Speakman wrote:
>>
>> You're confusing pipe's syntax and infix. Pipe is defined like this:
>>
>> (|>) x f = f x
>>
>> And used like this
>>
>> x |> f == f x
>>
>> So pipe has an inherent flip because it is used to chain otherwise 
>> right-building statements.
>>
>> e.g. 
>>
>> List.sum (List.filter isOdd [1, 2, 3])
>>
>> vs
>>
>> [1, 2, 3]
>> |> List.filter isOdd
>> |> List.sum
>>
>> Pipe is inherently right-building, so operations like subtract or string 
>> concatenation are not suitable for it since they are only left associative.
>>
>> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick 
>> The "
>>
>> On Friday, December 9, 2016 at 1:05:56 AM UTC-6, Aaron VonderHaar wrote:
>>>
>>> What's confusing here is how currying works with infix operators.  It's 
>>> idiomatic in Elm to have your accumulator be the last argument, and, for 
>>> instance, if you were writing your own data type, you would want to write 
>>> your functions so that they can be chained together easily:
>>>
>>> myMatrix
>>> |> scale 2
>>> |> subtract 5
>>> |> subtractMatrix myOtherMatrix
>>> |> normalize
>>>
>>>
>>> But as an infix operator (-) is not able to follow that convention;
>>>
>>> 5
>>> |> (-) 3
>>> |> (-) 1
>>>
>>> is confusingly equivalent to `(1 - (3 - 5))` rather than to `5 - 3 - 1`
>>>
>>>
>>> If you had a function `subtract` such that
>>>
>>> 5 |> subtract 3 |> subtract 1 == (5 - 3 - 1)
>>>
>>> then you could use that function with fold as you intend
>>>
>>> List.foldl subtract 0 [1, 2, 3, 4]  ==  -10
>>>
>>> You can achieve the same result with
>>>
>>> List.foldl (flip (-)) 0 [1, 2, 3, 4]  ==  -10
>>>
>>>
>>> Another way to put it is, in Elm, folds expand in the following way:
>>>
>>> List.foldl f x [b, c, d]  ==  x |> f b |> f c |> f d 
>>> List.foldr f x [b, c, d]  ==  f b <| f c <| f d <| x
>>>
>>>
>>> On Thu, Dec 8, 2016 at 7:50 PM, Kasey Speakman <kjspe...@gmail.com> 
>>> wrote:
>>>
>>>> (deleted and corrected original post with proper expansion of Elm's 
>>>> foldl)
>>>>
>>>> I know this is a really old thread, but I ran into this precise 
>>>> question and thought I would add a perspective.
>>>>
>>>> The form a -> b -> b is not left-building, regardless of the direction 
>>>> you are traversing the list.
>>>>
>>>> An example: Starting from zero, subtract the numbers 1, 2, and 3. The 
>>>> expected answer is -6.
>>>>
>>>> List.foldl (-) 0 [1, 2, 3]
>>>> -> returns -6 in Haskell (well, actually tested in F# which uses same 
>>>> order as Haskell)
>>>> expands to: ((0 - 1) - 2) - 3 = -6
>>>> -> returns 2 in Elm
>>>> expands to: 3 - ((1 - 0) - 2)
>>>>
>>>> Elm's expansion is wonky for this. It appears to be center-building:
>>>> List.foldl (-) 0 [1] -- returns 1, expands 1 - 0
>>>> List.foldl (-) 0 [1, 2] -- returns -1, expands (1 - 0) - 2
>>>> List.foldl (-) 0 [1, 2, 3] -- returns 2, expands 3 - ((1 - 0) - 2)
>>>> List.foldl (-) 0 [1, 2, 3, 4] -- returns -2, expands (3 - ((1 - 0) 
>>&g

Re: [elm-discuss] Re: fold function argument order

2016-12-09 Thread Kasey Speakman
Sorry, that last bit was an example of what happens in Elm when folding 
with string concat (++). That's unexpected behavior from a left fold.

List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick 
The "

On Friday, December 9, 2016 at 8:26:17 AM UTC-6, Kasey Speakman wrote:
>
> You're confusing pipe's syntax and infix. Pipe is defined like this:
>
> (|>) x f = f x
>
> And used like this
>
> x |> f == f x
>
> So pipe has an inherent flip because it is used to chain otherwise 
> right-building statements.
>
> e.g. 
>
> List.sum (List.filter isOdd [1, 2, 3])
>
> vs
>
> [1, 2, 3]
> |> List.filter isOdd
> |> List.sum
>
> Pipe is inherently right-building, so operations like subtract or string 
> concatenation are not suitable for it since they are only left associative.
>
> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick 
> The "
>
> On Friday, December 9, 2016 at 1:05:56 AM UTC-6, Aaron VonderHaar wrote:
>>
>> What's confusing here is how currying works with infix operators.  It's 
>> idiomatic in Elm to have your accumulator be the last argument, and, for 
>> instance, if you were writing your own data type, you would want to write 
>> your functions so that they can be chained together easily:
>>
>> myMatrix
>> |> scale 2
>> |> subtract 5
>> |> subtractMatrix myOtherMatrix
>> |> normalize
>>
>>
>> But as an infix operator (-) is not able to follow that convention;
>>
>> 5
>> |> (-) 3
>> |> (-) 1
>>
>> is confusingly equivalent to `(1 - (3 - 5))` rather than to `5 - 3 - 1`
>>
>>
>> If you had a function `subtract` such that
>>
>> 5 |> subtract 3 |> subtract 1 == (5 - 3 - 1)
>>
>> then you could use that function with fold as you intend
>>
>> List.foldl subtract 0 [1, 2, 3, 4]  ==  -10
>>
>> You can achieve the same result with
>>
>> List.foldl (flip (-)) 0 [1, 2, 3, 4]  ==  -10
>>
>>
>> Another way to put it is, in Elm, folds expand in the following way:
>>
>> List.foldl f x [b, c, d]  ==  x |> f b |> f c |> f d 
>> List.foldr f x [b, c, d]  ==  f b <| f c <| f d <| x
>>
>>
>> On Thu, Dec 8, 2016 at 7:50 PM, Kasey Speakman <kjspe...@gmail.com> 
>> wrote:
>>
>>> (deleted and corrected original post with proper expansion of Elm's 
>>> foldl)
>>>
>>> I know this is a really old thread, but I ran into this precise question 
>>> and thought I would add a perspective.
>>>
>>> The form a -> b -> b is not left-building, regardless of the direction 
>>> you are traversing the list.
>>>
>>> An example: Starting from zero, subtract the numbers 1, 2, and 3. The 
>>> expected answer is -6.
>>>
>>> List.foldl (-) 0 [1, 2, 3]
>>> -> returns -6 in Haskell (well, actually tested in F# which uses same 
>>> order as Haskell)
>>> expands to: ((0 - 1) - 2) - 3 = -6
>>> -> returns 2 in Elm
>>> expands to: 3 - ((1 - 0) - 2)
>>>
>>> Elm's expansion is wonky for this. It appears to be center-building:
>>> List.foldl (-) 0 [1] -- returns 1, expands 1 - 0
>>> List.foldl (-) 0 [1, 2] -- returns -1, expands (1 - 0) - 2
>>> List.foldl (-) 0 [1, 2, 3] -- returns 2, expands 3 - ((1 - 0) - 2)
>>> List.foldl (-) 0 [1, 2, 3, 4] -- returns -2, expands (3 - ((1 - 0) - 
>>> 2)) - 4
>>>
>>> When a and b are the same type it will only return the correct answer if 
>>> the fold operation is also commutative or if flip is used to correct 
>>> the ordering. When a and b are not the same type, the compiler will provide 
>>> an error for wrong ordering of course.
>>>
>>> I started out on the side that a -> b -> b was correct as that feels 
>>> like proper "reduction" or chainable syntax. But after exploring it, it is 
>>> clearly not left-building. Makes sense when you consider this form is used 
>>> with pipe to convert right-building operations into left-reading code. e.g. 
>>> a 
>>> |> f |> g |> h instead of h (g (f a))
>>>
>>> On Tuesday, July 16, 2013 at 6:13:01 AM UTC-5, Evan wrote:
>>>>
>>>> Gotcha, I definitely see the reasoning :)
>>>>
>>>>
>>>> On Tu

Re: [elm-discuss] Re: fold function argument order

2016-12-09 Thread Kasey Speakman
You're confusing pipe's syntax and infix. Pipe is defined like this:

(|>) x f = f x

And used like this

x |> f == f x

So pipe has an inherent flip because it is used to chain otherwise 
right-building statements.

e.g. 

List.sum (List.filter isOdd [1, 2, 3])

vs

[1, 2, 3]
|> List.filter isOdd
|> List.sum

Pipe is inherently right-building, so operations like subtract or string 
concatenation are not suitable for it since they are only left associative.

List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick 
The "

On Friday, December 9, 2016 at 1:05:56 AM UTC-6, Aaron VonderHaar wrote:
>
> What's confusing here is how currying works with infix operators.  It's 
> idiomatic in Elm to have your accumulator be the last argument, and, for 
> instance, if you were writing your own data type, you would want to write 
> your functions so that they can be chained together easily:
>
> myMatrix
> |> scale 2
> |> subtract 5
> |> subtractMatrix myOtherMatrix
> |> normalize
>
>
> But as an infix operator (-) is not able to follow that convention;
>
> 5
> |> (-) 3
> |> (-) 1
>
> is confusingly equivalent to `(1 - (3 - 5))` rather than to `5 - 3 - 1`
>
>
> If you had a function `subtract` such that
>
> 5 |> subtract 3 |> subtract 1 == (5 - 3 - 1)
>
> then you could use that function with fold as you intend
>
> List.foldl subtract 0 [1, 2, 3, 4]  ==  -10
>
> You can achieve the same result with
>
> List.foldl (flip (-)) 0 [1, 2, 3, 4]  ==  -10
>
>
> Another way to put it is, in Elm, folds expand in the following way:
>
> List.foldl f x [b, c, d]  ==  x |> f b |> f c |> f d 
> List.foldr f x [b, c, d]  ==  f b <| f c <| f d <| x
>
>
> On Thu, Dec 8, 2016 at 7:50 PM, Kasey Speakman <kjspe...@gmail.com 
> > wrote:
>
>> (deleted and corrected original post with proper expansion of Elm's foldl)
>>
>> I know this is a really old thread, but I ran into this precise question 
>> and thought I would add a perspective.
>>
>> The form a -> b -> b is not left-building, regardless of the direction 
>> you are traversing the list.
>>
>> An example: Starting from zero, subtract the numbers 1, 2, and 3. The 
>> expected answer is -6.
>>
>> List.foldl (-) 0 [1, 2, 3]
>> -> returns -6 in Haskell (well, actually tested in F# which uses same 
>> order as Haskell)
>> expands to: ((0 - 1) - 2) - 3 = -6
>> -> returns 2 in Elm
>> expands to: 3 - ((1 - 0) - 2)
>>
>> Elm's expansion is wonky for this. It appears to be center-building:
>> List.foldl (-) 0 [1] -- returns 1, expands 1 - 0
>> List.foldl (-) 0 [1, 2] -- returns -1, expands (1 - 0) - 2
>> List.foldl (-) 0 [1, 2, 3] -- returns 2, expands 3 - ((1 - 0) - 2)
>> List.foldl (-) 0 [1, 2, 3, 4] -- returns -2, expands (3 - ((1 - 0) - 
>> 2)) - 4
>>
>> When a and b are the same type it will only return the correct answer if 
>> the fold operation is also commutative or if flip is used to correct the 
>> ordering. When a and b are not the same type, the compiler will provide an 
>> error for wrong ordering of course.
>>
>> I started out on the side that a -> b -> b was correct as that feels like 
>> proper "reduction" or chainable syntax. But after exploring it, it is 
>> clearly not left-building. Makes sense when you consider this form is used 
>> with pipe to convert right-building operations into left-reading code. e.g. 
>> a 
>> |> f |> g |> h instead of h (g (f a))
>>
>> On Tuesday, July 16, 2013 at 6:13:01 AM UTC-5, Evan wrote:
>>>
>>> Gotcha, I definitely see the reasoning :)
>>>
>>>
>>> On Tue, Jul 16, 2013 at 12:54 PM, Balazs Komuves <bkom...@gmail.com> 
>>> wrote:
>>>
>>>>
>>>> I was not engaging in debate, religious or not (though I tend to have 
>>>> very strong opinions about these questions). I was explaining why I think 
>>>> Haskell uses the order it uses (because it is distinguished from a 
>>>> mathematical viewpoint). Of course you are not required to follow that 
>>>> convention, I was just pointing out that it is not simply an ad-hoc choice.
>>>>
>>>> Balazs
>>>>
>>>>
>>>>
>>>> On Tue, Jul 16, 2013 at 12:21 PM, Evan Czaplicki <eva...@gmail.com> 
>>>> wrote:
>>>>
>>>>> I think this might be a religious 

[elm-discuss] Re: fold function argument order

2016-12-08 Thread Kasey Speakman
(deleted and corrected original post with proper expansion of Elm's foldl)

I know this is a really old thread, but I ran into this precise question 
and thought I would add a perspective.

The form a -> b -> b is not left-building, regardless of the direction you 
are traversing the list.

An example: Starting from zero, subtract the numbers 1, 2, and 3. The 
expected answer is -6.

List.foldl (-) 0 [1, 2, 3]
-> returns -6 in Haskell (well, actually tested in F# which uses same order 
as Haskell)
expands to: ((0 - 1) - 2) - 3 = -6
-> returns 2 in Elm
expands to: 3 - ((1 - 0) - 2)

Elm's expansion is wonky for this. It appears to be center-building:
List.foldl (-) 0 [1] -- returns 1, expands 1 - 0
List.foldl (-) 0 [1, 2] -- returns -1, expands (1 - 0) - 2
List.foldl (-) 0 [1, 2, 3] -- returns 2, expands 3 - ((1 - 0) - 2)
List.foldl (-) 0 [1, 2, 3, 4] -- returns -2, expands (3 - ((1 - 0) - 
2)) - 4

When a and b are the same type it will only return the correct answer if 
the fold operation is also commutative or if flip is used to correct the 
ordering. When a and b are not the same type, the compiler will provide an 
error for wrong ordering of course.

I started out on the side that a -> b -> b was correct as that feels like 
proper "reduction" or chainable syntax. But after exploring it, it is 
clearly not left-building. Makes sense when you consider this form is used 
with pipe to convert right-building operations into left-reading code. e.g. a 
|> f |> g |> h instead of h (g (f a))

On Tuesday, July 16, 2013 at 6:13:01 AM UTC-5, Evan wrote:
>
> Gotcha, I definitely see the reasoning :)
>
>
> On Tue, Jul 16, 2013 at 12:54 PM, Balazs Komuves  > wrote:
>
>>
>> I was not engaging in debate, religious or not (though I tend to have 
>> very strong opinions about these questions). I was explaining why I think 
>> Haskell uses the order it uses (because it is distinguished from a 
>> mathematical viewpoint). Of course you are not required to follow that 
>> convention, I was just pointing out that it is not simply an ad-hoc choice.
>>
>> Balazs
>>
>>
>>
>> On Tue, Jul 16, 2013 at 12:21 PM, Evan Czaplicki > > wrote:
>>
>>> I think this might be a religious debate on some level. My first 
>>> functional languages were Scheme 
>>> 
>>>  
>>> and Standard ML . The 
>>> libraries I just linked both use the same argument order for foldl and 
>>> foldr as in Elm. I was raised a certain way and it just stuck in my mind. I 
>>> suspect that everyone prefers the order they learned first because it 
>>> matches their mental model.
>>>
>>> I wrote up a bunch of "reasoning", but really, I am just engaging in the 
>>> religious debate. I'd feel bad deleting it all though, so here is some of 
>>> it:
>>>
>>> OCaml's list library 
>>>  does it 
>>> the way you suggest. I find this order offensive on some level.
>>>
>>> The big questions for "physical" argument order are as follows:
>>>
>>>- What is the type of `fold` or `reduce`? When you fold an unordered 
>>>thing, is it from the right or the left? 
>>>- What is the type of `foldp`? Which way does time go? Is this 
>>>cultural?
>>>
>>> I don't find these questions particularly useful, and I don't think 
>>> programmers should have to wonder about them to use fold and foldp.
>>>
>>> At the end of the day, I chose the types on purpose. I find them easier 
>>> to use, easier to teach, easier to understand. I want to keep them this way.
>>>
>>>
>>> On Tue, Jul 16, 2013 at 10:40 AM, Balazs Komuves >> > wrote:
>>>

 The Haskell version of the foldl is the "right one" in the following 
 sense:

 foldl makes sense in general for left-associative operators, and foldr 
 makes sense for right-associative operators.
 Left-associative operators must have the type (a -> b -> a), while 
 right-associative operators must have type (a -> b -> b).

 I think the fact that you cannot change a foldr to foldl without 
 changing the types is actually an advantage: it forces you to think about 
 which version is the "proper" one, and you cannot accidentally do the 
 wrong 
 one. Of course sometimes it can be inconvenient.

 What I somewhat dislike in the Haskell version of foldr (not foldl), is 
 that while 

 (foldl . foldl . foldl) etc makes sense, (foldr . foldr) does not; for 
 that to work you would have to flip the last two arguments:

 myfoldr :: (a -> b -> b) -> ([a] -> b -> b)
 myfoldr f xs y = foldr f y xs

 But the practicality of this change is debatable, I guess.

 Balazs




 On Wed, Jul 10, 2013 at 4:38 PM, Evan Czaplicki  wrote:

[elm-discuss] Re: fold function argument order

2016-12-08 Thread Kasey Speakman
I know this is a really old thread, but I ran into this precise question 
and thought I would add a perspective.

The form a -> b -> b actually makes the fold right-building, regardless of 
the direction you are traversing the list.

An example: Starting from zero, subtract the numbers 1, 2, and 3. The 
expected answer is -6.

List.foldl (-) 0 [1, 2, 3]
-> returns -6 in Haskell (well, actually tested in F# which uses same order 
as Haskell)
expands to: ((0 - 1) - 2) - 3 = -6
-> returns 2 in Elm
expands to: 3 - (2 - (1 - 0)) = 2-- right-building

Elm's foldl implementation is actually equivalent to a right fold of a 
reversed list. So when a and b are the same type it will only return the 
correct answer if the fold operation is also commutative or if flip is used 
to correct the ordering. When a and b are not the same type, the compiler 
will provide an error for wrong ordering of course.

I started out on the side that a -> b -> b was correct as that feels like 
proper "reduction" or chainable syntax. But after exploring it, it is 
clearly not left-building. Makes sense when you consider this form is used 
with pipe to convert right-building operations into left-reading code. e.g. a 
|> f |> g |> h instead of h (g (f a))

On Tuesday, July 16, 2013 at 6:13:01 AM UTC-5, Evan wrote:
>
> Gotcha, I definitely see the reasoning :)
>
>
> On Tue, Jul 16, 2013 at 12:54 PM, Balazs Komuves  > wrote:
>
>>
>> I was not engaging in debate, religious or not (though I tend to have 
>> very strong opinions about these questions). I was explaining why I think 
>> Haskell uses the order it uses (because it is distinguished from a 
>> mathematical viewpoint). Of course you are not required to follow that 
>> convention, I was just pointing out that it is not simply an ad-hoc choice.
>>
>> Balazs
>>
>>
>>
>> On Tue, Jul 16, 2013 at 12:21 PM, Evan Czaplicki > > wrote:
>>
>>> I think this might be a religious debate on some level. My first 
>>> functional languages were Scheme 
>>> 
>>>  
>>> and Standard ML . The 
>>> libraries I just linked both use the same argument order for foldl and 
>>> foldr as in Elm. I was raised a certain way and it just stuck in my mind. I 
>>> suspect that everyone prefers the order they learned first because it 
>>> matches their mental model.
>>>
>>> I wrote up a bunch of "reasoning", but really, I am just engaging in the 
>>> religious debate. I'd feel bad deleting it all though, so here is some of 
>>> it:
>>>
>>> OCaml's list library 
>>>  does it 
>>> the way you suggest. I find this order offensive on some level.
>>>
>>> The big questions for "physical" argument order are as follows:
>>>
>>>- What is the type of `fold` or `reduce`? When you fold an unordered 
>>>thing, is it from the right or the left? 
>>>- What is the type of `foldp`? Which way does time go? Is this 
>>>cultural?
>>>
>>> I don't find these questions particularly useful, and I don't think 
>>> programmers should have to wonder about them to use fold and foldp.
>>>
>>> At the end of the day, I chose the types on purpose. I find them easier 
>>> to use, easier to teach, easier to understand. I want to keep them this way.
>>>
>>>
>>> On Tue, Jul 16, 2013 at 10:40 AM, Balazs Komuves >> > wrote:
>>>

 The Haskell version of the foldl is the "right one" in the following 
 sense:

 foldl makes sense in general for left-associative operators, and foldr 
 makes sense for right-associative operators.
 Left-associative operators must have the type (a -> b -> a), while 
 right-associative operators must have type (a -> b -> b).

 I think the fact that you cannot change a foldr to foldl without 
 changing the types is actually an advantage: it forces you to think about 
 which version is the "proper" one, and you cannot accidentally do the 
 wrong 
 one. Of course sometimes it can be inconvenient.

 What I somewhat dislike in the Haskell version of foldr (not foldl), is 
 that while 

 (foldl . foldl . foldl) etc makes sense, (foldr . foldr) does not; for 
 that to work you would have to flip the last two arguments:

 myfoldr :: (a -> b -> b) -> ([a] -> b -> b)
 myfoldr f xs y = foldr f y xs

 But the practicality of this change is debatable, I guess.

 Balazs




 On Wed, Jul 10, 2013 at 4:38 PM, Evan Czaplicki  wrote:

> It's partly about composability (i.e. the data structure should be 
> last).
>
> It is also about reuse. In Elm it is valid to say:
>
> foldl (::) []
> foldr (::) []
>
> If I want to change the order of my traversal, I should not *also* need 

[elm-discuss] Re: Svelte for components?

2016-11-30 Thread Kasey Speakman
The best parts of it seem to be its compiler (performance and dead branch 
trimming of compiled code). Otherwise, it looks like a similar machination 
to Angular 1. (HTML-based templates, mustaches, two-way binding, 
directives).

Component-orientedness = object-orientedness. The same refactoring problems 
with mutable state and effectful functions still apply. Elm isn't 
component-resistant just to be dogmatic about FP. It's actually providing a 
large maintainability advantage (with immutable data and pure functions) 
that happens to make it hard to do stateful components.

Beyond a low-level tricks they might be using, I doubt the compiler can be 
generalized to other compile-to-JS languages, as it will be expecting Svelt 
framework sprinkles.

On Wednesday, November 30, 2016 at 12:01:27 PM UTC-6, Duane Johnson wrote:
>
> There's been some ongoing discussion about components (web components, 
> simplifying design with component re-use, etc.) and I saw this introduction 
> to Svelte today:
>
> https://svelte.technology/blog/frameworks-without-the-framework/
>
> It seems like a compiler that produces bare-metal components by separating 
> data from rendering. There may be some compatibility with Elm if it is 
> possible to let Elm control the data and leave the rendering to Svelte.
>
> Has anyone taken a look at it yet?
>
> Duane
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: What do you think about Eve?

2016-11-14 Thread Kasey Speakman
The literate programming part and IDE seem pretty compelling. However the 
language itself looks to be another imperative, mutation 
-based language.

The language is pretty brilliant. It's really a database programming model, 
but the "database" also allows effects/functions/etc to be saved as data. 
For instance, in the commit docs  an 
example saves an http request and then also saves a listener for when it 
completes. Seems like something a DBA might feel comfortable programming 
with.

In the end, I think Elm's refactor-ability (due to user code being purely 
functional and immutable) is a crucial attribute that Eve does not match. 
And someone could conceivably design an IDE for literate programming on top 
of existing languages like Elm.

But that's just from skimming through the docs and examples.

On Monday, November 14, 2016 at 5:21:44 PM UTC-6, Erkal Selman wrote:
>
> I wonder, what the elm community thinks about Eve: http://witheve.com/ ?
> Here is the syntax reference: 
> https://witheve.github.io/assets/docs/SyntaxReference.pdf
>
> I think that this language/architecture is worth to look at.
> It has many similarities with elm.
> But it is more like logic programming. (Is this the logic programming of 
> the future?)
>
> I was following this project from far and I had the impression that he 
> (Chris Granger) was doing some kind of excel.
> But now I see that they can do flappy bird in eve: 
> http://play.witheve.com/#/examples/flappy.eve
> That is exciting!
>
> Is there something similar to Eve?
> It really looks like something new.
>
> My main question: 
> What do you think, are advantages and disadvantages of Eve, if you compare 
> it with Elm.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] port Maybe field behavior

2016-11-11 Thread Kasey Speakman
Yes, indeed. Thanks for pointing me to that.

On Thursday, November 10, 2016 at 11:13:08 PM UTC-6, Janis Voigtländer 
wrote:
>
> Isn't that exactly the following issue?
>
> https://github.com/elm-lang/core/issues/476
>
>
> Am 11.11.2016 um 04:41 schrieb Max Goldstein  >:
>
> I also think this is reasonable, although it's possible there's something 
> I'm missing.
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to elm-discuss...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Localstorage data migration

2016-11-08 Thread Kasey Speakman
I would additionally make each migration function only go from one version 
to the next version up. Then chain them together up to the latest version. 
That way you only have to make 1 migration function for each version bump 
and leave the others untouched and still upgrade from any previous version.

I think you'd have to have an intermediate format for the migration... like 
first decode whatever was stored into a Dict String Value. Then only 
decode, modify, and re-encode the changed model parts in each migration 
method. Then at the end, take the Dict String Value and decode that into 
the current model.

loadModel : String -> Dict String Value -> Result String Model
loadModel dataVersion d =
case dataVersion of
"0.0.1" ->
Dict.insert "aNewProperty" (Encoder.string "A Default Value") d
|> loadModel "0.0.2"

"0.0.2" ->
Dict.remove "anOldProperty" d
|> loadModel "0.0.3"

// at latest version
"0.0.3" ->
decodeModelFromDict d

_ ->
Result.Err "Invalid Version"


This is just an idea. I haven't tried it.

On Tuesday, November 8, 2016 at 9:20:56 AM UTC-6, Peter Damoc wrote:
>
> You could load the raw data into the app using Value instead of whatever 
> you have now and create a series of Json Decoders for each version of the 
> schema. 
> You could then use Json.Decode.oneOf to produce the current structure 
> from any of the old schemas. 
>
> You could also use a schema version field on the data and then do the 
> decoding in two parts using Json.Decod.andThen 
>
>
>
>
> On Tue, Nov 8, 2016 at 5:02 PM, Jacky See  > wrote:
>
>> I have an Elm app that would store the entire model into the local 
>> storage, using `programWithFlags` to feed in the data directly when `init`.
>> As the app develop, more fields is added to the model so there will be 
>> model mismatch between localStorage and the new model and Elm would fail at 
>> the JS side when trying to init.
>> Obviously, there should be some migration plan here at the js side to 
>> update the stored model to the new shape.
>> Personally, I wish I could have something like Json.Decode to handle the 
>> model directly in Elm, maybe peform a task?
>> What would you guys recommend to do?
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Fetch an element in a list from a parent module and render it in a child module

2016-11-07 Thread Kasey Speakman
With multi-selection, I put a `selected : Bool` on the item itself. When 
you reload a list, you can just default it to false.

On Monday, November 7, 2016 at 12:01:26 PM UTC-6, Rickey Barnes wrote:
>
> That sounds like a better way than what I was thinking. Although I don't 
> think it would work if you wanted to show multiple detail sections. For 
> example if you clicked on 2 different contacts, but you didn't want the 
> previous details to disappear with the new selection. 

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Fetch an element in a list from a parent module and render it in a child module

2016-11-07 Thread Kasey Speakman
What I've done is this:


   - Change the Model to have selectedContactId
   - Change renderContact to also take in the currently selected ID
   

|> List.map (renderContact model.selectedContactId)

The renderContact function can check if the selectedContactId is equal to 
the current item's ID and render it checked if so.

You can also add an onClick function to change the selectedContactId.

On Sunday, November 6, 2016 at 3:00:05 AM UTC-6, Did wrote:
>
> Hi there,
>
> is there a way for a parent module to "subscribe" to a child module 
> "event"? Here is the thing : I want to create a contact list. For that, I 
> have a component named ContactList. Inside, I display all contacts like 
> this :
>
> renderContact: Contact.Model -> Html a
> renderContact contact =
> li [] [Contact.view contact]
>
> renderContacts: Model -> Html a
> renderContacts model =
> model.contacts
> |> List.map renderContact
> |> ul []
>
> view: Html a
> view =
> div [] [
> renderContacts model
> ]
>
> You can see that a contact is rendered by the Contact module, like this :
>
> type alias Model = {
> firstname  : String
>,name   : String
>,phonenumber: String
> }
>
> view: Model -> Html a
> view model =
>  span[]
>  [
>  a [style contactfield] [text <| model.firstname ++ " " ++ 
> model.name]
> ,span [style contactfield] [text <| model.phonenumber]
>  ]
>
> I would like to interact with the "a" element so that when the user click 
> on it, it displays details about the selected contact. I started to write 
> something like this :
>
> type alias Model = {
> id: Int
>,firstname  : String
>,name   : String
>,phonenumber: String
> }
>
> view: Model -> Html a
> view model =
>  span[]
>  [
>  a [style contactfield, on "click" (Json.map fetchDetail 
> decodename), attribute "data-value" model.id)] [text <| model.firstname 
> ++ " " ++ model.name]
> ,span [style contactfield] [text <| model.phonenumber]
>  ]
>
> Here, my model has improved with a new property : id. But the Contact 
> module is not aware of any list of contacts, so I can't apply any filter in 
> order to fetch the desired contact. Is there a way to simply realize this? 
> Or maybe I'm on a totally wrong way...
>
> Thanks!
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Best place to find elm devs?

2016-11-07 Thread Kasey Speakman
Best place to find them: make them.

Hire candidates who show promise and give them some time to train on Elm. 
It's pretty easy to learn and pretty forgiving to refactor.

On Friday, November 4, 2016 at 6:04:05 PM UTC-5, aar...@enfluid.com wrote:
>
> Hi there! 
>
> I’m here to ask what's the best place to find Elm developers, ideally with 
> test driven development background.  Any ideas? 
>
> Thanks!
> Aaron
> aar...@enfluid.com 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Is a decoder the right level of abstraction for parsing JSON?

2016-11-03 Thread Kasey Speakman
I first started using Elm's recommended codec-ing scheme. I found that if I 
needed to round-trip an entity to an API, I needed *4 representations* of 
the same entity. One on the client and one on server is given. But then 1 
encoder representation and 1 decoder representation... both of which spell 
out the same information in the type alias. So in order to change the 
entity, I have 4 places that need maintenance. *No thanks.*

Abusing ports, I arrived at a similar solution to what I explained 
previously in this thread for decoding. But since encoding is also monkey 
work, I wanted to abuse ports to launder that too. However, the process to 
do that was herky-jerky. A port/sub round trip for encoding, then an Elm 
HTTP call, then a port/sub round trip for decoding. Instead, I abandoned 
the Elm HTTP library altogether. I added in a fetch polyfill (whatwg-fetch 
<https://github.com/github/fetch>) and run the HTTP call in JS.

Here is a gist. 
<https://gist.github.com/kspeakman/3653ae489c62c4d60c9ba9a9c19fd30b>

*Notes*

The JS fetch code could be generalized/improved even more, but this is all 
I need for calling my own APIs. Once tweaked and running for its intended 
use, it will rarely need to be touched.

Outgoing ports start with 'api' so that the startup code knows to wire them 
up. If Elm would let me, I would define only one outgoing port as `*port 
apiRequest : Request a -> Cmd msg*`, but that doesn't compile.

Overhead per API method is around 5 lines of code. One outgoing port, 2 
incoming ports (1 success, 1 fail), and 2 for adding incoming ports to 
subscriptions list.

Most importantly, if my messages change, I only have 2 places to update 
them: client model and server model. No encoder/decoder maintenance.

Using strings to represent incoming ports is not ideal, but shouldn't need 
that much maintenance and are private.

Just starting to explore this, so maybe there is some blocking situation I 
haven't discovered yet.

On Tuesday, October 4, 2016 at 10:37:41 AM UTC-5, Vojtěch Král wrote:
>
> Awesome! I'll try it out...
> Thanks!
> Vojtech
>
> Dne úterý 4. října 2016 16:36:37 UTC+2 Kasey Speakman napsal(a):
>>
>> I haven't done this yet as we're developing the UI first as things take 
>> shape and faking the API calls with Process.sleep + Task.perform. So below 
>> is just a sketch.
>>
>> Conceptually, you could use `Http.getString` (or construct a request and 
>> use `Http.send`) in Elm to get the JSON, then send that through a port to 
>> JavaScript. You'd need at least one outgoing port, and an incoming port for 
>> every result type.
>>
>> port deserializeJson : String -> String -> Cmd msg
>>
>>
>> port studentsLoaded : (List Student -> msg) -> Sub msg
>>
>> port coursesLoaded : (List Course -> msg) -> Sub msg
>>
>>
>> subscriptions : Model -> Sub Msg subscriptions model = Sub.batch [ 
>> studentLoaded StudentsLoaded , courseLoaded CoursesLoaded ] 
>>
>>
>> On the outgoing port, you could pass both the JSON and the incoming port 
>> name as a string. Then in the JS, you could wire it once like this:
>>
>> app.ports.deserializeJson.subscribe(function(port, json) {
>> // TODO can throw, so catch error and send to an error port
>> var object = JSON.parse(json);
>> app.ports[port].send(object);
>> });
>>
>>
>> Once you get the HTTP response string from a particular request, you send 
>> it through the outgoing port with the correct return path.
>>
>> deserializeJson "studentLoaded" json
>>
>> It looks like after initial setup, each deserialization would take ~3 
>> lines of wiring code. So it might not be worth it for small objects. But 
>> again this is just a sketch that I haven't tried to run.
>>
>> On Tuesday, October 4, 2016 at 6:40:08 AM UTC-5, Vojtěch Král wrote:
>>>
>>> I have the same problem. Would someone be so kind as to give an example 
>>> of how to launder the JSON via ports like this? Do you just rut the data 
>>> through a port, or do you do ajax in JS?
>>> Thanks! 
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-11-02 Thread Kasey Speakman
On Wednesday, November 2, 2016 at 4:50:21 AM UTC-5, Rupert Smith wrote:
>
> On Tuesday, November 1, 2016 at 5:54:10 PM UTC, Kasey Speakman wrote:
>>
>> In a new project, we are going for something like this.
>>
>>
>> https://www.youtube.com/watch?v=GneIxgl71NM=18=PL9Z-JgiTsOYTdi91N_DlcpWqkCYvMrhA4
>>
>
> What sort of throughput in events/sec are you aiming to support? 
>

Initially, the load will be small and our cloud-provisioned resources will 
reflect that. It will necessarily be multi-tenant and we've had a lot of 
interest expressed among clients. So there is a great potential for growth.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-11-02 Thread Kasey Speakman
On Tuesday, November 1, 2016 at 3:31:07 AM UTC-5, Peter Damoc wrote:
>
> On Tue, Nov 1, 2016 at 2:25 AM, Kasey Speakman <kjspe...@gmail.com 
> > wrote:
>>
>> So here's a concrete example of how we did it wrong in our legacy system. 
>> To close a trainee's registration as "No Show", an employee has to create 
>> an exam against that registration and grade it as 1%. This is an implicit 
>> concept which our employees and our software understand as "No Show". 
>> Instead of making it explicit by programming in a No Show 
>> button/action/status, we have to *program the employees* (current and 
>> future) to recognize this situation.
>>
>
> Wow... this is so silly that it almost looks like a joke. Unfortunately, 
> I've seen enough to know that it happens. 
>

After thinking on this, I can tell you exactly how it happens. The program 
was made on a contract basis, so either the contractor didn't discover the 
No Show use case, or it was not in the business processes at the time it 
was implemented. Later, a user in charge decides they themselves can 
implement a No Show feature without going through contracting by making 
policy around the data. "If you see a grade of 1, that means it was a No 
Show." The user probably congratulates themselves for saving money. This 
kind of thinking leads to more of this. And that's where we are.

Sometimes this kind of shortcut might be the only way to get things done 
under time/budge pressure, from the user's perspective.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-11-01 Thread Kasey Speakman
In a new project, we are going for something like this.

https://www.youtube.com/watch?v=GneIxgl71NM=18=PL9Z-JgiTsOYTdi91N_DlcpWqkCYvMrhA4

On Tuesday, November 1, 2016 at 10:00:36 AM UTC-5, Kasey Speakman wrote:
>
> On Tuesday, November 1, 2016 at 9:53:55 AM UTC-5, Rupert Smith wrote:
>>
>> ...
>> There is clever stuff we can do with the data-centric approach, in terms 
>> of using generic CRUD APIs, or tailoring graphql expressions to fetch or 
>> update particular paths in the data model. It is a bit harder to see how 
>> clever tricks can be used to cut down the larger amount of work that needs 
>> to be done with the service-oriented approach. I think by shifting from 
>> doing the clever bit at runtime to doing it at compile time and using code 
>> generation techniques, it is doable.
>>
>
>
> http://softwareengineering.stackexchange.com/questions/25276/why-is-cleverness-considered-harmful-in-programming-by-some-people/25281
>  
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-11-01 Thread Kasey Speakman
On Tuesday, November 1, 2016 at 9:53:55 AM UTC-5, Rupert Smith wrote:
>
> ...
> There is clever stuff we can do with the data-centric approach, in terms 
> of using generic CRUD APIs, or tailoring graphql expressions to fetch or 
> update particular paths in the data model. It is a bit harder to see how 
> clever tricks can be used to cut down the larger amount of work that needs 
> to be done with the service-oriented approach. I think by shifting from 
> doing the clever bit at runtime to doing it at compile time and using code 
> generation techniques, it is doable.
>

http://softwareengineering.stackexchange.com/questions/25276/why-is-cleverness-considered-harmful-in-programming-by-some-people/25281
 

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-11-01 Thread Kasey Speakman
On Tuesday, November 1, 2016 at 9:36:36 AM UTC-5, Rupert Smith wrote:

> On Tuesday, November 1, 2016 at 1:16:40 PM UTC, Kasey Speakman wrote:
>>
>> It is silly, and I don't know why it was done this way. But that's the 
>> world I live in now. It's easy to justify one case at a time, but all 
>> tolled it adds up.
>>
>> As far as "layers", you should check out these two posts in order.
>>
>>
>> http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same/
>>
>> http://blog.ploeh.dk/2016/03/18/functional-architecture-is-ports-and-adapters/
>>
>
> I think people who write code like this must get paid by the line. A 
> couple of years ago I worked some overtime over Christmass/New Year to 
> refactor a system like this that was getting out of control. In 5 days I 
> turned 10,000 lines of code with layers into 1,000 lines of code with just 
> 1 layer that did exactly the same thing - then booked myself a cheap 
> holiday in early January to enjoy my TOIL.
>
> I'm not saying its always the right answer, but when someone tells you 
> that you must have lots of layers, I would always question them and their 
> motives. 
>

I used to think that too. But then I fell into all the traps doing things 
naively and over time found myself moving towards similar things to the 
blog. Of course, such an OO architecture is not worth doing in every 
case... only in critical cases.

Then I eventually found functional programming. And if you read the 
followup post about "functional architecture", much of the overhead of 
"ports and adapters" is no longer present when it's done functional. For 
instance, single method interfaces are common in "ports and adapters" in OO 
languages, but in FP those are just functions. You probably don't even need 
to define a type alias. You get the benefits of dependency injection with 
almost none of the traditional overhead as seen in OO "ports and adapters".

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-11-01 Thread Kasey Speakman
Oh, and yes, most of these layers are on the server side if we are talking 
about an Elm client application. Generally speaking, the client app serves 
to collect and prepare data to submit use cases. So it reads data from an 
API and submits data to an API.

On Tuesday, November 1, 2016 at 8:16:40 AM UTC-5, Kasey Speakman wrote:
>
> It is silly, and I don't know why it was done this way. But that's the 
> world I live in now. It's easy to justify one case at a time, but all 
> tolled it adds up.
>
> As far as "layers", you should check out these two posts in order.
>
>
> http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same/
>
> http://blog.ploeh.dk/2016/03/18/functional-architecture-is-ports-and-adapters/
>
> On Tuesday, November 1, 2016 at 3:31:07 AM UTC-5, Peter Damoc wrote:
>>
>> On Tue, Nov 1, 2016 at 2:25 AM, Kasey Speakman <kjspe...@gmail.com> 
>> wrote:
>>>
>>> So here's a concrete example of how we did it wrong in our legacy 
>>> system. To close a trainee's registration as "No Show", an employee has to 
>>> create an exam against that registration and grade it as 1%. This is an 
>>> implicit concept which our employees and our software understand as "No 
>>> Show". Instead of making it explicit by programming in a No Show 
>>> button/action/status, we have to *program the employees* (current and 
>>> future) to recognize this situation.
>>>
>>
>> Wow... this is so silly that it almost looks like a joke. Unfortunately, 
>> I've seen enough to know that it happens. 
>>
>> However, looking at a fresh system that one might want to design it seams 
>> to me like there are 3 possible layers 
>>
>> Layer 3. Business Objects Layer - concerned with validity of state 
>> transactions 
>> Layer 2. Data Modeling Layer - concerned with what needs to be persistent 
>> Layer 1. Storage Layer - concerned with connections, locations, raw 
>> entity storage 
>>
>> Layer 1 would be the implementation of the library I would like to have 
>> in Elm. Ideally, something similar to Datomic.  
>> Layer 2 would be implemented by the user using Layer 1 in a declarative 
>> way similar to Json.Decode 
>> Layer 3 would be implemented by the user using Layer 2 in a way that is 
>> similar to the Elm Architecture (layer 2 Model + some update) 
>>
>> What do you think? 
>> Am I misunderstanding what you described? 
>>
>>
>> -- 
>> There is NO FATE, we are the creators.
>> blog: http://damoc.ro/
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-11-01 Thread Kasey Speakman
It is silly, and I don't know why it was done this way. But that's the 
world I live in now. It's easy to justify one case at a time, but all 
tolled it adds up.

As far as "layers", you should check out these two posts in order.

http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same/
http://blog.ploeh.dk/2016/03/18/functional-architecture-is-ports-and-adapters/

On Tuesday, November 1, 2016 at 3:31:07 AM UTC-5, Peter Damoc wrote:
>
> On Tue, Nov 1, 2016 at 2:25 AM, Kasey Speakman <kjspe...@gmail.com 
> > wrote:
>>
>> So here's a concrete example of how we did it wrong in our legacy system. 
>> To close a trainee's registration as "No Show", an employee has to create 
>> an exam against that registration and grade it as 1%. This is an implicit 
>> concept which our employees and our software understand as "No Show". 
>> Instead of making it explicit by programming in a No Show 
>> button/action/status, we have to *program the employees* (current and 
>> future) to recognize this situation.
>>
>
> Wow... this is so silly that it almost looks like a joke. Unfortunately, 
> I've seen enough to know that it happens. 
>
> However, looking at a fresh system that one might want to design it seams 
> to me like there are 3 possible layers 
>
> Layer 3. Business Objects Layer - concerned with validity of state 
> transactions 
> Layer 2. Data Modeling Layer - concerned with what needs to be persistent 
> Layer 1. Storage Layer - concerned with connections, locations, raw entity 
> storage 
>
> Layer 1 would be the implementation of the library I would like to have in 
> Elm. Ideally, something similar to Datomic.  
> Layer 2 would be implemented by the user using Layer 1 in a declarative 
> way similar to Json.Decode 
> Layer 3 would be implemented by the user using Layer 2 in a way that is 
> similar to the Elm Architecture (layer 2 Model + some update) 
>
> What do you think? 
> Am I misunderstanding what you described? 
>
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-10-31 Thread Kasey Speakman

>
> "Explicit is better than implicit." 

-- Tim Peters


So the main way "data-centric" happens is by modeling behaviors implicitly 
in the data. A common example is an item being active or not. I often model 
this as a boolean property "isActive". The usual way to tweak this value is 
to have the user edit the item and toggle that box. So, the problem lurking 
here is that deactivation may, in fact, be a process. If you have to check 
on save `*if oldValues.isActive <> newValues.isActive then // do extra 
de-/re-activation steps*`, that is an indication that you have implicit 
behavior hiding in data. That should be changed to be an explicit action 
the user can perform (e.g. a button in the UI) and have its own use case 
(uri or method call) on the system API. (Imagine this: to cancel your 
Amazon order, you have to edit the order and check the IsCanceled box.)

So here's a concrete example of how we did it wrong in our legacy system. 
To close a trainee's registration as "No Show", an employee has to create 
an exam against that registration and grade it as 1%. This is an implicit 
concept which our employees and our software understand as "No Show". 
Instead of making it explicit by programming in a No Show 
button/action/status, we have to *program the employees* (current and 
future) to recognize this situation.

And this is just one example of probably dozens in our system. Because of 
that, it takes 6 months or more to get someone fully trained to use it 
properly. And even then it's hard for people to keep dozens of cases in 
their head at once, so minor mistakes/inconsistencies can happen easily.

It's also hard to add features and fix bugs in such a system. Not only 
because there's a lot of potential dev time spent on support, but also 
because we programmers can't keep all these implicit behaviors straight 
either. (We often don't know them as well as our users do, because we don't 
work with them every day.) So deployments always carry at least a moderate 
level of risk even when we believe the changes are minor.

Going forward, we refactor these implicit behaviors to be explicit 
actions/API calls as we have feature/bug requests against them. It takes 
more time, but improves quality in the long run. So we are pushing it in 
the right direction, and users generally still manage to make good use of 
it in the mean time.

I should also note that for non-functional reasons, it may not be possible 
to make behaviors explicit. I worked on another project where I was not 
given leave to do this. I figure it was deemed prohibitively expensive, 
because I would need too much time with subject matter experts. Such is 
life.

On Monday, October 31, 2016 at 10:36:24 AM UTC-5, Peter Damoc wrote:
>
> On Mon, Oct 31, 2016 at 5:24 PM, Kasey Speakman <kjspe...@gmail.com 
> > wrote:
>
>> There is a danger in focusing on data over use cases. It's not a 
>> guarantee that you make this mistake (I have), but you know you've gone too 
>> far with it when most workflows are Load/Edit/Save (or Create/Save). And 
>> the user is left to know what field to change to have a specific effect in 
>> the system. I've seen this termed as data-centric. Seems okay at first but 
>> after a few years in production this leads to long user training times, 
>> brittle workflows, and high support loads.
>>
>
> What are the alternatives? How would an approach focused on use cases look 
> like? 
>  
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-10-31 Thread Kasey Speakman


On Friday, October 28, 2016 at 4:58:34 PM UTC-5, Rupert Smith wrote:
>
> On Friday, October 28, 2016 at 6:26:46 PM UTC+1, Kasey Speakman wrote:
>>
>> As best I can, I try to look at the system as use cases and events.
>>
>> With legacy systems, we are tied to a normalized data model (which is 
>> really designed for writing and not reading), so for queries we have to 
>> "project" from that normalized data model into another model.
>>
>
> My understanding of normalization is that its purpose is to avoid 
> duplicating data, and by avoiding duplication reduce the chance of errors 
> in order to help ensure the quality of stored data.
>

Yes, these are benefits of normalization. However, normalization optimizes 
for writing. Reads become more expensive due to joining in all the relevant 
details you need to service a particular query. In most business systems, 
multiple reads are performed for every write performed. It's a minor point 
for most business systems I've been a part of. However, I do currently have 
a couple of views where the reads became too expensive and it was better to 
maintain a denormalized read model alongside the normalized version. You 
might recognize this as a periodically-run report. But when I use events 
internally, I can have the report be updated cheaply as each event occurs 
rather than projected expensively from the normalized form.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-10-31 Thread Kasey Speakman
There is a danger in focusing on data over use cases. It's not a guarantee 
that you make this mistake (I have), but you know you've gone too far with 
it when most workflows are Load/Edit/Save (or Create/Save). And the user is 
left to know what field to change to have a specific effect in the 
system. I've seen this termed as data-centric. Seems okay at first but 
after a few years in production this leads to long user training times, 
brittle workflows, and high support loads.

Most businesses invest in custom software to accelerate businesses 
processes. So those should be the focus. For just data storage, low-code 
solutions could do that much cheaper. That said, CRUD is a part of almost 
all custom software because data must be collected to fulfill use cases 
(usually for the human factor, like seeing names instead of just IDs). 
Often the easiest place to start is with CRUD, because you need a way to 
populate data to work with anyway. But the database structure is the wrong 
thing to center a design on.

On Saturday, October 29, 2016 at 8:34:48 AM UTC-5, Rupert Smith wrote:
>
> On Friday, October 28, 2016 at 10:58:34 PM UTC+1, Rupert Smith wrote:
>>
>> For example, if a user account must have an email address associated with 
>> it, if there is validation on the format of the email address and it cannot 
>> be null, then there is not need to write a specific transactional end-point 
>> to allow a user to update their email address, you can just let them modify 
>> and save the account record and they can still only perform that operation 
>> in a way that produces correct data.
>>
>> I take your point though about being able to hook into changes relating 
>> to specific events.
>>
>
> I inadvertently picked an example with the email address that shows why 
> you want to hook into specific business events, because in this case you 
> might want to send a confirmation email with a link in it to confirm the 
> address when the email address is changed. In that case I would not allow 
> the email address to be set as part of a more generic 'save' endpoint, and 
> add a new end-point for the change email address as its own operation. Its 
> either that or add some code to detect the email change somehow - but I 
> think you are right, it better to have an explicit endpoint for it, then 
> very easy to hook into it as an 'event'. I like to start quickly by 
> starting with the open and generic data modelling with CRUD over entities, 
> and then refine things from there.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-10-28 Thread Kasey Speakman
As best I can, I try to look at the system as use cases and events.

With legacy systems, we are tied to a normalized data model (which is 
really designed for writing and not reading), so for queries we have to 
"project" from that normalized data model into another model. But the place 
I'd really like to get to is storing the system's events, and creating 
whatever models are necessary to answer queries and fulfill use cases from 
those events. AKA Event Sourcing 
<http://docs.geteventstore.com/introduction/3.9.0/event-sourcing-basics/>. 
I am finally getting to do this on a new project. Our existing systems will 
stay with a normalized data model for the foreseeable future as the cost of 
change is too high.

But I still try to take the principles of using business-specific events 
(like StudentRegistered or PaymentDeclined) in my business logic, then 
translate those into database calls when they are sent for persistence. 
That also allows me to use those events to update secondary models or 
trigger other logic. The common alternative, just updating state and doing 
`repository.Save()` makes it harder to hook into specific business 
happenings.

On Wednesday, October 26, 2016 at 3:23:44 PM UTC-5, Rupert Smith wrote:
>
> On Tuesday, October 25, 2016 at 3:12:53 PM UTC+1, Kasey Speakman wrote:
>>
>> So to phrase what I previously said a different way, a database is the 
>> wrong level of abstraction to be shooting for. 
>>
>  
> Yes, I think you are right. Much better if we can just think about the 
> data model we need, and have some completely automated way of persisting it.
>
> I was just thinking, with reference to "Making Impossible States 
> Impossible", typed functional languages have some appealing aspects as a 
> foundation for describing data models.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Metalinguistic abstractions over databases

2016-10-25 Thread Kasey Speakman
So to phrase what I previously said a different way, a database is the 
wrong level of abstraction to be shooting for. A database is just one 
integration that most business systems have.

The system itself exposes use cases and queries. Whether and which 
databases are involved (and their structural details, I contend) should be 
of no concern to client apps. The client apps exist to help the user 
fulfill the system's use cases, not just to connect to a database.

On Tuesday, October 25, 2016 at 6:02:45 AM UTC-5, Rupert Smith wrote:
>
> On Tuesday, October 25, 2016 at 10:01:48 AM UTC+1, Peter Damoc wrote:
>>
>> On Tue, Oct 25, 2016 at 11:27 AM, 'Rupert Smith' via Elm Discuss <
>> elm-d...@googlegroups.com> wrote:
>>
>>> If your 'persistence API' requires the application to behave correctly 
>>> in order to not store invalid or maliciously altered data, you cannot 
>>> guarantee that. 
>>>
>>
>> This actually sounds more like a challenge to be faced rather that a 
>> technical impossibility. 
>> Maybe some kind of declarative access control embedded in a shared schema 
>> could solve this. 
>>
>
> Declaring what the access rights are to the client UI is useful, yes - it 
> is just that they still need to be enforced by the server because you 
> cannot fully trust the client to take care of it. This is actually what I 
> am doing (in some cases), because when a user logs in they get back a JWT 
> token. This token contains some information about who the user is, and what 
> permissions they have. The UI can use this to only render screens and 
> functionality that the user is allowed to use. This is merely to be helpful 
> and provide a nice user experience, the permissions are always checked 
> whenever a restricted API endpoint is invoked.
>
> I don't always use the JWT tokens as bearer tokens in an HTTP 
> Authorization header field, or as a secure cookie because they can grow 
> quite large. However, I generally do provide an endpoint in my API where 
> the JWT token can be requested in order to inspect the users declared 
> access rights.
>  
>
>>  I do think that these server side responsibilities are not really within 
>>> the domain of Elm.
>>
>>
>> Look at what happened with Javascript. Once it got useful in the client 
>> people wanted it on the server and then we got Node. 
>> We are nowhere near the popularity of javascript and yet, I already see 
>> frequent enough questions about using Elm on the server-side. 
>>
>> There are two ways to address this: 
>> 1. allocating resources to making Elm viable on the server
>> 2. making the server part as small and automatic as possible as to not 
>> require much coding. 
>>
>> To me, option 2 is much more attractive. 
>>
>
> Ok, I think I now get a better idea of what you are after.  As per John 
> Kellys PostgREST code: https://github.com/john-kelly/elm-postgrest. Have 
> a way of defining a data model in Elm, and use that description to 
> automatically generate a suitable server to persist it.
>
> In this case defining the access rights in the Elm code would be ok, as 
> the server that you generate would also securely check them at runtime.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Proposal: Rename case..of -> match..with

2016-10-20 Thread Kasey Speakman
But `case` is a pattern matcher. Check out how it is used here in lieu of a 
parser.

https://github.com/knewter/time-tracker/blob/master/elm/src/Route.elm#L91

On Thursday, October 20, 2016 at 11:16:49 AM UTC-5, Joey Eremondi wrote:
>
> There's precedence in both directions, case comes from Haskell. So 
> changing it doesn't necessarily mean we'll match everyone else, pardon the 
> pun. 
>
> Being easier for non native English speakers seems pretty subjective, some 
> people might find case more intuitive as non native speakers. 
>
> To me, case is better at capturing the idea of programming by cases, that 
> it's a branching construct, not just a pattern matcher. 
>
> Both have pros and cons, and are roughly equal in my mind, but changing it 
> would break literally all Elm code ever, so I think the status quo wins in 
> this case. 
>
> On Oct 20, 2016 7:56 AM, "OvermindDL1"  
> wrote:
>
> On Thursday, October 20, 2016 at 8:46:42 AM UTC-6, Peter Damoc wrote:
>
>> On Thu, Oct 20, 2016 at 5:06 PM, Robin Heggelund Hansen <
>> skinn...@gmail.com> wrote:
>>
>>> The proposal, as the title of the post suggests, is to rename the 
>>> "case..of" expression to "match..with". 
>>>
>>
>> One added benefit that I'm seeing is that today, if I would have to 
>> describe "case...of", I would use the words "pattern matching". :) 
>>
>> I wonder if this has been discussed before.  I did a quick search but 
>> nothing jumped out as relevant. 
>>
>> > case..of to match..with renaming could be handled by elm-format.
>>
>> in theory, yes, it could be handled by a tool like elm-format but in 
>> practice, in order for it to be effective, it should be handled by 
>> something that is part of the elm-platform. 
>> this kind of a mechanical replacement would be OK if it would be handled 
>> right away and in an official manner. 
>> requiring installing extra tools that come with alpha warnings might be 
>> scary. 
>>
>
> If this were done (plenty of other precedence, OCaml uses `match ... with` 
> too), there could be a deprecation period where both are supported and 
> `case ... of` generated deprecation warnings... 
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to elm-discuss...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Metalinguistic abstractions over databases

2016-10-20 Thread Kasey Speakman
I like to put databases behind APIs. But I don't map URIs directly to 
database entities. I map URIs to use cases and queries. A use case could 
make multiple changes to the system, not just change one table. A query 
doesn't necessarily map to a single entity either. The result of one query 
might contain data from several entities.

So the key here is to use the API like an entry point into your system, NOT 
an entry point into your database.

On Wednesday, October 19, 2016 at 3:54:44 AM UTC-5, Peter Damoc wrote:
>
> *The problem *
>
> I know how to implement a REST API and interrogate that API from Elm but 
> that *seams very low level. *
>
> I was curious about a language abstraction that would isolate my Elm 
> program from the actual database strategy.  
>
> How do you approach dealing with the databases? What is your strategy? 
> What options are there?
> Do you have any pointers to interesting perspective/approaches? 
>
>
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: List.filter -> List.keep?

2016-10-18 Thread Kasey Speakman
I believe filter is a pretty standard name for this. Even Javascript has 
Array.filter 

 
with the same semantics.

In .NET Linq uses `.Where`, but I believe that is mainly to have similarity 
with SQL.

On Tuesday, October 18, 2016 at 2:35:45 PM UTC-5, Duane Johnson wrote:
>
> I saw @_chunglou's tweet 
>  yesterday and 
> wondered if this had been discussed before:
>
> "I can never, ever remember whether `filter` needs `true` or `false`. 
> `keep` would be a nicer name."
>
> I agree `keep` would remove the ambiguity. Thoughts?
>
> -- Duane
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Outgoing port event ordering

2016-10-17 Thread Kasey Speakman
Or how about adding an incoming subscription port when the localStorage 
save finishes. Then you could put something in the model to indicate you 
are waiting to close. Once the save message comes back, check to see if you 
were waiting to close before sending the close message out the other port.

On Monday, October 17, 2016 at 1:50:18 PM UTC-5, Leroy Campbell wrote:
>
> Ahh...I see. Assuming you have some sort of autosave logic, how about two 
> messages: Save and SaveAndQuit? It seems reasonable to me to split the 
> actions this way...Save could be scheduled using Time.every and 
> SaveAndQuit could be both an explicit user interaction and an incoming 
> port message triggered by window.onbeforeunload().
>
> On Monday, October 17, 2016 at 2:26:20 PM UTC-4, David Andrews wrote:
>>
>> The problem initially arose when I had two ports, one of which wrote to 
>> local storage and the other of which closed the window.  Nothing was ever 
>> written to local storage because the window closed first.  The reason I 
>> went with two ports is because those actions are so conceptually different, 
>> and if it were actually just for local storage I would have used a single 
>> port.  If it were not for the fact that JavaScript processing ceases after 
>> calling window.close, the current port implementation would have worked for 
>> me.
>>
>> On Oct 17, 2016 2:03 PM, "Leroy Campbell"  wrote:
>>
>>> From what I can tell, port communication uses Cmd because interop with 
>>> JavaScript isn't necessarily a request-response communication pattern 
>>> (instead, port are pubsub).
>>>
>>> But I do have a question: *Is the underlying problem a need to 
>>> coordinate access to a shared resource in JavaScript? *I ask because 
>>> you mentioned localStorage in your initial message. I imagine you'd instead 
>>> want to leave the coordination in Elm to take advantage of Elm's 
>>> concurrency model (immutable data + message-passing) and have a single port 
>>> to talk to JavaScript.
>>>
>>> On Monday, October 17, 2016 at 3:03:14 AM UTC-4, David Andrews wrote:

 In another discussion, I was pointed to 
 http://faq.elm-community.org/17.html#what-is-the-difference-between-cmd-and-task,
  
 which sheds some light on the issue, but also raises a few questions.

 Specifically:

1. The article mentions that APIs generally expose Task in favor of 
Cmd. Why is the port API a -> Cmd msg instead of a -> Task Never () 
or something like that?
2. Is there a recommended way to pass data to ports in order? I've 
come up with the workaround of sending over only one port per update 
 and 
using Cmd.Extra.message to trigger additional updates immediately, 
but I don't think it's very clean.


 On Monday, October 17, 2016 at 2:39:01 AM UTC-4, Peter Damoc wrote:
>
> On Mon, Oct 17, 2016 at 8:02 AM, Janis Voigtländer <
> janis.voi...@gmail.com> wrote:
>
>> Peter, the problem in David’s case is that the actions he wants to 
>> order execution of are port data sending, and there is no “something 
>> lower 
>> level, like Tasks” for that. The only API available for port data 
>> sending is Cmd-based.
>>
> Ooops... my bad. I should have looked more carefully. 
>
>
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>
 -- 
>>> You received this message because you are subscribed to a topic in the 
>>> Google Groups "Elm Discuss" group.
>>> To unsubscribe from this topic, visit 
>>> https://groups.google.com/d/topic/elm-discuss/cSzJT2-g8Ss/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to 
>>> elm-discuss...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: control structure

2016-10-14 Thread Kasey Speakman
That's great to hear! Whenever I searched for this, I only found an old 
elm-dev post where implementing it was still being talked about.

I haven't really needed to write recursive loops in Elm yet. But in F#, 
I've written a few.

On Thursday, October 13, 2016 at 11:21:50 PM UTC-5, Joey Eremondi wrote:
>
> One current limitation of Elm is that there is no tail call elimination
>
>
> Like Janis says, this is not true, and in most cases, tail-recursive 
> functions will become while-loops in the resulting JS.
>
> For example, consider a list-summing function:
>
> sum : List Int -> Int
> sum =
>   let
> helper accum lst =
>   case lst of
> [] -> accum
> (h :: t) -> helper (h + accum) t
>   in
> helper 0
>
> This gets turned into the following JS in 0.18 (though TCO has been around 
> for a few versions):
>
> var _user$project$Main$sum = function () {
> var helper = F2(
> function (accum, lst) {
> helper:
> while (true) {
> var _p0 = lst;
> if (_p0.ctor === '[]') {
> return accum;
> } else {
> var _v1 = _p0._0 + accum,
> _v2 = _p0._1;
> accum = _v1;
> lst = _v2;
> continue helper;
> }
> }
> });
> return helper(0);
> }();
>
>  
>
> On Thu, Oct 13, 2016 at 9:10 PM, Janis Voigtländer <janis.voi...@gmail.com 
> > wrote:
>
>> Your statement about tail call elimination is wrong. The Elm compiler 
>> does it. 
>>
>> Am 13.10.2016 um 23:38 schrieb Kasey Speakman <kjspe...@gmail.com 
>> >:
>>
>> It probably sounds insane that Elm doesn't have `for` or `while`. It 
>> would to me before exposure to functional programming.
>>
>> There are prebuilt functions for working with collections like List 
>> <http://package.elm-lang.org/packages/elm-lang/core/latest/List> and 
>> Array <http://package.elm-lang.org/packages/elm-lang/core/4.0.5/Array> 
>> which will take care of most needs.
>>
>> When you find you need something a bit more custom, a recursive loop is 
>> the normal way. Those take a little practice to get the feel for them.
>>
>> Often when I write my own recursive loop, I later find that I can 
>> accomplish the same by combining list operations or by just playing with 
>> List.foldr.
>>
>> One current limitation of Elm is that there is no tail call elimination 
>> when using a recursive loop, so if you write your own loop and have a large 
>> list, you can get a stack overflow. In practice, this is not a typical 
>> problem due to other factors. I.e. miles of data on the screen impacts 
>> performance, and is not considered good UX.
>>
>> On Wednesday, October 12, 2016 at 5:52:31 AM UTC-5, Patricia Nicole 
>> Benedicto wrote:
>>>
>>> hi can i ask what is the repetiton control structucture of this 
>>> programming languages?
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: control structure

2016-10-13 Thread Kasey Speakman
It probably sounds insane that Elm doesn't have `for` or `while`. It would 
to me before exposure to functional programming.

There are prebuilt functions for working with collections like List 
 and Array 
 which will 
take care of most needs.

When you find you need something a bit more custom, a recursive loop is the 
normal way. Those take a little practice to get the feel for them.

Often when I write my own recursive loop, I later find that I can 
accomplish the same by combining list operations or by just playing with 
List.foldr.

One current limitation of Elm is that there is no tail call elimination 
when using a recursive loop, so if you write your own loop and have a large 
list, you can get a stack overflow. In practice, this is not a typical 
problem due to other factors. I.e. miles of data on the screen impacts 
performance, and is not considered good UX.

On Wednesday, October 12, 2016 at 5:52:31 AM UTC-5, Patricia Nicole 
Benedicto wrote:
>
> hi can i ask what is the repetiton control structucture of this 
> programming languages?
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Function equality again

2016-10-12 Thread Kasey Speakman
So what's the specific case where you need to verify function reference 
equality?

I suspect that needing this is a symptom of some other problem.

On Wednesday, October 12, 2016 at 11:48:12 AM UTC-5, Mark Hamburg wrote:
>
> As discussed elsewhere, the runtime exception related to function equality 
> comparisons is a lurking time bomb for code that is really only addressed 
> on a multi-developer project by being paranoid both about functions in data 
> structures and use of the equality operator. Both points of paranoia get in 
> the way of writing "good" code. There are other arguments around things 
> like serialization for avoiding using functions in some places, but there 
> are lots of other places where it is extremely useful to put functions in 
> data structures. (Imagine writing an effects manager if it couldn't store 
> functions in its data structures.) 
>
> Full equality tests are, as I understand it, undecidable. That doesn't 
> mean, however, that some limited analysis can't prove equality in most of 
> the conditions that matter. In fact, the existing code doesn't always throw 
> an exception. It only throws an exception if an "allocation identity" test 
> fails. One could extend this to looking at the "code pointer" and 
> allocation identity for the closure values and probably get many of the 
> remaining cases that mattered. It's just a matter of how far one wants to 
> push when trying to prove or disprove equality and I'm not arguing for a 
> particular limit here. 
>
> Rather, I think the central issue is around what happens when we give up. 
> At that point, there are two choices: throw a runtime exception as happens 
> now or return false. As mentioned above and discussed at further length 
> elsewhere, the runtime exception leads to paranoid coding. What are the 
> issues with returning false? The big problem with returning false is that 
> this means that some compiler optimizations might then change cases that 
> returned false without the optimizations into cases that returned true and 
> people become understandably uncomfortable with the possibility that 
> compiler optimizations could change the meaning of programs. And with that, 
> I've more or less wanted a "return false" answer but convinced myself that 
> throwing an exception wasn't unjustified and that maybe what we needed 
> instead was type system support to avoid the issue. 
>
> But then this morning's discussion of the virtual DOM had me realizing 
> that runtime optimizations around when the render-diff-patch algorithm gets 
> run create significant potential for variable program behavior. We embrace 
> these optimizations even though they introduce non-determinism. Now, its 
> non-determinism at the level of the physical DOM rather than the values 
> produced in Elm itself — i.e., runtime v linguistic non-determinism — but 
> its non-determinism in one of the most fundamental parts about how Elm is 
> generally used so that distinction seems somewhat arbitrary. 
>
> I think Elm makes the right call on the DOM. Maybe it should log cases 
> where the DOM logic can recognize that there might be a problem, but I 
> think this is overall a tradeoff worth making. 
>
> But by the same argument, I think Elm programs would be better if the 
> runtime exception for function equality comparisons was replaced with a 
> false result even though it might actually be true. And if it's really 
> irksome, then it could generate a log statement as well. 
>
> Mark 
>
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: No Runtime Exceptions - Still not computing

2016-10-10 Thread Kasey Speakman
Excellent. Then check out this:

http://fsharpforfunandprofit.com/rop/

On Friday, October 7, 2016 at 3:05:50 PM UTC-5, Dave Ford wrote:
>
>
>
> On Fri, Oct 7, 2016 at 11:33 AM, Kasey Speakman <kjspe...@gmail.com 
> > wrote: 
>>
>> Then at the edge of the application, I can deal with the errors
>>
> Yes. This is what I am trying to figure out. How to deal with that class 
> of errors at the "edge". 
>  
> Thanks.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: No Runtime Exceptions - Still not computing

2016-10-07 Thread Kasey Speakman
Hi Dave.

Check out this link , 
but scroll down to the section titled "Should functions throw exceptions or 
return error structures?". It's F#, but the comparison is valid to 
exception handling vs "functional" error handling using Maybe (Option in 
F#) and Result.

In my back-end F# code, I no longer handle exceptions, generally speaking. 
I take functions which normally throw exceptions (like SQL queries) and 
wrap them in an Result type. Then using things like `map` and `bind` (aka 
`andThen`), I can continue my workflow only on success. Then at the edge of 
the application, I can deal with the errors differently based on which 
specific error occurred. Some could even invoke a program crash if that 
makes sense to do. But then I know exactly for which cases I am pushing the 
self-destruct button.

All that said, I think you are focusing on the trees and not the forest, 
because there's comparatively little need to do this kind of error handling 
in Elm, considering it only allows you to write pure functions. The main 
times you end up with Result types are parsing and comms. Maybe is more 
frequent, but more about presence than error handling.

On Thursday, October 6, 2016 at 9:13:32 PM UTC-5, Dave Ford wrote:
>
> I have listened to a number of podcasts where Richard Feldman boasts 
> about never getting a runtime exception. 
>
> I am having a hard time grasping the concept. I think I look at runtime 
> exceptions a bit differently. I look at them as a *positive*. A 
> programmers tool. A debugging tool. A way to communicate up the call stack. 
> A way to separate the error stream from the standard stream.
>
> For example, a java newbie might do this:
>
> void myFunction(int x){
>if(x < 1){
> *  log("error: x must be >= 1"); *
> *  return 0*
>}  
>return x * x * x;
> }
>
> A more experienced developer might do this:
>
> void myFunction(int x){
>if(x < 1){
>   *throw new IllegalArgumentException("error: x must be >= 1"); *
>}  
>return x * x * x;
> }
>
> I look at runtime exceptions as a good thing. It's kind of like having two 
> returns. One return for the normal answer (return). And another for error 
> conditions (throw). Just like unix has two output streams: one for normal 
> messages and one for error messages. This allows the caller to handle the 
> normal return value and the *top-level* caller to handle (i.e. catch) the 
> errors (usually by logging a stack trace). 
>
> So I don't get it. If I don't have runtime exceptions, what do I do when 
> someone passes an invalid argument? What do I do if some pre-condition is 
> not as I expected? Some JSON returned from the server is not in the correct 
> format? Are we back to just *one* return value for both error conditions 
> and normal conditions?
>
> Technically speaking, in java, if I wanted to create an app with no 
> runtime exceptions it would be real easy. I could just swallow invalid 
> arguments and let the program fail in a super mysterious way, farther 
> upstream (the opposite of fail-fast). But I wouldn't boast about that. Or I 
> could just have a try/catch in my main method that caught every exception 
> and swallowed it or logged it.
>
> If Richard said he wrote apps with no *bugs*. That would be impressive. 
> But an app with no runtime exceptions seems like a silly thing to boast 
> about. I see 3 kinds of bugs in my java apps:
>
> 1. *Compile errors.* These are the easiest to deal with. These are 
> preferred. But I don't see the compiler catching the above mentioned 
> IllegalArgumentException*. *Or a piece of bad JSON from the server.
>
> 2. *Runtime Exception. *Like a NullPointerException or an 
> IllegalArgumentException. I *love* these kind of bugs. Super easy to 
> find. Super easy to fix. A stack trace tells me exactly where to look. 
> These kind of exceptions have never been a thorn in my spine. 
>
> 3. *The mystery bug. *Program is just not producing the correct output. 
> No idea why. No idea where to start looking. No error message. No stack 
> trace. These are the worst kind of errors.
>
> In my opinion one of the key differences between an experienced developer 
> and a beginner developer is that an experienced developer fails-fast with 
> compile errors (#1) or runtime exceptions (#2). Beginner developers fail 
> mysteriously with (#3).
>
> So, based on my understanding, the whole "no runtime exceptions" concept 
> is just not computing.
>
> But I am new to Elm. Surely I am misunderstanding something. Please tell 
> me what I am missing.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Has anyone integrated Elm into a Web Forms project?

2016-10-06 Thread Kasey Speakman
I have a legacy project that needs a new page. I'm just trying to figure 
out the logistics of getting Elm to work with the existing (full) Visual 
Studio project. If someone has done that already, I would greatly 
appreciate hearing your experiences.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: A convenience pattern around Http?

2016-10-04 Thread Kasey Speakman
Seems like this is trying to normalize operations to CRUD. I would be 
careful of over-standardizing early. Because later you will likely have to 
break those abstractions to implement new features. For example, the way I 
would implement a Customer merge would not fit semantically into one of 
those operations.

There are a few steps involved in creating a new code path to an API, but 
most of it seems pretty reasonable. And there's nothing preventing you from 
making helper functions if you find yourself repeating mostly the same code 
for different calls.

On Tuesday, October 4, 2016 at 10:24:45 AM UTC-5, Rupert Smith wrote:
>
> On Friday, September 30, 2016 at 2:37:35 PM UTC+1, Rupert Smith wrote:
>>
>> Firstly, I define a set of call-back functions which will be notified 
>> when REST operations complete:
>>
>> callbacks : Account.Service.Callbacks Model Msg
>> callbacks =
>> { findAll = accountList
>> , findByExample = accountList
>> , create = \account -> \model -> ( model, Cmd.none )
>> , retrieve = \account -> \model -> ( model, Cmd.none )
>> , update = \account -> \model -> ( model, Cmd.none )
>> , delete = \response -> \model -> ( model, Cmd.none )
>> , error = error
>> }
>>
>
> One addition I am making to this, is to define a default set of 'no 
> action' callbacks in the service. Always -> ( model, Cmd.none). Then the 
> consumer of the service just needs to override and specify which events 
> they are interested in handling.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Is a decoder the right level of abstraction for parsing JSON?

2016-10-04 Thread Kasey Speakman
I haven't done this yet as we're developing the UI first as things take 
shape and faking the API calls with Process.sleep + Task.perform. So below 
is just a sketch.

Conceptually, you could use `Http.getString` (or construct a request and 
use `Http.send`) in Elm to get the JSON, then send that through a port to 
JavaScript. You'd need at least one outgoing port, and an incoming port for 
every result type.

port deserializeJson : String -> String -> Cmd msg


port studentsLoaded : (List Student -> msg) -> Sub msg

port coursesLoaded : (List Course -> msg) -> Sub msg


subscriptions : Model -> Sub Msg subscriptions model = Sub.batch [ 
studentLoaded StudentsLoaded , courseLoaded CoursesLoaded ] 


On the outgoing port, you could pass both the JSON and the incoming port 
name as a string. Then in the JS, you could wire it once like this:

app.ports.deserializeJson.subscribe(function(port, json) {
// TODO can throw, so catch error and send to an error port
var object = JSON.parse(json);
app.ports[port].send(object);
});


Once you get the HTTP response string from a particular request, you send 
it through the outgoing port with the correct return path.

deserializeJson "studentLoaded" json

It looks like after initial setup, each deserialization would take ~3 lines 
of wiring code. So it might not be worth it for small objects. But again 
this is just a sketch that I haven't tried to run.

On Tuesday, October 4, 2016 at 6:40:08 AM UTC-5, Vojtěch Král wrote:
>
> I have the same problem. Would someone be so kind as to give an example of 
> how to launder the JSON via ports like this? Do you just rut the data 
> through a port, or do you do ajax in JS?
> Thanks! 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Is a decoder the right level of abstraction for parsing JSON?

2016-10-04 Thread Kasey Speakman
Ehh, another missed plural.

deserializeJson "studentsLoaded" json

On Tuesday, October 4, 2016 at 6:40:08 AM UTC-5, Vojtěch Král wrote:
>
>
>
> Dne čtvrtek 29. září 2016 1:34:40 UTC+2 Kasey Speakman napsal(a):
>>
>> In the shorter term, my prevailing alternative to decoding in 0.17 is 
>> just to use ports to launder the JSON into clean Elm types, since ports are 
>> automatically decoded. 
>>
>
> I have the same problem. Would someone be so kind as to give an example of 
> how to launder the JSON via ports like this? Do you just rut the data 
> through a port, or do you do ajax in JS?
> Thanks! 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Is a decoder the right level of abstraction for parsing JSON?

2016-10-04 Thread Kasey Speakman
Sorry, subscriptions should be:

subscriptions : Model -> Sub Msg subscriptions model = Sub.batch [ 
studentsLoaded 
StudentsLoaded , coursesLoaded CoursesLoaded ]
Also, this does not work for types with Date or union members (limitations 
of ports).

On Tuesday, October 4, 2016 at 6:40:08 AM UTC-5, Vojtěch Král wrote:
>
>
>
> Dne čtvrtek 29. září 2016 1:34:40 UTC+2 Kasey Speakman napsal(a):
>>
>> In the shorter term, my prevailing alternative to decoding in 0.17 is 
>> just to use ports to launder the JSON into clean Elm types, since ports are 
>> automatically decoded. 
>>
>
> I have the same problem. Would someone be so kind as to give an example of 
> how to launder the JSON via ports like this? Do you just rut the data 
> through a port, or do you do ajax in JS?
> Thanks! 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Is a decoder the right level of abstraction for parsing JSON?

2016-10-03 Thread Kasey Speakman
@DuaneJohnson. I believe the compiler currently looks for ports and makes 
decoders for them. Then when you call a particular port or sub, the decoder 
is called under the covers. Something similar could happen for a 
Json.Decode.auto method, which could infer the type based on the tagger 
function it is invoked with. But it would probably have to be raised to the 
level of a language keyword like with `port` so its usage could be 
controlled enough that the compiler could find it.

@JamesWilson. I like what you're saying there. One slight tweak I'd make is 
to use a Result instead of Maybe. I'd like to know which field failed to 
decode in an error message.

@RupertSmith. I can think of one other case: decoding the same JSON to two 
different models. However, I think if you have a lot of custom rules, 
decoders would have to do. I don't have recursive fields, and I decode 
optional fields to Maybe. If I have multiple related Maybes, then I usually 
change my data model to link them together. Some reasonable defaults would 
fit 95% of my use cases, and I could use decoders for the one-offs.

@RileyEynon-Lynch. That's kindof what I was afraid of in the long term... 
decoders just being ongoing busy work. Coming from other languages, even 
back-end languages, decoding JSON just isn't a thing. Even on the back-end, 
I will setup a reflection-based deserializer with general error handling 
(e.g. Newtonsoft for .NET) and I'm done. The ongoing work is just 
maintaining the data types, which I must do anyway. The back-end 
deserializer does take some initial testing to work out the kinks, but that 
work has an end after which there is no ongoing maintenance.

PSA: There is also a code-gen tool to create decoders from example JSON.

http://noredink.github.io/json-to-elm/

(A little late to the party because I forgot to subscribe to updates.)

On Saturday, October 1, 2016 at 9:36:37 AM UTC-5, Andrew Radford wrote:
>
> Not sure if it has been mentioned but there is this effort to create 
> decoders from swagger definitions:
>
> https://github.com/ahultgren/swagger-elm
>
> Still a work in progress, but looks promising.
>
>  
>
>>
>> A tool that would really help me right now would be a json-schema-to-elm 
>> converter.
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Is a decoder the right level of abstraction for parsing JSON?

2016-09-28 Thread Kasey Speakman
Today I found my team struggling over decoding some fixed-structure JSON. 
Search this list for "decode" to see further examples.

Even though I understand decoders well enough to use them, I still don't 
want to use them. For one thing, I don't deal with fuzzy JSON. I have type 
aliases that match the JSON structures. Decoder code is entirely redundant 
with the information in the type alias. Secondly, writing a decoder is 
demonstrably beginner unfriendly. (Read the search results or watch a 
beginner struggle with it to see for yourself.) So writing a decoder is 
painful both conceptually and because it's redundant work.

In the shorter term, my prevailing alternative to decoding in 0.17 is just 
to use ports to launder the JSON into clean Elm types, since ports are 
automatically decoded. But notably Date will not pass through ports. Not a 
frequent need for me but if I did need a Date type, another type alias with 
date as string or int would be required. Then that would have to be 
converted to the real record. It's even more redundant work (albeit 
simpler), so I'll avoid if possible.

In the longer term, the solution that jumps out at me is the compiler could 
generate decoders for marked type aliases automatically. (I assume ports 
work this way already.) And decoding is still there for fuzzy scenarios.

Anyway, I saw in one of the Elm-conf videos Evan say that if I have issues, 
I should say something. So there it is. The other main issue we have looks 
to get fixed next version (changes to files not being recompiled).

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: So how do *you* handle Dates through ports?

2016-08-24 Thread Kasey Speakman
Yeah, a number has specific advantages and disadvantages vs ISO date. 
Neither is strictly better, just different trade-offs.

You mention decoding. To me it seems better to auto-decode, using two 
records if necessary, than to employ Json.decode. It's also conceptually 
more simple (record to record mapping) than creating parsers with probably 
no more boilerplate. Seems like a real missed opportunity for the HTTP API.

On Wednesday, August 24, 2016 at 2:24:57 AM UTC-5, Markus wrote:
>
> Doesn't seems like it would be much different from passing the ISO string 
>> through as I mentioned before. It just has the same tradeoffs of using a 
>> number to represent a Date.
>>
>
> True, if you know you get an ISO string, then they are essentially the 
> same. Convenience of each format depends on the use case. For instance, 
> manipulations of timestamps, like adding days or getting the difference 
> between two dates, are easier.
>
> Trying to answer your original question, I personally regard flags or 
> incoming ports as essentially json data that must be consumed or processed 
> in some way, and then I use the two records *technique* to auto-decode*.* 
> Incidentally, the two records usually end up being very different from each 
> other, because you can design your model using whatever Elm types you need, 
> without worrying too much about where that data comes from.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: So how do *you* handle Dates through ports?

2016-08-23 Thread Kasey Speakman
Doesn't seems like it would be much different from passing the ISO string 
through as I mentioned before. It just has the same tradeoffs of using a 
number to represent a Date.

On Tuesday, August 23, 2016 at 5:16:10 AM UTC-5, Markus wrote:
>
> I'm wondering, wouldn't be enough to convert the date to a timestamp and 
> pass it as a Float to Elm? (and then use Date.fromTime inside Elm)
>
>
> On Monday, 22 August 2016 18:59:18 UTC+2, OvermindDL1 wrote:
>>
>> On Monday, August 22, 2016 at 10:44:24 AM UTC-6, Kasey Speakman wrote:
>>>
>>> Re encoding: You can pass the value over as Json.Value and decode it, no?
>>>
>>
>> Still involves an extra step regardless, and I like being explicit about 
>> types so I have my record.  It is a standard Javascript Date time object 
>> though, the style that is entirely explicit so there is no question about 
>> any aspect of the time, calendar, or anything of the sort, it is the almost 
>> accurate date object (to be more accurate you also need to define relative 
>> start/end locations and such, which involves relativity, which can be 
>> ignored in 'most' cases).
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: So how do *you* handle Dates through ports?

2016-08-22 Thread Kasey Speakman
The only ones that really makes sense to auto convert through a port is ISO 
string or JS native. If you use a strange object, then yeah you would need 
manual conversion.

Re encoding: You can pass the value over as Json.Value and decode it, no?

On Monday, August 22, 2016 at 11:25:31 AM UTC-5, OvermindDL1 wrote:
>
> Too many formats for date though.  ;-)
>
> Such as is it in a format of a String?  With or without timezone?  Is it 
> in the format of a record like this that I use:
> ```elm
> type alias JsonDateTime =
> { year : Int
> , timezone :
> { until : String
> , offset_utc : Int
> , offset_std : Int
> , full_name : String
> , from : String
> , abbreviation : String
> }
> , second : Int
> , month : Int
> , minute : Int
> , millisecond : Int
> , hour : Int
> , day : Int
> , calendar : String
> }
> ```
> The above record is parsed by the Javascript Date object without issue, 
> but nothing in Elm takes it so I have some nasty converting.  But there are 
> lots of ways and things.  Customized Encoding/Decoding for ports would be 
> awesome though.
>
>
> On Monday, August 22, 2016 at 9:55:39 AM UTC-6, Kasey Speakman wrote:
>>
>> Well, I'd wish for Dates to just automatically come over first. :)
>>
>> On Monday, August 22, 2016 at 10:50:39 AM UTC-5, OvermindDL1 wrote:
>>>
>>> I use the method of two records, one that comes in the port and one 
>>> after massaging it into the better format at the subscription step.  It is 
>>> ugly but I do not really see a way around it without being able to somehow 
>>> define our own Encoders/Decoders for ports (which I wish!).
>>>
>>>
>>> On Monday, August 22, 2016 at 9:22:06 AM UTC-6, Kasey Speakman wrote:
>>>>
>>>> If I have a record with a Date field, and I need to receive that 
>>>> through a port (which I understand is not possible). Do I have to de/code 
>>>> the whole record just because of this or is there a better way?
>>>>
>>>> Another way that occurs to me is to create two records, one with the 
>>>> date as a string for going through the port. Then once it gets inside Elm, 
>>>> use Date.fromString and map to the actual record type. Seems only slightly 
>>>> better than de/coding.
>>>>
>>>> Thoughts?
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: So how do *you* handle Dates through ports?

2016-08-22 Thread Kasey Speakman
Well, I'd wish for Dates to just automatically come over first. :)

On Monday, August 22, 2016 at 10:50:39 AM UTC-5, OvermindDL1 wrote:
>
> I use the method of two records, one that comes in the port and one after 
> massaging it into the better format at the subscription step.  It is ugly 
> but I do not really see a way around it without being able to somehow 
> define our own Encoders/Decoders for ports (which I wish!).
>
>
> On Monday, August 22, 2016 at 9:22:06 AM UTC-6, Kasey Speakman wrote:
>>
>> If I have a record with a Date field, and I need to receive that through 
>> a port (which I understand is not possible). Do I have to de/code the whole 
>> record just because of this or is there a better way?
>>
>> Another way that occurs to me is to create two records, one with the date 
>> as a string for going through the port. Then once it gets inside Elm, use 
>> Date.fromString and map to the actual record type. Seems only slightly 
>> better than de/coding.
>>
>> Thoughts?
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] So how do *you* handle Dates through ports?

2016-08-22 Thread Kasey Speakman
If I have a record with a Date field, and I need to receive that through a 
port (which I understand is not possible). Do I have to de/code the whole 
record just because of this or is there a better way?

Another way that occurs to me is to create two records, one with the date 
as a string for going through the port. Then once it gets inside Elm, use 
Date.fromString and map to the actual record type. Seems only slightly 
better than de/coding.

Thoughts?

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Elm UI boilerplate

2016-08-18 Thread Kasey Speakman
I had the same thought... Elm's HTML components stand out as examples of 
self-contained components. But when I checked their implementations, they 
all turned out to be native. Their effects/state are managed by native code 
<https://github.com/elm-lang/virtual-dom/blob/master/src/Native/VirtualDom.js#L410>
.

This unfortunately means that the way they work has no corollary in pure 
Elm. Maybe it's possible to build your own components by calling the same 
native functions. I haven't seen any guidance suggesting this approach. I 
would imagine a lot of the safety features are bypassed this way. I think 
even then, all the component's Elm messages would get send to the top of 
the program, not the component itself, the same way Elm messages work for 
standard HTML components.

The view function is pure in that: given the same inputs, the same output 
is generated. But the program on the whole is not pure. (Pure programs are 
generally useless since they can't interact with the outside.) The 
framework steps in to handle turning the rendered HTML into effect-ful 
elements (attaching event handlers, delivering messages, etc).

I, too, wonder if there is a way to bridge the Elm world to native in a 
safe way for building components, but I would be wary of losing the 
benefits of determinism. Currently Elm forces you to write your application 
bits as pure functions so that your code holds no accidental complexity. 
Then it handles the effectful complexity for you, or at least forces it to 
take place "outside" in JS where you're used to it.

On Thursday, August 18, 2016 at 4:47:53 AM UTC-5, Peter Damoc wrote:
>
> Hi Kasey,
>
> Take this code as example: 
>
> import Html exposing (..)
> import Html.App as App
> import Html.Events exposing (..)
>
> main =
>   App.beginnerProgram
> { model = 0
> , view = view
> , update = \msg model -> model
> }
>
> type Msg = NoOp String  
>
> view : Int -> Html Msg
> view model =
>   div []
> [ input [onInput NoOp ][]
> ]
>  
> if you type in the input of this short program you will see characters. 
> Those characters are not part of the model. 
> Every time you press something, the view is called again with the exact 
> same argument and what you see on the screen is different. 
>
> In order for this input component to work, there has to be state. State 
> that holds the characters typed, state that holds the cursor position, even 
> state that animates that cursor. 
>
> So, if elm views are pure, what does this make `Html msg`? 
>
> The easiest answer I could come up with is that `Html msg` behaves like 
> the record you give to a `Html.App.program`
>
> Given this record, the runtime could create some state if it hasn't 
> already done this and use the provided functions to update it / represent 
> it.  
>
> Of course, elm-html is not implemented like this but, from a type 
> conceptualization point of view, this is the easiest way that I could find 
> to explain the *behavior* or elm-html and still maintain the idea that 
> the view is pure. 
>
> And this brings us back to the issue of boilerplate. If elm-html can do 
> this automatic state and avoid the boilerplate, how can alternatives to 
> elm-html do the same thing? 
>
> Another way to think about it is, how would a pure Elm ui be implemented 
> if there would not be the support of state management that the dom does? 
> (Imagine a cross platform UI implemented in Elm on top of something like a 
> canvas ) 
>
>
>
>
>
>
>
> On Thu, Aug 18, 2016 at 11:32 AM, Kasey Speakman <kjspe...@gmail.com 
> > wrote:
>
>> I've hesitated to mention this since I'm a newcomer to Elm, but I'll 
>> throw it out there and see what you think.
>>
>> The way Elm currently renders subcomponents is because the view is a pure 
>> function, so all subparts must be pure functions. That's what makes 
>> stateful subcomponents irritating to work with... the boilerplate of 
>> accounting for them in the parent.
>>
>> As a thought experiment, what if Elm were to bring in support for UI 
>> components that were independent of Main? They get wired to received 
>> init/update/view independently of the parent. They get avenues to send 
>> messages to the parent and vice versa. They get some state from the parent 
>> on init. Etc. That path has already been well-traveled by most every other 
>> front-end so we can know the answer. Doing that is basically bringing in 
>> object orientation and all the accidental complexity that comes with it. 
>> Right now Elm steers us away from those problems by forcing our code to be 
>> deterministic, but with the trade-off of the parent being responsible for 
>> everyth

Re: [elm-discuss] Re: More thorough side-effect isolation

2016-08-18 Thread Kasey Speakman
You could be right. I'm thinking of back-end systems where a PM may need to
send a command to an "external" system (or even calls to its own system are
done as "external" calls), so I/O is involved. Maybe that scenario doesn't
apply on the front-end.

On Thu, Aug 18, 2016 at 9:32 AM, Marco Perone <pasaf...@gmail.com> wrote:

> Thanks Kasey for your observations!
>
> I agree with everything except for one thing. Regarding `process`, I don't
> think it should return a Cmd Command. Cmd generates asynchronous
> operations, and we receive a notification when they are completed, so I'd
> rather represent this message with an Event. I guess that `process` should
> return something like Command | Cmd Event, to allow both synchronous and
> asynchronous commands
>
>
> On Wednesday, August 17, 2016 at 9:31:02 PM UTC+2, Kasey Speakman wrote:
>>
>> So, reading through your implementation:
>>
>> Bug: In `projection`, you're doing a foldl on your history, but you're
>> putting new events at the head of your history using cons (::). So your
>> history be replayed in reverse order. I think there was a quite humorous
>> Red Dwarf episode about that.
>>
>> Possible typo: `process` should return a Cmd Command instead of Cmd Event
>> if we're talking about the Process Manager pattern. I would also do a List
>> instead of Maybe. (You can Cmd.batch them, and Cmd.none is actually
>> implemented as Cmd.batch on an empty list)
>>
>> Also, `process` is called incorrectly if it only uses Events to make
>> decisions. It should be called with all history, not just the events
>> generated from the one command. With only current events, it might be
>> missing the information needed to know if a Command is warranted. RPG
>> example: your game didn't have full history, so even though you got a
>> GoblinSlayer sword 5 minutes ago, it didn't on turn Glow on when
>> GoblinsEnteredTheArea.
>>
>> `commandHandler` - I believe the definition of commandHandler as `Command
>> -> Events -> Events` is too narrow. A command handler is often responsible
>> for wrangling external resources (e.g. API calls). The only way to make
>> this possible is to return `Cmd Events`. I also imagine it possible to
>> perform some IO through Cmd and subsequently need to issue another Command
>> to do something else with logic or IO. (Generally, I think multiple API
>> calls would be handled better by an API gateway, but I wouldn't want to
>> limit possibilities here.) I think Cmd Msg or Cmd (List Msg) would be more
>> expected here.
>>
>> As previously mentioned, I don't think it's a good idea to carry around
>> the increment value and actually calculate it in the `eventHandler`. The
>> relating of Incremented to the plus operator and Decremented to minus is
>> logic, and logic should be under the command handler. Updating a model with
>> event data should be as dumb as possible, because it should not have the
>> possibility to fail when simply responding to facts. Not sure if plus/minus
>> overflow in Elm (in JS, they flip sign on overflow), but other kinds of
>> operators could.
>>
>> On Wednesday, August 17, 2016 at 11:32:27 AM UTC-5, Marco Perone wrote:
>>>
>>> Hi!
>>>
>>> I was eventually able to read carefully the thread and give some
>>> thoughts about it.
>>>
>>> @kasey, I had a look to your Gist and it looks really interesting! Some
>>> notes about it:
>>>
>>> - I think it would be better to store in the parameter of the Fact's the
>>> increment, and not the state of the application. It looks to me that you
>>> are mixing two concerns, i.e. the state of the applications and the events
>>> that happens to it
>>>
>>> - if I'm not mistaken, from you implementation it seems that only Act's
>>> (and not Fact's) can generate new Cmd's. I think that is some applications
>>> there could be the need to react automatically with a new Cmd to some
>>> events that happened
>>>
>>> To make everything clearer in my mind, I wrote my own implementation of
>>> something similar to what you did. You can find it here:
>>>
>>> https://github.com/marcosh/elm-escqrs/blob/master/EsCqrsMain.elm
>>>
>>> It should be just a functional transposition of a standard es/cqrs
>>> architecture (I actually used also es/cqrs jargon), adacted to the Elm
>>> Architecture.
>>>
>>> I'd really like to know what you think of it. Let me know if something
>>> is not clear enough
>>>
>>> On Sunday, 

Re: [elm-discuss] Re: Elm UI boilerplate

2016-08-18 Thread Kasey Speakman
I've hesitated to mention this since I'm a newcomer to Elm, but I'll throw 
it out there and see what you think.

The way Elm currently renders subcomponents is because the view is a pure 
function, so all subparts must be pure functions. That's what makes 
stateful subcomponents irritating to work with... the boilerplate of 
accounting for them in the parent.

As a thought experiment, what if Elm were to bring in support for UI 
components that were independent of Main? They get wired to received 
init/update/view independently of the parent. They get avenues to send 
messages to the parent and vice versa. They get some state from the parent 
on init. Etc. That path has already been well-traveled by most every other 
front-end so we can know the answer. Doing that is basically bringing in 
object orientation and all the accidental complexity that comes with it. 
Right now Elm steers us away from those problems by forcing our code to be 
deterministic, but with the trade-off of the parent being responsible for 
everything underneath (requiring the boilerplate).

That's not an answer to the issue at hand. It's just an observation that 
Elm does provide a (perhaps non-obvious) benefit with the current way it 
does things. It still definitely has pain, but it's clear-cut as opposed to 
accidental and pervasive. So I think that's why we hear the advice from the 
more seasoned folks to start from a place of having the parent manage 
everything with the child being stateless. Only once it becomes impractical 
for the parent to maintain the child's state, then take the lumps to make 
it stateful. The message is: yes, there's pain... just avoid it until you 
can't.

Now don't get me wrong, I want the ability to use UI toolkits without 
impacting "my" code. And I want to eradicate boilerplate. We just need to 
be mindful of the trade-offs in how that's accomplished. Myself, I'm still 
thinking on it.

On Thursday, August 18, 2016 at 1:41:57 AM UTC-5, Oliver Searle-Barnes 
wrote:
>
> In my experience every large SPA I've worked on has ended up building a 
> set of it's own components similar to elm-mdl. They've usually been used 
> alongside other components that have been provided by libraries such as 
> elm-mdl but they're still a significant part of the codebase. From this 
> perspective, and judging by the questions I've seen in slack, this is 
> something that pretty much every Elm developer is going to need to resolve. 
>
> It would also be great to have a healthy selection of UX components 
> available at http://package.elm-lang.org/. To get a concrete idea of some 
> of the sorts of components this might be take a look at 
> https://emberobserver.com/categories/components. 
>
> Making it easy to author, share and consume UX components will only make 
> building Elm apps even more pleasurable :) I'd caution against treating it 
> as a special case for advanced use or the select few. 
>
>
> On Thursday, 18 August 2016 08:25:29 UTC+2, Peter Damoc wrote:
>>
>> A small clarification that came up in an earlier discussion. 
>>
>> This is a boilerplate example for the case where you have many small 
>> components that are unavoidably stateful as it is the case with UI 
>> toolkits. 
>>
>> This is a topic that concerns very few people from an implementation 
>> point of view but stands to concern a lot of people from usage point of 
>> view. 
>>
>> Most of the components needs are covered by current technologies. 
>>
>> One more thing that might be worth mentioning: 
>> Adding a new field involves changing the code in 3 places for the 
>> with-parts version and it 5 places for the without-parts code. 
>>
>>
>> P.S. Many thanks to Josh for cleaning up the code of without-parts 
>> example.  
>>
>> -- 
>> There is NO FATE, we are the creators.
>> blog: http://damoc.ro/
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-17 Thread Kasey Speakman
One question @Evan. How are you keeping events? I would assume in Elm 
structures, since you can't send union types through ports be default. 
Asking in case you have some magic for transferring them out to Javascript. 
The idea of writing de/en-coders for every message case (in order to 
transmit or load/save in Session State) makes my brain shut down.

On Wednesday, August 17, 2016 at 2:15:49 PM UTC-5, Evan wrote:
>
> Warning, I have not read everything here. About ignoring commands though, 
> think of the type of a Html.App.program
>
> program : { init, update, view, subscriptions } -> Program Never
>
> The essence of this is just a record. So you can wrap that record however 
> you want. Say like this:
>
> myProgram : ({ init, update, view, subscriptions } as details) =
>   { details | update = \msg model -> (fst (update msg model), Cmd.none) }
>
> Now you have programs that drop all commands.
>
> I'm in the process of revining elm-reactor to track history for exactly 
> the kinds of things you have in mind (testing, etc.) and I am using this 
> basic technique. Anyone can do this. You can write time-travel in pure Elm 
> this way. Make the update log all the messages it gets.
>
> Again, I have no idea what's happening in this discussion though, so 
> hopefully that's a helpful insight.
>
>
> On Thursday, August 11, 2016 at 10:37:48 AM UTC-7, Kasey Speakman wrote:
>>
>> Hi all,
>>
>> I'm getting to know Elm. I recently read this article 
>> <http://marcosh.github.io/post/2016/07/09/elm-event-sourcing.html> about 
>> event sourcing in Elm. Essentially, the time-traveling debugger is event 
>> sourcing. But it's a pattern that could be used in an app for other great 
>> things. (Lots of literature on that in the internet. One particular 
>> interest of mine is producing a complete failing use case from live running 
>> app -- it's just all the events. Obviously wouldn't work for real-time 
>> apps... too many events... but for most of mine it would.)
>>
>> However, one thing that is a hindrance (to the TTD as well) and that has 
>> always bothered me about the Elm examples is this signature.
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>>
>>
>> Because an update returns both a Model and Cmd, for instance, the 
>> time-traveling debugger "...needs to tell the runtime not to perform any 
>> side-effects during replay to avoid these issues"[1]. An event-sourcing 
>> implementation would have to figure a way to do the same without runtime 
>> hooks.
>>
>> This part of the architecture mixes concerns by returning a model and 
>> effects. And usually (not always) you see each message returning one or the 
>> other, not both. From the docs:
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>   case msg of
>> Roll ->
>>   (model, Random.generate NewFace (Random.int 1 6))
>>
>> NewFace newFace ->
>>   (Model newFace, Cmd.none)
>>
>>
>> Here, Roll does an effect, but nothing with the model. NewFace returns a 
>> new model but no effects. You do have cases where you want to update a UI 
>> element when an outside effect happens, like activating a spinner when 
>> sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
>> One that immediately returns a separate message affecting the model's 
>> spinner. And another to do the HTTP request.
>>
>> So it seems to me that there are really two concepts at work here. There 
>> are "events" which have happened and can be used completely 
>> deterministically, and there are commands which interface with the outside 
>> and may produce events.
>>
>> I think it's something worth pointing out and considering for the future. 
>> What do y'all think?
>>
>> Kasey
>>
>> [1] source <http://debug.elm-lang.org/>, section "How Elm makes this 
>> possible", subsection "Purity", last paragraph
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-17 Thread Kasey Speakman
So, reading through your implementation:

Bug: In `projection`, you're doing a foldl on your history, but you're 
putting new events at the head of your history using cons (::). So your 
history be replayed in reverse order. I think there was a quite humorous 
Red Dwarf episode about that.

Possible typo: `process` should return a Cmd Command instead of Cmd Event 
if we're talking about the Process Manager pattern. I would also do a List 
instead of Maybe. (You can Cmd.batch them, and Cmd.none is actually 
implemented as Cmd.batch on an empty list)

Also, `process` is called incorrectly if it only uses Events to make 
decisions. It should be called with all history, not just the events 
generated from the one command. With only current events, it might be 
missing the information needed to know if a Command is warranted. RPG 
example: your game didn't have full history, so even though you got a 
GoblinSlayer sword 5 minutes ago, it didn't on turn Glow on when 
GoblinsEnteredTheArea.

`commandHandler` - I believe the definition of commandHandler as `Command 
-> Events -> Events` is too narrow. A command handler is often responsible 
for wrangling external resources (e.g. API calls). The only way to make 
this possible is to return `Cmd Events`. I also imagine it possible to 
perform some IO through Cmd and subsequently need to issue another Command 
to do something else with logic or IO. (Generally, I think multiple API 
calls would be handled better by an API gateway, but I wouldn't want to 
limit possibilities here.) I think Cmd Msg or Cmd (List Msg) would be more 
expected here.

As previously mentioned, I don't think it's a good idea to carry around the 
increment value and actually calculate it in the `eventHandler`. The 
relating of Incremented to the plus operator and Decremented to minus is 
logic, and logic should be under the command handler. Updating a model with 
event data should be as dumb as possible, because it should not have the 
possibility to fail when simply responding to facts. Not sure if plus/minus 
overflow in Elm (in JS, they flip sign on overflow), but other kinds of 
operators could.

On Wednesday, August 17, 2016 at 11:32:27 AM UTC-5, Marco Perone wrote:
>
> Hi!
>
> I was eventually able to read carefully the thread and give some thoughts 
> about it.
>
> @kasey, I had a look to your Gist and it looks really interesting! Some 
> notes about it:
>
> - I think it would be better to store in the parameter of the Fact's the 
> increment, and not the state of the application. It looks to me that you 
> are mixing two concerns, i.e. the state of the applications and the events 
> that happens to it
>
> - if I'm not mistaken, from you implementation it seems that only Act's 
> (and not Fact's) can generate new Cmd's. I think that is some applications 
> there could be the need to react automatically with a new Cmd to some 
> events that happened
>
> To make everything clearer in my mind, I wrote my own implementation of 
> something similar to what you did. You can find it here:
>
> https://github.com/marcosh/elm-escqrs/blob/master/EsCqrsMain.elm
>
> It should be just a functional transposition of a standard es/cqrs 
> architecture (I actually used also es/cqrs jargon), adacted to the Elm 
> Architecture.
>
> I'd really like to know what you think of it. Let me know if something is 
> not clear enough
>
> On Sunday, August 14, 2016 at 7:37:25 AM UTC+2, Kasey Speakman wrote:
>>
>> So, I made a Gist 
>> <https://gist.github.com/kspeakman/109475ecdd3068a022b59f7f73c9485a> of 
>> the helper stuff which splits Facts and Acts. I call the helper Factor... 
>> (Fact or Act ~=> Factor). There is a subsequent comment with an example 
>> program explaining the helper's usage.
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-17 Thread Kasey Speakman
Dunno why I didn't think of that. It should have been obvious to me.

On Wednesday, August 17, 2016 at 2:15:49 PM UTC-5, Evan wrote:
>
> Warning, I have not read everything here. About ignoring commands though, 
> think of the type of a Html.App.program
>
> program : { init, update, view, subscriptions } -> Program Never
>
> The essence of this is just a record. So you can wrap that record however 
> you want. Say like this:
>
> myProgram : ({ init, update, view, subscriptions } as details) =
>   { details | update = \msg model -> (fst (update msg model), Cmd.none) }
>
> Now you have programs that drop all commands.
>
> I'm in the process of revining elm-reactor to track history for exactly 
> the kinds of things you have in mind (testing, etc.) and I am using this 
> basic technique. Anyone can do this. You can write time-travel in pure Elm 
> this way. Make the update log all the messages it gets.
>
> Again, I have no idea what's happening in this discussion though, so 
> hopefully that's a helpful insight.
>
>
> On Thursday, August 11, 2016 at 10:37:48 AM UTC-7, Kasey Speakman wrote:
>>
>> Hi all,
>>
>> I'm getting to know Elm. I recently read this article 
>> <http://marcosh.github.io/post/2016/07/09/elm-event-sourcing.html> about 
>> event sourcing in Elm. Essentially, the time-traveling debugger is event 
>> sourcing. But it's a pattern that could be used in an app for other great 
>> things. (Lots of literature on that in the internet. One particular 
>> interest of mine is producing a complete failing use case from live running 
>> app -- it's just all the events. Obviously wouldn't work for real-time 
>> apps... too many events... but for most of mine it would.)
>>
>> However, one thing that is a hindrance (to the TTD as well) and that has 
>> always bothered me about the Elm examples is this signature.
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>>
>>
>> Because an update returns both a Model and Cmd, for instance, the 
>> time-traveling debugger "...needs to tell the runtime not to perform any 
>> side-effects during replay to avoid these issues"[1]. An event-sourcing 
>> implementation would have to figure a way to do the same without runtime 
>> hooks.
>>
>> This part of the architecture mixes concerns by returning a model and 
>> effects. And usually (not always) you see each message returning one or the 
>> other, not both. From the docs:
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>   case msg of
>> Roll ->
>>   (model, Random.generate NewFace (Random.int 1 6))
>>
>> NewFace newFace ->
>>   (Model newFace, Cmd.none)
>>
>>
>> Here, Roll does an effect, but nothing with the model. NewFace returns a 
>> new model but no effects. You do have cases where you want to update a UI 
>> element when an outside effect happens, like activating a spinner when 
>> sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
>> One that immediately returns a separate message affecting the model's 
>> spinner. And another to do the HTTP request.
>>
>> So it seems to me that there are really two concepts at work here. There 
>> are "events" which have happened and can be used completely 
>> deterministically, and there are commands which interface with the outside 
>> and may produce events.
>>
>> I think it's something worth pointing out and considering for the future. 
>> What do y'all think?
>>
>> Kasey
>>
>> [1] source <http://debug.elm-lang.org/>, section "How Elm makes this 
>> possible", subsection "Purity", last paragraph
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-17 Thread Kasey Speakman
Btw, the "event compression" only works for sequential messages of 
identical type (assuming idempotence). So Incremented 1, Incremented 2 
could compress to just Incremented 2, but Incremented 1, Decremented 0 
could not compress obviously. The counter example is bad here as it doesn't 
express how different the events can affect the model in orthogonal ways... 
all these events are affecting the same piece of data, so they could all be 
compressed down to the last event. But that's not a guarantee you can make 
in general.

On Wednesday, August 17, 2016 at 1:22:20 PM UTC-5, Kasey Speakman wrote:
>
> Thanks for the comment!
>
> - I think it would be better to store in the parameter of the Fact's the 
>> increment, and not the state of the application. It looks to me that you 
>> are mixing two concerns, i.e. the state of the applications and the events 
>> that happens to it
>>
>
> The counter example is too simple to properly express this, but the Fact 
> doesn't store the whole application state, only data applicable to the 
> event. For instance, imagine the apply function was `NameChanged name -> 
> {model | Name = name }`. It doesn't change the whole model, but it changes 
> a part of the model it applies to. In the counter example, the part 
> unfortunately happens to be the whole model.
>
> If the data instead carried the increment instead of the final value, then 
> the logic of how the counter works is decentralized... part of it (model + 
> 1, model - 1) is in the apply function now. You wouldn't put other kinds of 
> logic in the apply function (e.g. HTTP call). Storing the increment in the 
> event is also no longer idempotent. Idempotence is typically something you 
> want on the back-end because it allows you to deliver a message more than 
> once with no ill effects. However, it is valuable in the UI because it 
> could allow you to "compress" events to prevent history from getting too 
> large. For example, say someone spammed the Increment button 100 times, 
> giving you Incremented 1... Incremented 100. When applied in order, the 
> result is the same as just applying the last event of the same type; 
> Incremented 100. Now you are loosing history that way (and undo-ability), 
> but you can choose to make that trade-off for space without a deep 
> understanding of the events. In order to do the same if you were carrying 
> the increment, you would have understand what the event was doing and apply 
> logic to the messages to figure out the "compressed" message's data (add 
> the increments), so you have another place where you are putting logic.
>
> However, the compression benefit is probably mitigated by Elm not having a 
> way to determine if two union cases are the same type (no metaprogramming 
> that I know of). You'd have to manually check for specific sequential 
> messages you want to compress.
>
> - if I'm not mistaken, from you implementation it seems that only Act's 
>> (and not Fact's) can generate new Cmd's. I think that is some applications 
>> there could be the need to react automatically with a new Cmd to some 
>> events that happened
>>
>
> This (events to commands, aka Process Manager aka Saga) is not covered in 
> my example. Seems like the easiest way to accomplish this is to have 3rd 
> method which is called after `apply` that checks the model (or the part 
> where the process manager has been keeping track of state) to see if a new 
> Act needs to be issued. Maybe something like this:
>
> propose : Model -> Cmd Act
> propose model =
>   if model.orderProcess.orderPlaced && model.orderProcess.paymentFailed 
> then
> CancelOrder model.orderProcess.orderId |> actCmd
>   else if model.orderProcess.orderPlaced && model.orderProcess.paidInFull 
> then
> ShipOrder model.orderProcess.orderId |> actCmd
>   else
> Cmd.none
>
> That's assuming your `apply` method is updating the model with those flags 
> in response to the appropriate events. Of course, this particular logic 
> doesn't make sense on the front end, but this type of pattern could.
>
> On Wednesday, August 17, 2016 at 11:32:27 AM UTC-5, Marco Perone wrote:
>>
>> Hi!
>>
>> I was eventually able to read carefully the thread and give some thoughts 
>> about it.
>>
>> @kasey, I had a look to your Gist and it looks really interesting! Some 
>> notes about it:
>>
>> - I think it would be better to store in the parameter of the Fact's the 
>> increment, and not the state of the application. It looks to me that you 
>> are mixing two concerns, i.e. the state of the applications and the events 
>> that happens to it
>>
>> - if I'm not m

[elm-discuss] Re: More thorough side-effect isolation

2016-08-17 Thread Kasey Speakman
Thanks for the comment!

- I think it would be better to store in the parameter of the Fact's the 
> increment, and not the state of the application. It looks to me that you 
> are mixing two concerns, i.e. the state of the applications and the events 
> that happens to it
>

The counter example is too simple to properly express this, but the Fact 
doesn't store the whole application state, only data applicable to the 
event. For instance, imagine the apply function was `NameChanged name -> 
{model | Name = name }`. It doesn't change the whole model, but it changes 
a part of the model it applies to. In the counter example, the part 
unfortunately happens to be the whole model.

If the data instead carried the increment instead of the final value, then 
the logic of how the counter works is decentralized... part of it (model + 
1, model - 1) is in the apply function now. You wouldn't put other kinds of 
logic in the apply function (e.g. HTTP call). Storing the increment in the 
event is also no longer idempotent. Idempotence is typically something you 
want on the back-end because it allows you to deliver a message more than 
once with no ill effects. However, it is valuable in the UI because it 
could allow you to "compress" events to prevent history from getting too 
large. For example, say someone spammed the Increment button 100 times, 
giving you Incremented 1... Incremented 100. When applied in order, the 
result is the same as just applying the last event of the same type; 
Incremented 100. Now you are loosing history that way (and undo-ability), 
but you can choose to make that trade-off for space without a deep 
understanding of the events. In order to do the same if you were carrying 
the increment, you would have understand what the event was doing and apply 
logic to the messages to figure out the "compressed" message's data (add 
the increments), so you have another place where you are putting logic.

However, the compression benefit is probably mitigated by Elm not having a 
way to determine if two union cases are the same type (no metaprogramming 
that I know of). You'd have to manually check for specific sequential 
messages you want to compress.

- if I'm not mistaken, from you implementation it seems that only Act's 
> (and not Fact's) can generate new Cmd's. I think that is some applications 
> there could be the need to react automatically with a new Cmd to some 
> events that happened
>

This (events to commands, aka Process Manager aka Saga) is not covered in 
my example. Seems like the easiest way to accomplish this is to have 3rd 
method which is called after `apply` that checks the model (or the part 
where the process manager has been keeping track of state) to see if a new 
Act needs to be issued. Maybe something like this:

propose : Model -> Cmd Act
propose model =
  if model.orderProcess.orderPlaced && model.orderProcess.paymentFailed then
CancelOrder model.orderProcess.orderId |> actCmd
  else if model.orderProcess.orderPlaced && model.orderProcess.paidInFull 
then
ShipOrder model.orderProcess.orderId |> actCmd
  else
Cmd.none

That's assuming your `apply` method is updating the model with those flags 
in response to the appropriate events. Of course, this particular logic 
doesn't make sense on the front end, but this type of pattern could.

On Wednesday, August 17, 2016 at 11:32:27 AM UTC-5, Marco Perone wrote:
>
> Hi!
>
> I was eventually able to read carefully the thread and give some thoughts 
> about it.
>
> @kasey, I had a look to your Gist and it looks really interesting! Some 
> notes about it:
>
> - I think it would be better to store in the parameter of the Fact's the 
> increment, and not the state of the application. It looks to me that you 
> are mixing two concerns, i.e. the state of the applications and the events 
> that happens to it
>
> - if I'm not mistaken, from you implementation it seems that only Act's 
> (and not Fact's) can generate new Cmd's. I think that is some applications 
> there could be the need to react automatically with a new Cmd to some 
> events that happened
>
> To make everything clearer in my mind, I wrote my own implementation of 
> something similar to what you did. You can find it here:
>
> https://github.com/marcosh/elm-escqrs/blob/master/EsCqrsMain.elm
>
> It should be just a functional transposition of a standard es/cqrs 
> architecture (I actually used also es/cqrs jargon), adacted to the Elm 
> Architecture.
>
> I'd really like to know what you think of it. Let me know if something is 
> not clear enough
>
> On Sunday, August 14, 2016 at 7:37:25 AM UTC+2, Kasey Speakman wrote:
>>
>> So, I made a Gist 
>> <https://gist.github.com/kspeakman/109475ecdd3068a022b59f7f73c9485a> of 
>> the helper stuff which splits Facts and

[elm-discuss] Re: Child model change propagation problem in elm architecture

2016-08-17 Thread Kasey Speakman
Why were two inputs arbitrarily made into a component? If you're not 
reusing it, then why bother? In the broader picture, you are trying to 
apply object orientation (encapsulation), and it doesn't fit. It can't fit 
because the model does not ultimately belong to the component.

If you need to compose certain elements together for reuse, consider making 
it a view-only widget (a pure function), passing in the data and message 
constructors it needs to fulfill its purpose.

http://elm-lang.org/blog/blazing-fast-html#reusable-widgets

The thread Magnus linked is a good read as well.

On Tuesday, August 16, 2016 at 9:51:15 PM UTC-5, Jacky See wrote:
>
>
> Hi, I'm a new comer to elm. I try to build application using elm and have 
> some problem on component.
>
> Suppose I'm building an BMI calculator, initially I have a model
>
> type alias Model = { weight:Int, height:Int }
>
> The rendering is just an two input[type=number].
> The result is rendered by a pure function at the main app:
>
> calclulate model = 
>   let 
> h = (toFloat model.height) / 100
> w = toFloat model.weight
>   in
> toString (round (w / (h*h)))
>
>
> One day a decision made to change those two inputs into a component of its 
> own (BmiConfig). 
> So the models become
>
> --at main app 
> type alias Model = { bmiConfig: BmiConfig.Model ... }
>
> --at BmiConfig
> type alias Model = {weight:Int, height:Int}
>
> We need to to the work of connecting Msg, etc. The calculate function 
> becomes
>
> calclulate model = 
>   let 
> h = (toFloat model.config.height) / 100
> w = toFloat model.config.weight
>   in
> toString (round (w / (h*h)))
>
>
> Another a change comes and requesting add +/- button to the number input. 
> We try to make a small generic component NumberInput. Models become:
>
> --at main app 
> type alias Model = { bmiConfig: BmiConfig.Model ... }
>
> --at BmiConfig
> type alias Model = {weight:NumberInput.Model, height:NumberInput.Model}
> 
> --at NumberInput
>  type alias Model = {value:Int, max:Int, min:Int,  }
>
> The calculate function needs to be changed again:
>
> calculate model =
>   let 
> h = (toFloat model.config.height.value) / 100
> w = toFloat model.config.weight.value
>   in
> toString (round (w / (h*h)))
>
> It seems to me that every refactoring to extract component would lead to a 
> propagation
> of change all the ways from child to its parents. Parents need to know the 
> data
> structure of child to do calculation too. Is that the correct way of 
> applying the elm architecture?
> Have I missed something?
>  
>
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Exporting an event stream

2016-08-16 Thread Kasey Speakman
I watched a video on the debugger, and it seems possible to ignore the 
commands with some native javascript modifying Elm's behavior. Seems messy 
though.

On Tuesday, August 16, 2016 at 11:35:33 PM UTC-5, Zachary Kessin wrote:
>
> By Side effects I meant commands, sorry still have not had any tea yet 
> today 
>
> Zach
> ᐧ
>
> On Wed, Aug 17, 2016 at 7:34 AM, Zachary Kessin <zke...@gmail.com 
> > wrote:
>
>> I think the format for exporting types must be someform of json encoding, 
>> for everyone's sanity. And I think when you are in "Re play mode" side 
>> effects should be ignored in favor of the existing events.
>>
>> Zach
>> ᐧ
>>
>> On Tue, Aug 16, 2016 at 7:35 PM, Kasey Speakman <kjspe...@gmail.com 
>> > wrote:
>>
>>> I've started looking at this. The first hurdle is that updates return 
>>> both a model update and a side effect. So you could not replay side effects 
>>> as they may not be deterministic. (Replay produces Cmd which returns a 
>>> different result message from first time. The time traveling debugger gets 
>>> around this by disabling Cmd when replaying.) Not to mention running Cmds 
>>> depends on some outside access (at least mocking it).
>>>
>>> There is a discussion of that here 
>>> <https://groups.google.com/forum/#!topic/elm-discuss/yKRYkoiQmPs> and I 
>>> made a gist of a possible way to implement side effect isolation here 
>>> <https://gist.github.com/kspeakman/109475ecdd3068a022b59f7f73c9485a>. 
>>> Look at the comment first to see what it looks like in use.
>>>
>>> The other hurdle is events are likely to be union types with data. All 
>>> the JSON encoding/decoding I've see in Elm for union types are for the 
>>> simple kind where the case has no other values (like an enum). So having a 
>>> case with values will be a challenge. In JSON.NET, serialized F# union 
>>> type `CaseName ("something", 1, 3.5)` would look like this: `{ "Case": 
>>> "CaseName", "Fields": ["something", 1, 3.5] }`. Note: case values are 
>>> tuples in F#. Javascript allows arrays to contain dissimilar types, so this 
>>> works.
>>>
>>> But, making a custom encoder/decoder for every union case makes you want 
>>> to rethink life choices. Indeed, it might be better to just use Redux-style 
>>> messages where the type is a string so you can send the events out of a 
>>> port for free. It's a shame to lose out on that nice union syntax, but man 
>>> the pain.
>>>
>>> Even then, you will still feel the pain on decoding. Actually, decoding 
>>> anything is painfully manual in Elm. However, there are no surprises that 
>>> way.
>>>
>>> On Thursday, July 28, 2016 at 6:58:58 AM UTC-5, Zachary Kessin wrote:
>>>>
>>>> I know the idea of having an event stream that can be exported and 
>>>> replayed has been kicked around a bit for a while. Has anyone ever done 
>>>> anything with this? 
>>>>
>>>> Ideally I would like to be able to generate a sequence of events with a 
>>>> QuickCheck type tool (either in elm or erlang)
>>>>
>>>> Zach
>>>>
>>>> -- 
>>>> Zach Kessin
>>>> SquareTarget <http://squaretarget.rocks?utm_source=email-sig>
>>>> Twitter: @zkessin <https://twitter.com/zkessin>
>>>> Skype: zachkessin
>>>> ᐧ
>>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Elm Discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to elm-discuss...@googlegroups.com .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> -- 
>> Zach Kessin
>> SquareTarget <http://squaretarget.rocks?utm_source=email-sig>
>> Twitter: @zkessin <https://twitter.com/zkessin>
>> Skype: zachkessin
>>
>
>
>
> -- 
> Zach Kessin
> SquareTarget <http://squaretarget.rocks?utm_source=email-sig>
> Twitter: @zkessin <https://twitter.com/zkessin>
> Skype: zachkessin
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Exporting an event stream

2016-08-16 Thread Kasey Speakman
I've started looking at this. The first hurdle is that updates return both 
a model update and a side effect. So you could not replay side effects as 
they may not be deterministic. (Replay produces Cmd which returns a 
different result message from first time. The time traveling debugger gets 
around this by disabling Cmd when replaying.) Not to mention running Cmds 
depends on some outside access (at least mocking it).

There is a discussion of that here 
 and I 
made a gist of a possible way to implement side effect isolation here 
. Look 
at the comment first to see what it looks like in use.

The other hurdle is events are likely to be union types with data. All the 
JSON encoding/decoding I've see in Elm for union types are for the simple 
kind where the case has no other values (like an enum). So having a case 
with values will be a challenge. In JSON.NET, serialized F# union type 
`CaseName ("something", 1, 3.5)` would look like this: `{ "Case": 
"CaseName", "Fields": ["something", 1, 3.5] }`. Note: case values are 
tuples in F#. Javascript allows arrays to contain dissimilar types, so this 
works.

But, making a custom encoder/decoder for every union case makes you want to 
rethink life choices. Indeed, it might be better to just use Redux-style 
messages where the type is a string so you can send the events out of a 
port for free. It's a shame to lose out on that nice union syntax, but man 
the pain.

Even then, you will still feel the pain on decoding. Actually, decoding 
anything is painfully manual in Elm. However, there are no surprises that 
way.

On Thursday, July 28, 2016 at 6:58:58 AM UTC-5, Zachary Kessin wrote:
>
> I know the idea of having an event stream that can be exported and 
> replayed has been kicked around a bit for a while. Has anyone ever done 
> anything with this? 
>
> Ideally I would like to be able to generate a sequence of events with a 
> QuickCheck type tool (either in elm or erlang)
>
> Zach
>
> -- 
> Zach Kessin
> SquareTarget 
> Twitter: @zkessin 
> Skype: zachkessin
> ᐧ
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-13 Thread Kasey Speakman
So, I made a Gist 
 of the 
helper stuff which splits Facts and Acts. I call the helper Factor... (Fact 
or Act ~=> Factor). There is a subsequent comment with an example program 
explaining the helper's usage.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-12 Thread Kasey Speakman
Hmm, union types are JSON-serializable elsewhere (e.g. JSON.NET, although 
they are gly in JSON), so just something that eventually needs doing I 
suppose.

What conversion method did you have in mind that's not hard?

On Friday, August 12, 2016 at 1:59:43 PM UTC-5, OvermindDL1 wrote:
>
> I entirely missed that.  ^.^
>
> Hmm, is interesting.  Flags take Json'able types so those would not be 
> passable there, would need to convert first, but not hard.
>
>
>
> On Friday, August 12, 2016 at 12:53:36 PM UTC-6, Kasey Speakman wrote:
>>
>> I did that if you look at link to marcosh's github I posted above.
>>
>> On Friday, August 12, 2016 at 1:50:12 PM UTC-5, OvermindDL1 wrote:
>>>
>>> Hmm, I'd be curious if you could whip up a full compileable example, say 
>>> a Multi-Counter project example we could paste into elm-try.  Perhaps mark 
>>> things that are boilerplate and could be hoisted out to a parent library 
>>> too so we can ignore those?  :-)
>>>
>>>
>>> On Friday, August 12, 2016 at 12:15:20 PM UTC-6, Kasey Speakman wrote:
>>>>
>>>> Skimming through the code, it looks like batch commands will happen in 
>>>> order. The mentioned `mailbox.push` was from the Elm source code.
>>>>
>>>> Also, I fleshed out an example with both a clean separation and using 
>>>> event sourcing. I posted it with some commentary on marcosh's github 
>>>> <https://github.com/marcosh/marcosh.github.io/issues/1>.
>>>>
>>>> I like the terminology in this example much better than my previous 
>>>> examples, especially because `Action` was a previous concept in Elm.
>>>>
>>>> type Act = Increment | Decrement
>>>>
>>>> type Fact = Incremented Int | Decremented Int
>>>>
>>>> type Msg = Perform Act | Apply Fact
>>>>
>>>> perform : Act -> Model -> Cmd Msg
>>>>
>>>> apply : Fact -> Model -> Model
>>>>
>>>> update : Msg -> Model -> (Model, Cmd Msg)
>>>> update msg model =
>>>>   case msg of
>>>> Perform act ->
>>>>   (model, perform act model)
>>>>
>>>> Apply fact ->
>>>>   (apply fact model, Cmd.none)
>>>>
>>>>
>>>> The Facts here are also idempotent 
>>>> <https://en.wikipedia.org/wiki/Idempotence> (no dependency on previous 
>>>> values). That's not as important in this example, but can as its extended.
>>>>
>>>> On Friday, August 12, 2016 at 9:15:23 AM UTC-5, OvermindDL1 wrote:
>>>>>
>>>>> Will your pushed command appear after or before a potentially pushed 
>>>>> 'other' command, say from an incoming port, or button click?  That is the 
>>>>> part I am not sure about yet (not read enough Elm internals 'quite' yet).
>>>>>
>>>>> On Thursday, August 11, 2016 at 6:31:06 PM UTC-6, Kasey Speakman wrote:
>>>>>>
>>>>>> Checked the current implementation of Cmd.batch and it appears 
>>>>>> sequential (`mailbox.push`). Ordering guarantees are not documented so I 
>>>>>> suppose they shouldn't be depended on. But otherwise, the one I coded 
>>>>>> above 
>>>>>> that guarantees Act doesn't change the model and Evt doesn't have 
>>>>>> effects 
>>>>>> would work.
>>>>>>
>>>>>> On Thursday, August 11, 2016 at 6:33:39 PM UTC-5, Kasey Speakman 
>>>>>> wrote:
>>>>>>>
>>>>>>> Yes, that's why I said back to square one if Cmd.batch isn't 
>>>>>>> ordered. The only thing this is guaranteeing (and the only intended 
>>>>>>> guarantee) is that the messages which only update the model are 
>>>>>>> separated 
>>>>>>> from the ones which cause effects. The ones which cause effects produce 
>>>>>>> ones which update the model, same as always.
>>>>>>>
>>>>>>> It occurs to me that some of the benefit of event sourcing the UI 
>>>>>>> could be gained by adding features to the TTD, since it has the magic 
>>>>>>> which 
>>>>>>> ignores Cmds on replay. Some are already listed as ideas at 
>>>>>>> http://debug.elm-lang.org/. I'd still have to keep the messages in 
>>>>>>> m

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Yes, that's why I said back to square one if Cmd.batch isn't ordered. The 
only thing this is guaranteeing (and the only intended guarantee) is that 
the messages which only update the model are separated from the ones which 
cause effects. The ones which cause effects produce ones which update the 
model, same as always.

It occurs to me that some of the benefit of event sourcing the UI could be 
gained by adding features to the TTD, since it has the magic which ignores 
Cmds on replay. Some are already listed as ideas at 
http://debug.elm-lang.org/. I'd still have to keep the messages in my model 
and provide a way for the user to transmit them in a bug report. But if I 
could load them in the TTD, that would make repro a snap.

On Thursday, August 11, 2016 at 5:22:05 PM UTC-5, OvermindDL1 wrote:
>
> Isn't `doSideEffects` basically just the current `update` function 
> though?  Except it is returning a list of changes (via message) to perform 
> to a model instead of doing it in-place?  What is this saving precisely?
>
>
>
> On Thursday, August 11, 2016 at 4:05:57 PM UTC-6, Kasey Speakman wrote:
>>
>> Actually, I'd probably use a List instead of Maybe on the immediately 
>> returned event(s).
>>
>> doSideEffects : Act -> Model -> (List Evt, Cmd Evt)
>> doSideEffects act model = 
>>   case act of
>> UpdateCustomer customer ->
>>   ( [ CustomerUpdateRequested ]
>>   , callServerWithCustomer customer
>>   )
>>
>> ...
>>
>> updateModel : Evt -> Model -> Model
>> ... -- implementation as previous
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>   case msg of
>> Action act ->
>>   let
>> (events, command) = doSideEffects act model
>>   in
>>     (List.foldr updateModel model events, Cmd.map Evt command)
>>
>> Event evt ->
>>   (updateModel evt model, Cmd.none)
>>
>>
>>
>> On Thursday, August 11, 2016 at 4:26:03 PM UTC-5, Kasey Speakman wrote:
>>>
>>> Yes, that was the goal. That way the UI state is utterly deterministic / 
>>> reproducible in isolation of all outside services.
>>>
>>> That's a good point on the race conditions. I only use Cmd.batch because 
>>> it's the facility that came to mind. (I'm still getting acquainted with 
>>> Elm.) I don't know if Cmd.batch makes any ordering guarantee.
>>>
>>> If not we'd be more or less back to square one. Abuse `update` to do 
>>> both things.
>>>
>>> doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt)
>>> doSideEffects act model =
>>>   case act of
>>> UpdateCustomer customer ->
>>>   (Just CustomerUpdateRequested, callServerWithCustomer customer)
>>>
>>> ...
>>>
>>> updateModel: Evt -> Model -> Model
>>> ... -- implementation as previous
>>>
>>> maybeUpdateModel:  Maybe Evt -> Model -> Model
>>> maybeUpdateModel evtOpt model =
>>>   case evtOpt of
>>> Nothing ->
>>>   model
>>>
>>> Just evt ->
>>>   updateModel evt model
>>>
>>> update : Msg -> Model -> (Model, Cmd Msg)
>>> update msg model =
>>>   case msg of
>>> Action act ->
>>>   let
>>> (eventNow, command) = doSideEffects act model
>>>   in
>>> (maybeUpdateModel eventNow model, Cmd.map Evt command)
>>>
>>> Event evt ->
>>>   (updateModel evt model, Cmd.none)
>>>
>>> So this should apply an event immediately if one is needed for the 
>>> action. But it still keeps the model updating events separate.
>>>
>>> These immediate events would be seen by a userland event-store 
>>> implementation (which is underneath updateModel), but I bet the TTD 
>>> wouldn't see it since it doesn't come from Elm.
>>>
>>> On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote:
>>>>
>>>> So you really are wanting to hard device events into two different 
>>>> ones, those that can *only* alter the model, and those that can *only* 
>>>> send 
>>>> commands (which may call ones that alter the model).  Unsure if it might 
>>>> actually happen but might have to take into account possible race 
>>>> conditions for if other messages appear before your other expected ones 
>>>> are 
>>>> processed through?  Easier to do that atomically all at once?
>>>>
>>>>
>>>> On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:
>>>>>
>>>>> doSideEffects above would also have to map Cmd Evt to Cmd Msg.
>>>>>
>>>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Actually, I'd probably use a List instead of Maybe on the immediately 
returned event(s).

doSideEffects : Act -> Model -> (List Evt, Cmd Evt)
doSideEffects act model = 
  case act of
UpdateCustomer customer ->
  ( [ CustomerUpdateRequested ]
  , callServerWithCustomer customer
  )

...

updateModel : Evt -> Model -> Model
... -- implementation as previous

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
Action act ->
  let
(events, command) = doSideEffects act model
  in
(List.foldr updateModel model events, Cmd.map Evt command)

Event evt ->
  (updateModel evt model, Cmd.none)



On Thursday, August 11, 2016 at 4:26:03 PM UTC-5, Kasey Speakman wrote:
>
> Yes, that was the goal. That way the UI state is utterly deterministic / 
> reproducible in isolation of all outside services.
>
> That's a good point on the race conditions. I only use Cmd.batch because 
> it's the facility that came to mind. (I'm still getting acquainted with 
> Elm.) I don't know if Cmd.batch makes any ordering guarantee.
>
> If not we'd be more or less back to square one. Abuse `update` to do both 
> things.
>
> doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt)
> doSideEffects act model =
>   case act of
> UpdateCustomer customer ->
>   (Just CustomerUpdateRequested, callServerWithCustomer customer)
>
> ...
>
> updateModel: Evt -> Model -> Model
> ... -- implementation as previous
>
> maybeUpdateModel:  Maybe Evt -> Model -> Model
> maybeUpdateModel evtOpt model =
>   case evtOpt of
> Nothing ->
>   model
>
> Just evt ->
>   updateModel evt model
>
> update : Msg -> Model -> (Model, Cmd Msg)
> update msg model =
>   case msg of
> Action act ->
>   let
> (eventNow, command) = doSideEffects act model
>   in
> (maybeUpdateModel eventNow model, Cmd.map Evt command)
>
> Event evt ->
>   (updateModel evt model, Cmd.none)
>
> So this should apply an event immediately if one is needed for the action. 
> But it still keeps the model updating events separate.
>
> These immediate events would be seen by a userland event-store 
> implementation (which is underneath updateModel), but I bet the TTD 
> wouldn't see it since it doesn't come from Elm.
>
> On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote:
>>
>> So you really are wanting to hard device events into two different ones, 
>> those that can *only* alter the model, and those that can *only* send 
>> commands (which may call ones that alter the model).  Unsure if it might 
>> actually happen but might have to take into account possible race 
>> conditions for if other messages appear before your other expected ones are 
>> processed through?  Easier to do that atomically all at once?
>>
>>
>> On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:
>>>
>>> doSideEffects above would also have to map Cmd Evt to Cmd Msg.
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


  1   2   >