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

2017-07-24 Thread Christian Charukiewicz
You should not keep derived values in the model.  The model should be a 
single source of truth.  This property is violated if you store derived 
data in the model.  What happens if you create a new input that fires a 
different Msg that only updates the height, but does not recompute and 
update the BMI?  Should you now be reading from the weight and height 
fields?  Or should you be reading from the BMI?  Or what happens if you add 
a reset Msg?  If you store this derived BMI calculation in your model, you 
have 3 fields to worry about rather than 2.

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.


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

2017-07-24 Thread Ray Toal
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.


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

2017-07-24 Thread Erik Simmler
Despite your desire to isolate this aspect from other factors such as 
immutability, I don't think you can do that without missing the big 
picture. Elm's strength does not come from a list of features (types, 
immutability, controlled side effects, etc...), but rather from way that 
they have all been thoughtfully combined.

That said, what if we flip the question around? Given that we have 
facilities for encapsulation (unexposed types), what would we gain by 
adding a new set of concepts around mixing data/logic and syntactic sugar 
in the form of "this"? What would this enable?


On Thursday, July 20, 2017 at 3:55:54 AM UTC-4, 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.


Re: [elm-discuss] Immutable data design problem

2017-07-24 Thread Lyle Kopnicky
Hi Harry,

That's an interesting pattern I hadn't thought of. I had been thinking more 
along the lines of:

type alias AssessmentEvent a = { a |
otherField : Int
}

Then something like:

type alias InitialAssessmentEvent = AssessmentEvent {}

type alias ComputedAssessmentEvent = AssessmentEvent { accounts: List 
Account }

or even:

type alias WithAccounts a = { a | accounts: List Account }

type alias ComputedAssessmentEvent = AssessmentEvent (WithAccounts {})

...but those use raw records, no tagging. The tags allow for representation 
hiding and stronger typing guarantees. (That is, nobody can just make a 
record which happens to substitute for an AssessmentEvent just because they 
pick the right field names and types.)

Your proposal is an interesting way to do it but retain the type tags. And 
it keeps the data within the data structure that the caller would have a 
handle on, so they do not need to call some function on a parent object and 
an ID in order to indirectly retrieve the data.

That's becoming an important distinction for me. In my view code it's nice 
if when it has an AssessmentEvent, it can render that, then extract from 
that a list of Accounts, and render those. It's a different interface if it 
has to have a Parcel and an EventID and call a function to get a list of 
Accounts.

Thanks,
Lyle

