[elm-discuss] Record syntax overhaul

2017-03-01 Thread Francesco Orsenigo
I'm posting this here rather than in elm-dev because the discussion might 
get both long and broad.
Also, as much as I would like to help out, I understand that only Evan 
changes the compiler.

The matter has been discussed already, and it might be useful to get an 
idea of the prior thoughts:

This is a previous discussion that evaluated a few different proposals:
https://github.com/elm-lang/elm-compiler/issues/984

This is a very useful summary of the ideas considered:
https://gist.github.com/rtfeldman/f4b04468f3d865c4135153fea29d23f7

What follow is my personal experience; the TL;DR version is "Any proposed 
overhaul of record syntax should consider not only instance manipulation, 
but also record type manipulation".

---

The issues I personally encountered are:

1)
There is a common pattern where a library (ex, elm-markdown) will provide a 
default config, to be extended by the user.

import Slides

myCustomSlidesConfig =
 { Slides.defaultConfig | someAttribute = myCustomvalue }

The above does not work because the left side of the { record | attribute = 
value, ...} syntax does not accept expressions.
The current workarounds are either:

import Slides

slidesDefaultConfig =
  Slides.defaultConfig

myCustomSlidesConfig =
 { slidesDefaultConfig | someAttribute = myCustomvalue }

or

import Slides exposing (slidesDefaultConfig)

myCustomSlidesConfig =
 { slidesDefaultConfig | someAttribute = myCustomvalue }

Not a big deal TBH, but annoying.

2) 
Record type manipulation is limited.
It is normal for the front end to get some record from the database, 
display it, edit it or create a new one and push it back to the db.
The record types necessary for these operations are very similar but need 
to have very specific differences.
When the record comes from the db and is displayed, it has usually several 
definite values.
However when editing it, many (but not necessarily all) of those values 
could be "Maybe x" rather than "x".
If I am creating a new record in the front end, chances are that it will 
not have an "id" field.

However, the options that I have to define a record as function of another 
are very limited.
I can't remove fields but only add them, and even that is very limited.

In my current project, I need to edit a "Rule" record.
The app has already a "Rule" type, which *must* have an "id", because 
that's how the data arrives from the DB and is displayed to the user.
However, the form to edit a Rule will need a different type, because 
depending on whether I am creating a new rule or editing an existing one, 
it may or may not have an "id".
I have to duplicate every attribute of the "Rule" type but "id : String" 
into a "RuleContent" type.

3)
Then, unless I want to get crazy with updating nested record properties, I 
need to extend my form Model with RuleContent.
This is the best workaround I have found so far:

type alias RuleContentAnd a =
  {a |
attributes...
  }

type alias RuleContent = RuleContentAnd {}




type alias Model =
  RuleContentAnd
{ someUiAttributes
,  ...
}

This works, but currently it removes the ability to use "ResultContent" as 
a constructor (which is very useful when writing decoders).
If manipulating nested records was easier, this would be less of a problem 
because then the Model could just contain a "ruleContent : RuleContent" 
attribute.
As Elm is right now, nested records require me to write an updater helper 
"updateRuleContentAttributeX : TypeOfX -> Model -> Model" for every 
attribute in "RuleContent", leading to even more duplication.


I might be wrong, but I think that points 2) and 3) describe use cases 
(Display / Edit / Create something from/on a DB) that are probably the most 
common in web applications.
If this is the case, it might be worth to consider not only how to better 
manipulate record instances, but also record types.

-- 
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] Under what conditions will a node in the DOM be deleted and replaced?

2017-03-01 Thread 'Rupert Smith' via Elm Discuss
On Wednesday, March 1, 2017 at 4:24:54 PM UTC, Witold Szczerba wrote:
>
> So, you ask for a list of mutations and then, for each mutation you repeat 
> exactly the same procedure which is not related to the mutation you are 
> currently at.
> Why are you iterating over mutations?
>

Good point. No need to iterate, its just got left in there from your code.

Using a MutationObserver to implement a ResizeObserver does not seem the 
best idea. I don't really like that I end up scanning from the top instead 
of looking at an actual mutation 'target'. But this trick of putting the 
observer at the top is needed to get around the virtual DOM issue that 
prevents the observer being placed on the actual node that I want to watch, 
so I suppose doing a scan from the top on any mutation is justified as it 
is part of this workaround.

