[elm-discuss] Using extensible records for optional attributes?

2017-08-01 Thread Mike Austin
I'm curious if it's possible to use extensible records for HTML attributes 
instead of lists of function application such as [id "foo", class "bar"]?
I've poked around a bit, but didn't find too much on specifically this. For 
example, something along the lines of this:


  let x = anchor { href = "#", id = Just "root" }


Something along the lines of defining common attributes all being maybe 
types, and then combining it with a record passed to a function.


  type alias CommonAttrs a =
   { a | id : Maybe String, class : Maybe String }

  commonAttrs : a -> CommonAttrs a
  commonAttrs x =
{ x | id = Nothing, class = Nothing }

  anchor : { a | href : String } -> CommonAttrs { href : String }
  anchor attrs =
commonAttrs attrs


I know that's not going to work, but something along those lines. I'm new 
to Elm and only somewhat familiar with Haskell.

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] elm-tools/parser: how to access intermediate parsed objects downstream in parsing pipeline?

2017-08-01 Thread Dave Doty
The elm-tools/parser documentation recommends using parsing pipelines such 
as 

type alias Point = { x : Float, y : Float}
point : Parser Pointpoint =
  succeed Point
|. symbol "("
|. spaces
|= float
|. spaces
|. symbol ","
|. spaces
|= float
|. spaces
|. symbol ")"
spaces : Parser ()spaces =
  ignore zeroOrMore (\c -> c == ' ')


I am parsing text in this way, but it is much longer than just two floats. 
The high-level parser parses text with five major parts in order 
(describing portions of a finite automaton) and it looks like this (and 
uses five "subroutine" parsers that I've not shown):

type alias State = String
type alias DFATransition = State -> Char -> Result String State
type alias DFA =
{ states : List State
, inputAlphabet : List Char
, startState : State
, acceptStates : List State
, delta : DFATransition
}

dfaParser : Parser.Parser DFA
dfaParser =
Parser.succeed DFA
|. spaces
|. Parser.keyword "states:"
|. spaces
|= statesParser
|. spaces
|. Parser.keyword "input_alphabet:"
|. spaces
|= alphabetParser
|. spaces
|. Parser.keyword "start_state:"
|. spaces
|= startStateParser
|. spaces
|. Parser.keyword "accept_states:"
|. spaces
|= statesParser
|. spaces
|. Parser.keyword "delta:"
|. spaces
|= deltaParser
|. spaces

to parse text such as, for instance, 

"""
states:  {q,q0,q00,q000}
input_alphabet:  {0,1}
start_state: q
accept_states:   {q,q0,q00}
delta:
q,1-> q
q0,1   -> q
q00,1  -> q
q000,1 -> q
q,0-> q0
q0,0   -> q00
q00,0  -> q000
q000,0 -> q000
"""

Here's what I want to do: insert code in the middle of the pipeline that 
can reference the data that has been parsed so far.

For example, after this portion of the pipeline has succeeded: 

dfaParser =
Parser.succeed DFA
|. spaces
|. Parser.keyword "states:"
|. spaces
|= statesParser
|. spaces
|. Parser.keyword "input_alphabet:"
|. spaces
|= alphabetParser
...

then the data for states and alphabet have been successfully parsed into 
two Lists. I would like to access those lists by name, later down the 
pipeline. 

One reason is that I would like to pass those lists as input to subsequent 
parsers (startStateParser, acceptStatesParser, and deltaParser), to help 
them do error-checking. 

For example, the next thing parsed is a String parsed by startStateParser, 
and I want to ensure that the parsed String is an element of the List 
parsed by statesParser. But at the time I put the line |= startStateParser 
in the pipeline, the parsed result of statesParser doesn't have a name that 
I can refer to.

Another reason is that I want to do error-checking in the middle of a 
pipeline. For example, my implementation of deltaParser reads the lines 
such as "q,0 -> q0" and "q0,1 -> q" one at a time, and I would like to 
access data parsed by previous lines when looking for errors on the current 
line. (For example, it is an error to have duplicates on the left side of -> 
such as the line "q,1 -> q" followed later by "q,1 -> q0", but to indicate 
this error and reference the correct line number, I need access to the 
lines parsed so far as I am processing the line with the error.)

I get the feeling that perhaps I'm structuring this incorrectly, so I 
welcome advice on a better way to structure the parser.

-- 
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] Passing whole state to each view function