On Monday, July 24, 2017 at 6:50:34 AM UTC-7, Harry Lachenmayer wrote:
>
> Hi Lyle,
>
> A fairly common pattern is to add a type parameter to the AssessmentEvent, 
> eg.:
>
> type AssessmentEvent a = AssessmentEvent {
>   otherField : Int,
>   accounts : a
> }
>
> You would model the case where the accounts are "an empty list" by adding 
> the type parameter () - the unit type 
> . This 
> is equivalent to making the value null in an object-oriented setting.
>
> You could then define a function to calculate the accounts:
>
> calculateAccounts : AssessmentEvent () -> AssessmentEvent (List Account)
>
> For convenience, you can also define type aliases:
>
> type alias InitialAssessmentEvent = AssessmentEvent ()
> type alias CalculatedAssessmentEvent = AssessmentEvent (List Account)
>
> calculateAccounts : InitialAssessmentEvent -> CalculatedAssessmentEvent
>
> (You can probably come up with better names ;) )
> You could then define a "getter" like this, which only operates on 
> AssessmentEvents that have had accounts calculated:
>
> accounts : CalculatedAssessmentEvent -> List Account
> accounts (AssessmentEvent {accounts}) = accounts
>
> Notice that if you do this, it's impossible to accidentally pass in 
> AssessmentEvents that haven't had their accounts calculated, ie. in the 
> case you mention ("at that point I know it will always be Just 
> something").
>
> Hope that helps!
> -harry
>
> On Mon, Jul 24, 2017 at 4:17 AM Aaron VonderHaar  > wrote:
>
>> I'm not sure I understand all the details of your domain model, but it 
>> seems like the notable point is that accounts are created implicitly as 
>> assessment events occur, and you'd like to be able to, given an assessment 
>> event, get the related accounts?
>>
>> I'd probably start with making a module (maybe called "AssessmentStore") 
>> that has functions that describe what you need.  I'm thinking something 
>> like:
>>
>> allEvents : AssessmentStore -> List AssessmentEvent
>>
>> and hmm... now that I write that out, it seems like that's all you want, 
>> except that you ideally want AssessmentEvent to have a list of Accounts in 
>> it.
>>
>> I think the approach I would prefer is similar to what you mention in 
>> your last paragraph about keeping the data in separate structures, but you 
>> question the safety of managing parallel structures.  If you create a 
>> separate module to encapsulates the data, you can can limit the need for 
>> careful handling to that single module.  I might try something like this in 
>> `AssessmentStore`:
>>
>> type AssessmentStore =
>> AssessmentStore 
>> { assessmentEventInfo : Dict EventId { name : String, ... } -- 
>> This is not the full AssessmentEvent; just the things that don't relate to 
>> accounts.
>> , accountsByEvent : Dict EventId (List AccountId)
>> , accountInfo : Dict AccountId Account
>> , allEvents : List EventId -- (or maybe you want them indexed 
>> differently, by time, etc)
>> }
>>
>> then have a function to create the assessment store, and then the 
>> `allEvents` functions suggested above (or any other function to get 
>> AssessmentEvents) can take the data in that private data structure and 
>> merge it together to give the data that you actually want to return to the 
>> caller.  In fact, you never need to expose the AccountIds/EventIds outside 
>> of this module.
>>
>> If you are still worried about safety, you can add more unit tests to 
>> this module, or try to define fuzz test properties to help you ensure that 
>> you handle the 

Re: [elm-discuss] Immutable data design problem

2017-07-24 Thread Lyle Kopnicky
Hi Aaron,

Thanks for your thoughtful reply.

The domain model is pretty complex, so it's hard to distill down to a few 
issues. There's a higher-level structure called a Parcel. That already 
contains, among other things, the list of AssessmentEvents. I have a 
function called createParcel that takes a record with a parcel number, 
initial owner, and list of AssessmentEvents. Those AssessmentEvents must in 
turn have been created by calling createAssessmentEvent, which takes the 
independent fields of an AssessmentEvent and creates the full record with 
the derived fields. However, there really are yet more fields that can't be 
derived by looking at a single AssessmentEvent in isolation. Some 
calculation has to be done by determining chains of them and computing 
deltas along the chain.

Currently I have createParcel computing a Dict of assessmentEventsById (so, 
it's assuming some ID already exists on the AssessmentEvents, which is a 
separate issue). It also computes a list of roll years that are relevant to 
the assessment events, which involves some date math. It computes an 
ownership chain - that is, a list of date ranges and who owned the property 
during that time range. And finally it computes the list of assessment 
events that are effective for each roll year. Each assessment event might 
appear in the list for as many as two consecutive years, depending on its 
dates.

Then there will have to be deltas calculated between the assessment events 
for a given roll year. The accounts will be created from those. And 
finally, one or two bills will be created from each account, depending on 
the type of assessment event. All of this will be completely deterministic, 
based on the initial seed data of assessment events. But I need these 
accounts and bills calculated in order to properly view the data.

If I am using IDs, then I can make a data structure that just contains the 
deltas by ID, rather than creating another AssessmentEvent structure that 
has room for the delta values. But that would mean that when outside code 
needed to get the delta value, it couldn't just have an AssessmentEvent. It 
would have to have an AssessmentStore (or Parcel) and an EventID and call a 
function which could use that to retrieve the delta value from the Dict. 
So, it's a pretty different model for the caller.

So far I have been putting all this logic in one module, called Property. 
(The view logic is in a separate module.) I've been using datatypes with a 
single constructor, so the view code can pattern match against them. But 
now I'm starting to wonder whether it'd be safer to hide the 
representations here in the Property module.

At some point in the future I will want to allow adding/removing/updating 
assessment events in real time. Then I will have to decide whether I want 
to just recalculate the entire set of data or try to figure out which bits 
need to change. Recalculating the whole thing will probably be performant 
enough. But I guess there could be an issue with IDs - if some data gets 
loaded from the database and needs to preserve existing IDs, I can't just 
generate new IDs for the whole set. I'll figure out that problem when I 
come to it.

Regards,
Lyle

On Sunday, July 23, 2017 at 8:17:07 PM UTC-7, Aaron VonderHaar wrote:
>
> I'm not sure I understand all the details of your domain model, but it 
> seems like the notable point is that accounts are created implicitly as 
> assessment events occur, and you'd like to be able to, given an assessment 
> event, get the related accounts?
>
> I'd probably start with making a module (maybe called "AssessmentStore") 
> that has functions that describe what you need.  I'm thinking something 
> like:
>
> allEvents : AssessmentStore -> List AssessmentEvent
>
> and hmm... now that I write that out, it seems like that's all you want, 
> except that you ideally want AssessmentEvent to have a list of Accounts in 
> it.
>
> I think the approach I would prefer is similar to what you mention in your 
> last paragraph about keeping the data in separate structures, but you 
> question the safety of managing parallel structures.  If you create a 
> separate module to encapsulates the data, you can can limit the need for 
> careful handling to that single module.  I might try something like this in 
> `AssessmentStore`:
>
> type AssessmentStore =
> AssessmentStore 
> { assessmentEventInfo : Dict EventId { name : String, ... } -- 
> This is not the full AssessmentEvent; just the things that don't relate to 
> accounts.
> , accountsByEvent : Dict EventId (List AccountId)
> , accountInfo : Dict AccountId Account
> , allEvents : List EventId -- (or maybe you want them indexed 
> differently, by time, etc)
> }
>
> then have a function to create the assessment store, and then the 
> `allEvents` functions suggested above (or any other function to get 
> AssessmentEvents) can take the data in that private data structure and 

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

2017-07-24 Thread Marcus Roberts
Dave

Perhaps I'm being bit oversensitive, but this does seem to be a rather
argumentative approach.I know you said you learn by arguing, but this
seems to be turning into a dogmatic crossing of swords, rather like walking
into a British pub and declaring the local football team a load of rubbish
:)