A ResizeObserver would be better its 'target' would definitely be the thing 
being resized - not having to guess something is resized because it or one 
of its children was mutated. I think ResizeObserver is not so well 
supported though, which is why I stuck with MutationObserver. I called the 
Elm module I wrote around it ResizeObserver, with a view to rewriting it 
with a ResizeObserver at some future time when ResizeObserver is widely 
supported.
 

>
> Regards,
> Witold Szczerba
>
> On Wed, Mar 1, 2017 at 4:59 PM, 'Rupert Smith' via Elm Discuss <
> elm-d...@googlegroups.com > wrote:
>
>> On Tuesday, February 28, 2017 at 10:54:56 PM UTC, Witold Szczerba wrote:
>>>
>>> I have used MutationObserver, so in Elm all I have to do is to add a 
>>> specific class and custom event handler, so there is no need to track it by 
>>> "id". The mutation observer is attached at the top node of the Elm app. 
>>> This works OK so far.
>>>
>>
>> When looking for nodes that have may have been resized, I found it 
>> helpful just to scan from the top of the document for the 'watch-resize' 
>> class. This is because the mutation may occur nested within some div that I 
>> am interested in. The div is not in 'addedNodes' on the mutation, and it 
>> isn't always the 'target' either, sometimes its the parent of the target, 
>> sometimes the parent.parent and so on.
>>
>> const topElement = document.getElementById("jtrial");
>>
>> const observer = new MutationObserver(mutations => {
>>   mutations.forEach(mutation => {
>> $(topElement).find('.watch-resize').each(function () {
>>   console.log("found node with .watch-resize class.");
>>   console.log($(this));
>>
>>   var result = {
>>   id: $(this).context.id,
>>   height: $(this).context.clientHeight,
>>   width: $(this).context.clientWidth
>>   };
>>
>>   app.ports.mutation.send(result);
>> });
>>   });
>> }); 
>>
>> -- 
>> 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] Decoding JSON to Union types.

2017-03-01 Thread Dan Willis
Thanks so much, Peter & Brian,

I had earlier found your article re: dates, but revisiting it now has 
helped!
Yep, I like the idea of keeping that function as agnostic as possible, 
i.e., out of a Decoder.

Thanks again for your help, I really appreciate it.




On Thursday, 2 March 2017 03:40:12 UTC+13, Brian Hicks wrote:
>
> Seconding what Peter said! I think the approach you've got here (String -> 
> OrderStatus) is good. If you don't specialize it to a decoder you can do a 
> lot more with it (testing, other serialization methods.) Composing those 
> functions together is the way to go.
>
> I've also written about this, but in the context of dates: 
> https://www.brianthicks.com/post/2017/01/13/create-custom-json-decoders-in-elm-018/
>

-- 
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] Under what conditions will a node in the DOM be deleted and replaced?

2017-03-01 Thread Witold Szczerba
So, you ask for a list of mutations and then, for each mutation you repeat
exactly the same procedure which is not related to the mutation you are
currently at.
Why are you iterating over mutations?

Regards,
Witold Szczerba

On Wed, Mar 1, 2017 at 4:59 PM, 'Rupert Smith' via Elm Discuss <
elm-discuss@googlegroups.com> wrote:

> On Tuesday, February 28, 2017 at 10:54:56 PM UTC, Witold Szczerba wrote:
>>
>> I have used MutationObserver, so in Elm all I have to do is to add a
>> specific class and custom event handler, so there is no need to track it by
>> "id". The mutation observer is attached at the top node of the Elm app.
>> This works OK so far.
>>
>
> When looking for nodes that have may have been resized, I found it helpful
> just to scan from the top of the document for the 'watch-resize' class.
> This is because the mutation may occur nested within some div that I am
> interested in. The div is not in 'addedNodes' on the mutation, and it isn't
> always the 'target' either, sometimes its the parent of the target,
> sometimes the parent.parent and so on.
>
> const topElement = document.getElementById("jtrial");
>
> const observer = new MutationObserver(mutations => {
>   mutations.forEach(mutation => {
> $(topElement).find('.watch-resize').each(function () {
>   console.log("found node with .watch-resize class.");
>   console.log($(this));
>
>   var result = {
>   id: $(this).context.id,
>   height: $(this).context.clientHeight,
>   width: $(this).context.clientWidth
>   };
>
>   app.ports.mutation.send(result);
> });
>   });
> });
>
> --
> 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: Elm package manager behind a proxy