2017-08-01 Thread Andrew Stoeckley
Hi Mark, feel free to hit me up on Slack sometime to discuss further. My last 
two messages to this list have had more than one week delay in posting (ignore 
the timestamp, I'm posting this on Friday July 21), so that might be easier. 

I discussed these ideas quite a bit with @ilias and he made a rather 
interesting example of doing some things relating to state access: 
https://github.com/zwilias/elm-disco

I'm a firm believer that view functions should only receive data that they 
directly interact with, and nothing more. I've just found that to be a much 
better way to reason about interfaces.

> On 21 Jul 2017, at 19:04, Mark Hamburg  wrote:
> 
> Per the other thread discussing this this morning, I don't know that passing 
> the whole data model to all of the view-side functions is that horrendous. 
> (We pass around a UXConfig structure in all of our views to provide access to 
> translation functions amongst other things and the biggest pain is that I'm 
> not certain that making it he first parameter by convention was the right 
> choice.) Passing the whole data model feels icky, but you can document the 
> dependencies using different modules to access different parts of the data 
> model and you can still keep data model mutation out of the views by 
> emulating the command mechanism.
> 
> That said, there are, definitely friction points where being able to 
> subscribe to pieces of the data model would be a significant improvement. See 
> my other message for some examples of these. But the friction is not in 
> needing to pass the whole data model through the rendering process.
> 
> Mark
> 
>> On Fri, Jul 21, 2017 at 6:55 AM ajs  wrote:
>> > However, the downside of doing passing the entire model everywhere is that 
>> > you have to keep the entire model in your head when looking at any of your 
>> > view functions.
>> 
>> This is correct, but how can you avoid passing the whole model to all views 
>> if the data model isn't structured similarly to your view hierarchy? The 
>> idea of doing pre-processing on your data into a view-friendly structure 
>> seems to add overhead and complexity, while also more or less duplicating 
>> your view structure in two places: the view stack, and the view data.
>> 
>> We have found that as apps grow in size, it is unreasonable to couple a data 
>> model's internal structure to the requirements of a UI, and thus passing The 
>> whole model is the only valid option for most view functions. The exception 
>> are leaf nodes down the line that have few or no children, in which case 
>> they can receive focused inputs only.
>> 
>> --
>> 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/F5pdcsls1Zc/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.


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

2017-08-01 Thread John Bortins
Ha! I just stumbled onto this recently to solve an ugly performance issue 
and it works great.

The cost is a layer of complexity added to the update function. In this 
way, the intermediate calculations need be done just once per update rather 
than spread out many times over the view. Well worth the effort to keep 
users oblivious to the difficulties and happy with the results. 

Perhaps there is a way to store such dependent state separately? Until then 
I shall keep this technique close to hand.

On Tuesday, July 25, 2017 at 3:11:22 AM UTC-4, Peter Damoc wrote:
>
> Keep derived data in the model if it makes sense to keep derived data in 
> the model. 
>

   . . . 
 

> 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: Elm.fullscreen is not a function

2017-08-01 Thread Allan Clark
Also new to Elm so I may be wrong, but assuming your program is
defined in the module 'Main.elm' I think you want:

Elm.Main.fullscreen();

On 7 July 2017 at 21:38, Denis Kolodin  wrote:
> Another reason for 0.18: I take `Elm.MyApp.fullscreen is not a function`
> when I forget to add `main` (which calls `Html.program`) function to MyApp
> module.
>
> On Wednesday, June 29, 2016 at 12:29:24 PM UTC+3, Stuart Axon wrote:
>>
>> I've been getting started with elm using the environment described here
>> https://boonofcode.svbtle.com/setting-up-an-atom-elm-dev-environment   I
>> have an index.html as below, but am getting -
>>
>> TypeError: Elm.fullscreen is not a function
>>
>> Any idea what I need to change ?
>>
>>
>>> 
>>> 
>>> 
>>> 
>>> My App
>>> 
>>> 
>>> 
>>> 
>>> 
>>> Elm.fullscreen(Elm.Main);
>>> 
>>> 
>>> 
>>
>>
>>
> --
> 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.


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

2017-08-01 Thread ajs
I got plenty of discussion on this in Slack while this was awaiting 
moderation for a week or so; I don't think there is need to get into it 
again. I'm comfortable with the feedback I got there. Thanks for all the 
input and (spirited) talks about this! :)

On Friday, July 21, 2017 at 3:55:42 PM UTC+2, 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 arises is when a child requires access to more than 
> one part of the central model, and those parts are not "in the same place". 
>
> One "solution": you pass the entire model state to all view functions, 
> then each view just takes what it needs. But this is very poor for a 
> variety of reasons, not the least of which is that children now have much 
> more access than they need. And it can lead to more code as each child has 
> to go grab what it needs from a large monolithic data source before 
> operating it -- it requires children to be responsible for both the query 
> and the processing. It makes it hard to trace data access through your app 
> when all views access the same global model. And it requires more code on 
> behalf of children.
>
> Here are two Elm examples that show the problem:
>
> Line 22 on:
> https://ellie-app.com/3JbGH7v2v7ra1/1
> How to give the child data that its parent didn't need or receive? Here, 
> I've hard-coded it to 0 because there is no other obvious way to access 
> what the child needs.
>
> Another attempt:
> https://ellie-app.com/3JbNQk26qNRa1/0
> On Line 32, an ancestor is still having to hunt down data that a 
> potentially very distant child would need, and actually handle the building 
> of that child.
>
> We have an app with hundreds, perhaps over a