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

2017-07-20 Thread Alex Barry
Here's my take.

In C++ (Or Java, what-have-you), you could have something like this:

class Square {
  private float size;

  Square(float size) {
this.size = size;
  }

  void size(float size) {
this.size = size;
  }

  float size(void) {
return this.size;
  }

  float perimeter(void) {
return this.size * 4;
  }

  float area(void) {
return this.size * this.size;
  }
}


In Elm, you end up with a much different looking structure and code:

module Square exposing (Square, perimeter, area)


type alias Square = { size : Float } 


perimeter : Square -> Float
perimeter square = square.size * 4

area : Square -> Float
area square = square.size * square.size 

 



It forces immutability. In an object oriented language, what would the 
point be of having immutable data?  Why would `Square(oldSquare, newSize)` 
ever be better than `oldSquare.size(newSize)`?  You end up working against 
the language. It's not that OOP is bad, but it encourages mutation, a thing 
that Elm is strictly against.

Mutation can be a problem because it means there is more to debug. In C++, 
if I had something like:

foo.bar = "baz";
foo.someSpecialFunction();
std::cout << foo.bar << std::endl;


What is the expected value of foo.bar? When we initially evaluate the code, 
we make an educated assumption that foo.bar is probably going to be "baz", 
but is that actually the case? We need knowledge about what 
someSpecialFunction does, because we know it could, in a non obvious way, 
change the value of bar.

In Elm:

type alias Thing = { bar : String }

someSpecialFunction : Thing -> a

foo = Thing "baz"
_ = someSpecialFunction foo
valueOfFooBar = Debug.log "value of foo.bar" foo.bar


This example is intentionally leaving out some parts, but we will always 
know that foo.bar  results in "baz". If someSpecialFunction where to return 
a Thing, we could assume it is a copy of the original with some changes. In 
this case, it's obvious that something about that result will be different 
from foo, and we can deal with it appropriately.

Testing probably ends up being harder in C++ since you aren't just testing 
results, you need to test mutations, so `this` may cause misdirection. It 
tethers operations on your class to that instance. It means things can 
change without you necessarily knowing they have changed.

In Elm, it is hard to do this. Not impossible, but hard. The idea is that 
the less work a developer has to do to understand a piece of code, the more 
productive (s)he can be.

I think the statement does boil down to a point about immutability and 
guarantees provided by all constant variables. I'm not convinced that it is 
a systemic problem, but it is just another layer of knowledge that a 
developer must have every time (s)he runs an instance method on a variable. 
There are always a set of rules that a developer can follow to minimize the 
impact `this` and mutations has on his/her code, like a function can only 
perform one thing, having well defined names for functions, following a 
code guide for a project, etc..

In a broad and maybe stretched sense, perhaps the author is suggesting that 
rather than developers having to opt into rules to keep good and tidy code, 
perhaps it is better that those rules are strictly enforced outside of the 
developers control, under the assumption that the forced rules will always 
result in better code.

- Alex


On Thursday, 20 July 2017 03:55:54 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.


[elm-discuss] Re: Decoding json from incoming websocket packets