2017-03-01 Thread Abhinav Gogna
Roovo,

Sorry for the late response. I have verified github connection for other 
repositories. I can git clone. I can even do wget on the 
http://github.com/elm-lang/core/zipball/5.1.1/ but I can't get it to work 
with elm-repl.

After some rudimentary research, I found out that elm uses http-client. I 
cabal updated that library but still can't connect. I get the same error 
message as mentioned in the previous post. 


On Friday, February 24, 2017 at 3:22:32 AM UTC-5, roovo wrote:
>
> what are you typing to get that error - I'm currently behind a corporate 
> proxy and can run elm repl fine.  It even runs if I unset the proxy env 
> variables in the terminal session.  Is it that it isn't installed properly? 
>  It looks like your proxy doesn't let you access github via https?? 
> although why elm repl would try and do this when you start it up I don't 
> know...
>
> My set-up is on a mac - and I'm using the asdf package manager to install 
> elm
>
> On Thursday, February 23, 2017 at 1:09:54 PM UTC, Abhinav Gogna wrote:
>>
>> Can anyone help me out? I am willing to make it work (almost) whatever it 
>> takes.
>>
>> On Wednesday, February 22, 2017 at 6:15:11 PM UTC-5, Abhinav Gogna wrote:
>>>
>>> I can't get elm-repl to work behind proxy. I have set http_proxy and 
>>> https_proxy but to no avail.
>>>
>>> I would like to learn elm and use it at work but without proxy support, 
>>> I can go forward. Would really appreciate, if someone, can help get this 
>>> working behind proxy. 
>>>
>>> Currently, the error I am getting is 
>>>
>>> Error: The following HTTP request failed.
>>> 
>>>
>>> ProxyConnectException "github.com" 443 (Right (StatusCodeException (
>>> Status {statusCode = 403, statusMessage = "Forbidden"}) [] (CJ {expose = 
>>> []})))
>>>
>>>
>>>
>>> On Saturday, January 16, 2016 at 1:09:15 AM UTC-5, Alex Neslusan wrote:

 Yes. It works for me at work behind my authenticated corporate proxy. I 
 don't remember having to do anything to get it working, it just worked 
 when 
 I set it as a system proxy.
 On Saturday, January 16, 2016 at 12:50:19 AM UTC+8, Ronn Ross wrote:
>
> Has anyone used Elm's package manager from behind a proxy? Any advice 
> to get it working? 
>


-- 
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] Decoding JSON to Union types.

2017-03-01 Thread Brian Hicks
Seconding what Peter said! I think the approach you've got here (String -> 
OrderStatus) is good. If you don't specialize it to a decoder you can do a 
lot more with it (testing, other serialization methods.) Composing those 
functions together is the way to go.

I've also written about this, but in the context of 
dates: 
https://www.brianthicks.com/post/2017/01/13/create-custom-json-decoders-in-elm-018/

-- 
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] Under what conditions will a node in the DOM be deleted and replaced?

2017-03-01 Thread 'Rupert Smith' via Elm Discuss
On Wednesday, March 1, 2017 at 11:19:02 AM UTC, Rupert Smith wrote:
>
> On Tuesday, February 28, 2017 at 10:54:56 PM UTC, Witold Szczerba wrote:
>>
>> Hi,
>> few days ago I was trying to embed a date picker in my Elm app. I have 
>> used MutationObserver, so in Elm all I have to do is to add a specific 
>> class and custom event handler, so there is no need to track it by "id". 
>> The mutation observer is attached at the top node of the Elm app. This 
>> works OK so far.
>>
>
> I think I can still find the nodes by id, instead of class. The reason id 
> was not working for me, is that I was finding the id, then attaching a 
> mutation observer to that node. The node would then be replaced by a new 
> one with the same id, but it is not the same node, so the mutation observer 
> is not watching it.
>
> The way you are doing it is to watch for mutations at the top-level, then 
> find a particular class. I should be able to do the same; watch for 
> mutations at the top-level, then find a particular id. 
>

I think I will use a class though. Then I can watch for resize events on a 
particular class and report the event and the id together. Inspired by your 
use of custom events, I can then achieve all of this without using any 
ports and subscriptions - very nice idea, 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] Under what conditions will a node in the DOM be deleted and replaced?