On Mon, Jul 24, 2017 at 6:50 PM, 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.
>

-- 
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: Looping While/Until

2017-07-24 Thread Yosuke Torii
Hi John,

I don't know the reason why Elm does not have them but Elm's core library 
usually gives best minimum set of functions. For example, List module don't 
have `find`, `zip`, and `scanl` that are included in community package 
named list-extra 
.
 
But I don't think all of them should always be listed in core, simply 
because it is too many. So it should be important how often we use them or 
how these functions effectively work in practice.

I agree that basically it is better to not write a bare recursion. I also 
agree `until : (a -> Bool) -> (a -> a) -> a -> a` is better than `until 
: (a -> Bool) -> a -> (a -> a) -> a`. But in my daily development, 
generating a list or calculating until some condition is very rare logic. I 
wonder which is easier to choose/remember a function or to write/read a 
recursive function.


2017年7月24日月曜日 19時13分09秒 UTC+9 John Bugner:
>
> For example, making a function that flood fills an area from a given start 
> point. You know that it'll eventually end, but you don't know exactly how 
> many times you need to recurse, unlike 'map' or 'fold', where the number of 
> times is the same as the number of items in the list/collection.
>
> It's basically a wrapper for the recursion, letting your function focus on 
> the logic.
>
> On Monday, July 10, 2017 at 10:28:15 AM UTC-5, Erkal Selman wrote:
>>
>> What exactly do you need the while-loop for?
>>
>> On Thursday, July 6, 2017 at 7:04:18 AM UTC+2, John Bugner wrote:
>>>
>>> In imperative OO languages, there are for/while loops:
>>>
>>> A for-loop often looks like this:
>>>
>>> for (i = 0; i < 100; i++) {
>>>   a[i] = f(i);
>>> }
>>>
>>> In Elm (and Haskell), we have the neat `map` function that captures this 
>>> pattern:
>>>
>>> map f a
>>>
>>> A while-loop looks like this:
>>>
>>> while (!isDone(s)) {
>>>   f(s);
>>> }
>>>
>>> Haskell has the `until` function that captures this pattern:
>>>
>>> until isDone f s
>>>
>>> Elm lacks this function. Is there a reason why? What's the current elmic 
>>> way of doing this? Explicit recursion, I assume?
>>>
>>> Anyways, it seems that somebody else already yearned for `until` like 
>>> me, and made this module: 
>>> http://package.elm-lang.org/packages/Chadtech/elm-loop/1.0.2/Loop ...
>>>
>>> I note though, that he changed the order of the arguments from Haskell's 
>>> `(a -> Bool) -> (a -> a) -> a -> a` to `(a -> Bool) -> a -> (a -> a) -> a`. 
>>> I'm not sure why. If he wanted to match the usual impOO order, then why not 
>>> `a -> (a -> Bool) -> (a -> a) -> a` instead ? Anyways, I think Haskell's 
>>> order is the right order, because it let's you make useful closures, like 
>>> this:
>>>
>>> collatz : Int -> Int
>>> collatz =
>>>   let
>>> u : Int -> Int
>>> u n =
>>>   if isEven n
>>>   then n // 2
>>>   else 3 * n + 1
>>>   in
>>> until ((==) 1) u
>>>
>>> This function is elegantly defined, but not very useful, because the 
>>> result of every (positive) number will simply return 1 (mathematicians 
>>> strongly suspect so, anyways). What's interesting is the *sequence* that a 
>>> number makes on it's way down to 1. So I made a function that repeats like 
>>> `until`, but also records each intermediate result in a list, like `scanl`:
>>>
>>> scanUntil : (a -> Bool) -> (a -> a) -> a -> List a
>>> scanUntil p u s =
>>>   let
>>> p_ : List a -> Bool
>>> p_ xs = case xs of
>>> [] -> True
>>> x :: _ -> p x
>>> u_ : List a -> List a
>>> u_ xs = case xs of
>>> [] -> []
>>> x :: _ -> u x :: xs
>>>   in
>>> until p_ u_ [s]
>>>
>>> I'm not sure that `scanUntil` is the best name. Can anybody think of a 
>>> better name? I also note that list that it returns is reversed compared to 
>>> `scanl`'s and Haskell's `iterate` function ( 
>>> https://hackage.haskell.org/package/base-4.7.0.2/docs/Prelude.html#v:iterate
>>>  
>>> ), but feels right because the most useful value is probably going to be 
>>> the last one calculated. But maybe this doesn't matter, because if you 
>>> really want the last one calculated, then you'd just use `until` instead 
>>> anyways.
>>>
>>> Anyways... answers, thoughts, and comments are welcome.
>>>
>>>