2017-07-10 Thread Alex Barry
If you control the sender and are guaranteed to get some messages exceeding 
the websocket limit (which I'm assuming is 4500 bytes) is to either send 
multiple smaller updates, or assign some sort of message id and prepend it 
to each chunk.

Another option you can do (if you can't control the sender) is have a 
string buffer, and each time you get data, if it can't be decoded, append 
it to the buffer. After every append, attempt a decode, and if it's 
successful, clear the buffer. This will probably break if you get multiple 
unrelated messages.

One thing you should keep in mind is websockets on their own aren't really 
for messages, it's for streaming data. If you can guarantee synchronous 
messages (ie first message must always complete before the second message 
starts), you could send a byte length + json (ie "14{ foo: 'bar' }", and do 
the buffer method I suggested.

So if you have big messages, your best bet is to chunk them yourself so 
you're guaranteeing the size. Otherwise, hope they are synchronous and 
assemble them in elm.

On Monday, 10 July 2017 09:12:31 UTC-4, _Boris _ wrote:
>
> Hello,
>
> I have implemented very straightforward converting received packet into 
> Msg:
>
> subscriptions : Model -> Sub Msg
> subscriptions model =
>   Sub.batch
> [ WebSocket.listen wsServer decoderServerMsg
>  
> where decoderServerMsg:
> decoderServerMsg :  String -> Msg
> decoderServerMsg rcvdStr = case JD.decodeString  jsonDecServerMsg rcvdStr 
> of
>   Ok serverMsg   ->  ServerMsgReceived serverMsg
>   Err err->  SystemError ("Failed to parser server msg:"++err++" 
> string:"++rcvdStr)
>
>
> It works well as long as there is no fragmentation, ie. every packet 
> contains valid json payload.
> My problem starts when packet exceeds about 4500 bytes and then it is 
> broken  into two chunks.
> I believe it very common case so before reinventing the wheel I wanted to 
> ask if there is already solution for this problem that I can use?
>
>
> Thanks,
> Boris
>
>

-- 
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 there an Elm window.print()?

2017-07-08 Thread Alex Barry
Also to expand on why I used an empty tuple - Elm, from my understanding, 
will cache the call if it just returns a Bool, because it ends up looking 
like a constant. I don't know if, as a result, Elm will actually execute 
the function a second time, or if it will just return the boolean value 
from the first run of the call. The empty tuple forces elm to see this as a 
function rather than a constant, but it's a hack, and not a good practice.

On Saturday, 8 July 2017 13:26:05 UTC-4, Marek Fajkus wrote:
>
> I agree with Alex in all his points - ports are a better way to achieve 
> this. Btw () (0-tuple) is unit type (
> https://en.wikipedia.org/wiki/Unit_type). *I'm saying that only so there 
> is any additional value in my comment other than +1 for Alex*
>

-- 
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 there an Elm window.print()?

2017-07-08 Thread Alex Barry
Is there a good reason *not* to use a port for this? The difficultly level 
is very low, and t's a single js function call.

Also, don't even consider a native module at all. The general consensus is 
that native code isn't meant for the general Elm population, because it has 
the ability to absolutely break all guarantees that Elm initially promises.

One main issue here is that Elm, being a functional language, needs a value 
returned after a function call. Sure, you could have something like `print 
: () -> Bool`, but that's not quite correct because you are adding extra 
meaningless data (ie passing a tuple and returning a bool, both unrelated 
to print). As a result, it's much better suited to be a Task (port 
function), since tasks don't return values, and there is no logical thing 
to return.

>From personal experience, don't even consider native modules unless:

   1. Elm does not have the ability to support the feature you want.
   2. Sending a message to run a task makes performing the function awkward.

99% of the time for printing the screen, it's because the user is clicking 
a button on the page, and that's a super simple update from Elm.

On Friday, 7 July 2017 03:39:40 UTC-4, Casper Bollen wrote:
>
> Is there an Elm way to implement window.print() without using a javascript 
> port?
>

-- 
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: Divide by zero?

2017-02-18 Thread Alex Barry
But that if statement would only go around something doing integer
division, where the divisor could be zero. What you're suggesting would be
required for at least all integer division, and potentially a pattern for
other integer operations. That's a huge impact.

On Feb 18, 2017 7:06 PM, "'Rupert Smith' via Elm Discuss" <
elm-discuss@googlegroups.com> wrote:

On Saturday, February 18, 2017 at 11:23:01 PM UTC, Alex Barry wrote:
>
> I think for integer division, it has to return 0 because infinity is
> expressed as a float. I'm going to agree with Erkal, though, you definitely
> don't want to wrap all your math statements in a maybe or result type, that
> would make most code considerably more verbose.
>

But to use it safely you have to wrap it in a check for zero anyway

if divisor == 0 then
  ...
else
  val // divisor

Which is equally complex as:

case (a // b) of
  Integer val -> val
  DivideByZero -> ...


-- 
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: Divide by zero?

2017-02-18 Thread Alex Barry
I think for integer division, it has to return 0 because infinity is
expressed as a float. I'm going to agree with Erkal, though, you definitely
don't want to wrap all your math statements in a maybe or result type, that
would make most code considerably more verbose.

On Sat, Feb 18, 2017 at 5:38 PM, 'Rupert Smith' via Elm Discuss <
elm-discuss@googlegroups.com> wrote:

> On Saturday, February 18, 2017 at 9:53:49 PM UTC, Erkal Selman wrote:
>>
>> Why didn't you try it?
>> Try it!
>> Yes, it returns Infinity.
>> Would you that error handling for every other operation, like for example
>> the squareroot of negative numbers, or the logarithm of zero? I don't think
>> that this is a good idea for a language like elm.
>>
>
> With elm-repl:
>
> > type alias T = { val : Int }
> > t = T 4
> { val = 4 } : Repl.T
> > x = t.val / 0
> -- TYPE MISMATCH -
> repl-temp-000.elm
>
> The left argument of (/) is causing a type mismatch.
>
> 8| t.val / 0
>^
> (/) is expecting the left argument to be a:
>
> Float
>
> But the left argument is:
>
> Int
>
> Hint: Elm does not automatically convert between Ints and Floats. Use
> `toFloat`
> and `round` to do specific conversions.
> 
>
> Hint: The (/) operator is specifically for floating point division, and
> (//) is
> for integer division. You may need to do some conversions between ints and
> floats to get both arguments matching the division operator you want.
>
>
> > x = t.val // 0
> 0 : Int
> >
>
> So for integer division by zero, it simply returns zero!
>
> --
> 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] How do you discard an Html message?

2017-01-27 Thread Alex Barry
Type Msg
  = ...
  | NoOp msg

update msg model =
  case msg of
NoOp _ -> ( model, Cmd.none )

That should do the trick for you. You might want a better message name.
Also, why discard the message?


On Fri, Jan 27, 2017 at 10:45 AM, 'Rupert Smith' via Elm Discuss <
elm-discuss@googlegroups.com> wrote:

> Having a dozy moment again...
>
> If I have some view that returns an Html MyFunkyStuff.Msg but I want to
> Html.map that to the local Html Msg, is there a way I can discard the
> message being mapped? There isn't an Html.none like there is Cmd.none or
> Sub.none.
>
> Perhaps there isn't a way of doing this, and I need to code my own Noop
> message? I guess javascript event handlers have already been attached by
> the view function just executed, so they can't be turned off in this way?
>
> --
> 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: What do you think about Types/State/View split?

2017-01-25 Thread Alex Barry
Just to pipe in with my experience, I'm working on a medium sized project
with a lot of inter-related data between my modules, which is dictated by a
database structure. We started the project as a single file elm project,
but the code was starting to get unmanageable, so we broke it out into
modules. When that was done, we fixed the elm error reports until it worked
again. That meant that in some cases, we broke out some modules into
multiple files, and we tried to stick to generally Module.View,
Module.Update, and Module.Model. We had a few instances where we had to
break out sub-update messages (ie the union type typically used in
Module.Update) because we had messages that passed messages.

Also for methods, only pass what you need, even if it means passing and
returning more data. I eliminated a handful of circular dependencies just
by doing that.

Only break things out if there is a reason to. If there is a circular
dependency, then either see if there is a way to use anonymous types, or
break out the files. Things like update messages might be okay to use
anonymous types, as long as elm is able to infer the types properly.

On Wed, Jan 25, 2017 at 9:41 AM, 'Rupert Smith' via Elm Discuss <
elm-discuss@googlegroups.com> wrote:

> On Wednesday, January 25, 2017 at 12:11:46 PM UTC, Rupert Smith wrote:
>>
>> I think a better approach would be to put build a TEA component like this:
>>
>> module MyComponent exposing (Model, Msg, update, view, init,
>> subscriptions) -- and perhaps also OutMsg
>>
>
> So I think I understand where the tempation to put Model and Msg in
> Types.elm comes from. As the codebase grows I may end up with lots of
> functions for rendering the view, which are of the type Model -> Html Msg.
> Or it may be the update function that grows and I end up with lots of
> helper update functions of type a -> (Model, Cmd.Msg). So these functions
> cannot simply be pushed down to a sub-module as they need to import the
> type, but that is in the main module that is using them - a circular
> dependency.
>
> Just grabbing some random function from view code I was working on today:
>
> slideButton : Model -> Html Msg
> slideButton model =
> div
> [ class "slide-button"
> , Events.onClick ToggleMenu
> ]
> [ div
> (Animation.render model.slideButtonStyle
> ++ [ class "slide-button__inset" ]
> )
> []
> ]
>
> I could push this down into a child module by not passing the whole Model,
> but just the bits it needs, and by passing a 'tagger' for building the
> messages:
>
> slideButton : Animation.State -> msg -> Html msg
> slideButton slideButtonStyle clickTagger =
> div
> [ class "slide-button"
> , Events.onClick clickTagger
> ]
> [ div
> (Animation.render slideButtonStyle
> ++ [ class "slide-button__inset" ]
> )
> []
> ]
>
> Interestingly by removing the Msg and Model type from this piece of view
> logic I have also made it re-usable (with other Models and Msgs, that is,
> other components). So I think if I structure my code this way, as groups of
> related functionality emerge and files get too long, the tidying up
> activity will be to introduce re-usability into code as it it organized.
>
> So some good rules about modules with Types only might be:
>
> * A module that declares Type only cannot take responsibility for
> implementing some functionality, so modules like this should be avoided.
> * A module that declares Type only can introduce too much coupling when it
> is used as a technique to break the circular dependency of modules.
>
>
>
> --
> 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.