2017-03-01 Thread 'Rupert Smith' via Elm Discuss
On Tuesday, February 28, 2017 at 10:54:56 PM UTC, Witold Szczerba wrote:
>
> Hi,
> few days ago I was trying to embed a date picker in my Elm app. I have 
> used MutationObserver, so in Elm all I have to do is to add a specific 
> class and custom event handler, so there is no need to track it by "id". 
> The mutation observer is attached at the top node of the Elm app. This 
> works OK so far.
>

I think I can still find the nodes by id, instead of class. The reason id 
was not working for me, is that I was finding the id, then attaching a 
mutation observer to that node. The node would then be replaced by a new 
one with the same id, but it is not the same node, so the mutation observer 
is not watching it.

The way you are doing it is to watch for mutations at the top-level, then 
find a particular class. I should be able to do the same; watch for 
mutations at the top-level, then find a particular id. 

-- 
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] Under what conditions will a node in the DOM be deleted and replaced?

2017-03-01 Thread 'Rupert Smith' via Elm Discuss
On Tuesday, February 28, 2017 at 10:54:56 PM UTC, Witold Szczerba wrote:
>
> Hi,
> few days ago I was trying to embed a date picker in my Elm app. I have 
> used MutationObserver, so in Elm all I have to do is to add a specific 
> class and custom event handler, so there is no need to track it by "id". 
> The mutation observer is attached at the top node of the Elm app. This 
> works OK so far.
>
> I have described it here: 
> https://www.reddit.com/r/elm/comments/5uqa13/those_fancy_date_pickers_in_elm_watch_this_no/
> There is also a demo app.
>

Very good. This will be a big help, thanks. I think you are taking a better 
approach by attaching the mutation observer at the top, as this seems 
likely to be much more stable and not subject to breaking or working 
depending on the particulars of the diffing algorithm.
 

> I was wandering if I could use exactly same approach to embed a rich text 
> editor. I wanted to check it out and publish my results, but did not have 
> time to do it yet. What kind of editor are you using? What exactly is your 
> "content" value, "Overlay.editedValue" and "markdownView" functions 
> doing? 
>

markdownView is just rendering my content with evancz/elm-markdown:

markdownView contentModel =
Markdown.toHtml
[ domMetricsOn (MouseOverContent contentModel) "mouseover"
]
<|
asMarkdown contentModel


Overlay.editedValue gets the updated value for the content if it is being 
edited.

I have an 'overlay' which sits on top of the page, and lets me edit content 
as markdown. I have an 'inline' editor which intercepts the rendering of a 
piece of content and replaces it with a wysiwyg editor. I have not yet 
implemented or chosen a wysiwyg editor, its just a place-holder for now, 
and I will edit my content as markdown to begin with.

I am sharing a lot of code between client and server side. The type of the 
Editor is:

type alias Editor msg =
Model.ContentModel -> Html msg

That is, it just renders some content to Html. In the server side 
implementation, it just renders the content. In the client side 
implementation, it renders the content or injects an editor into the html 
when the content is selected for editing. I replaced all the rendering 
templates which were written in handlebars, with server side Elm. This 
means I can now produce new rendering templates in Elm, and automatically 
be able to inject an editing facility into them, regardless of what the 
template looks like. That's the idea anyway :-).

-- 
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: Under what conditions will a node in the DOM be deleted and replaced?

2017-03-01 Thread 'Rupert Smith' via Elm Discuss
On Tuesday, February 28, 2017 at 6:40:36 PM UTC, Richard Haven wrote:
>
> My understanding is that the Elm should create the entire DOM every time, 
> and the runtime will do the diff and change the parts that need changing.
>

Yes, this is my understanding too. The virtual DOM is built each time the 
'view' function is evaluated, then some internal code in the runtime diffs 
this with the page and tries to update the page as efficiently as it can. 
What I am trying to figure out is when will a diff actually be detected and 
applied? 

The content inside my div is changing, does that also cause the parent div 
to be completely replaced? Weirdly it was working before with the same 
structure, but not now, so the conditions under which it happens are not 
very clear.

Perhaps even if they are clear, it is not a good idea to rely on knowing 
them; the diffing algorithm may change.

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