-- 
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 

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

2017-07-24 Thread David Andrews
As far as I'm concerned, this is just syntactic sugar.  I've noticed that
elm has a convention to use the last parameter in a function where an OO
programmer would use this.  Using this convention, code winds up being very
similar when used.

OO version:
model
.getSomeProperty
.withDefault(3)

Elm version:
model
|> getSomeProperty
|> Maybe.withDefault 3



On Mon, Jul 24, 2017 at 1:50 PM 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.
>

-- 
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 Dave Ford
>
> 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: 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: Looping While/Until

2017-07-24 Thread John Bugner
For example, making a function that flood fills an area from a given start 
point. You know that it'll eventually end, but you don't know exactly how 
many times you need to recurse, unlike 'map' or 'fold', where the number of 
times is the same as the number of items in the list/collection.

It's basically a wrapper for the recursion, letting your function focus on 
the logic.

On Monday, July 10, 2017 at 10:28:15 AM UTC-5, Erkal Selman wrote:
>
> What exactly do you need the while-loop for?
>
> On Thursday, July 6, 2017 at 7:04:18 AM UTC+2, John Bugner wrote:
>>
>> In imperative OO languages, there are for/while loops:
>>
>> A for-loop often looks like this:
>>
>> for (i = 0; i < 100; i++) {
>>   a[i] = f(i);
>> }
>>
>> In Elm (and Haskell), we have the neat `map` function that captures this 
>> pattern:
>>
>> map f a
>>
>> A while-loop looks like this:
>>
>> while (!isDone(s)) {
>>   f(s);
>> }
>>
>> Haskell has the `until` function that captures this pattern:
>>
>> until isDone f s
>>
>> Elm lacks this function. Is there a reason why? What's the current elmic 
>> way of doing this? Explicit recursion, I assume?
>>
>> Anyways, it seems that somebody else already yearned for `until` like me, 
>> and made this module: 
>> http://package.elm-lang.org/packages/Chadtech/elm-loop/1.0.2/Loop ...
>>
>> I note though, that he changed the order of the arguments from Haskell's 
>> `(a -> Bool) -> (a -> a) -> a -> a` to `(a -> Bool) -> a -> (a -> a) -> a`. 
>> I'm not sure why. If he wanted to match the usual impOO order, then why not 
>> `a -> (a -> Bool) -> (a -> a) -> a` instead ? Anyways, I think Haskell's 
>> order is the right order, because it let's you make useful closures, like 
>> this:
>>
>> collatz : Int -> Int
>> collatz =
>>   let
>> u : Int -> Int
>> u n =
>>   if isEven n
>>   then n // 2
>>   else 3 * n + 1
>>   in
>> until ((==) 1) u
>>
>> This function is elegantly defined, but not very useful, because the 
>> result of every (positive) number will simply return 1 (mathematicians 
>> strongly suspect so, anyways). What's interesting is the *sequence* that a 
>> number makes on it's way down to 1. So I made a function that repeats like 
>> `until`, but also records each intermediate result in a list, like `scanl`:
>>
>> scanUntil : (a -> Bool) -> (a -> a) -> a -> List a
>> scanUntil p u s =
>>   let
>> p_ : List a -> Bool
>> p_ xs = case xs of
>> [] -> True
>> x :: _ -> p x
>> u_ : List a -> List a
>> u_ xs = case xs of
>> [] -> []
>> x :: _ -> u x :: xs
>>   in
>> until p_ u_ [s]
>>
>> I'm not sure that `scanUntil` is the best name. Can anybody think of a 
>> better name? I also note that list that it returns is reversed compared to 
>> `scanl`'s and Haskell's `iterate` function ( 
>> https://hackage.haskell.org/package/base-4.7.0.2/docs/Prelude.html#v:iterate 
>> ), but feels right because the most useful value is probably going to be 
>> the last one calculated. But maybe this doesn't matter, because if you 
>> really want the last one calculated, then you'd just use `until` instead 
>> anyways.
>>
>> Anyways... answers, thoughts, and comments are welcome.
>>
>>

-- 
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.