[elm-discuss] How are people deploying their Elm applications?

2016-12-26 Thread Anthony Naddeo
I've been beating my head against a wall trying to integrate Elm into my 
companies build system. Whether its getting haskell running at all, getting 
the right version of glibc to execute the elm binaries or hacking the 
elm-stuff folder to fake private repos, I'm hitting walls at every turn. To 
make matters worse, I don't have a lot of control over the build systems. 
They run a pretty old version of something like Red Hat.

If anyone is using Elm in production can you talk a bit about your 
automated deployment and testing process around it? I have a lot of 
restrictions that I'm trying to work around at the moment.

-- 
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 "faster than JavaScript" (version 0.18) - NOT - Parts I and II...

2016-12-26 Thread GordonBGood


On Tuesday, 27 December 2016 05:37:43 UTC+7, Robin Heggelund Hansen wrote:
>
> Part I: Evan is already aware of this issue, you can see the full 
> discussion in this github issue: 
> https://github.com/elm-lang/elm-compiler/issues/1528
> The short of it is that the code generator part of the compiler is not 
> aware of type information, and adding this would be a serious undertaking. 
> It will probably come at some point, as there are interesting optimizations 
> that can be made, like the one mentioned
>

Although it is good to see that Even is aware of the issue, it is 
discouraging to learn that the type information is not retained by the code 
generator and therefore this improvement is part of a "huge project"; thus 
the linked issue has been closed.  The person who raised the original issue 
developed some timing results that showed only about a 20% speed 
improvement for the particular code use.  However, when I compare the above 
tight loop written directly in JavaScript, the difference here is about 
700%!  Of course, real use cases won't be quite this large, but I could see 
a fairly tight loop being 300% (+/- 100%) faster.
 

>
> Part II: Bitwise operators are inlined in 0.18, which gave a noticable 
> performance boost in libraries like Skinney/elm-array-exploration and 
> mgold/random-pcg. Having it available as a function (just like +, -, * 
> etc.) allows more flexibility like currying.
>

 I checked and you are right that these functions are now inlined.

The only other thing they should also have is infix for those with two 
operands for better (conventional) clarity of code, but this is no biggy.

It turns out that the huge slowdown as compared to equivalent JavaScript 
code is another instance of the Part I problem as it is caused by a *call 
to `Native_Utils.eq` which is even less efficient than `Native_Utils.**cmp`* 
resulting in about a 1500% slowdown compared to JavaScript for the 
following code:

import Bitwise as Bw

testProg : Int -> Int
testProg n = -- do some work
  let loop i =
if Bw.and i 0x3FFF == 0x3FFF then i else
loop (i + 1) in loop n

which compiles to:

var _user$project$Temp1482804013226255$testProg = function (n) {
var loop = function (i) {
loop:
while (true) {
if (_elm_lang$core$Native_Utils.eq(i & 1073741823, 1073741823)) {
return i;
} else {
var _v0 = i + 1;
i = _v0;
continue loop;
}
}
};
return loop(n);
};

with  `Native_Utils.eq` defined as:

function eq(x, y)
{
var stack = [];
var isEqual = eqHelp(x, y, 0, stack);
var pair;
while (isEqual && (pair = stack.pop()))
{
isEqual = eqHelp(pair.x, pair.y, 0, stack);
}
return isEqual;
}


function eqHelp(x, y, depth, stack)
{
if (depth > 100)
{
stack.push({ x: x, y: y });
return true;
}

if (x === y)
{
return true;
}
...

For this use case, there are a succession of conditions which won't cost 
that much as explained in the opening post, but it is twice as slow as the 
example in Part I because *there are typically two nested calls of the 
functions `Native_Utils.eq` with `Native_Utils.eqHelp` called from within 
it!*  This is the reason it is twice as slow as the example in Part I.

If and when the issue as of Part I is fixed, then bitwise operations will 
be fixed too.

Meanwhile, for real work programs with intensive bitwise tight loop 
computations, Elm is likely up to about 10 times slower than JavaScript and 
for general numeric tight loop calculations about 5 times slower, which I 
find unacceptable.

-- 
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 "faster than JavaScript" (version 0.18) - NOT - Parts I and II...

2016-12-26 Thread Robin Heggelund Hansen
Part I: Evan is already aware of this issue, you can see the full 
discussion in this github 
issue: https://github.com/elm-lang/elm-compiler/issues/1528
The short of it is that the code generator part of the compiler is not 
aware of type information, and adding this would be a serious undertaking. 
It will probably come at some point, as there are interesting optimizations 
that can be made, like the one mentioned.

Part II: Bitwise operators are inlined in 0.18, which gave a noticable 
performance boost in libraries like Skinney/elm-array-exploration and 
mgold/random-pcg. Having it available as a function (just like +, -, * 
etc.) allows more flexibility like currying.

mandag 26. desember 2016 18.44.49 UTC+1 skrev GordonBGood følgende:
>
> *Synopsis:*  Some, including  Evan, maintain that Elm can be "faster than 
> JavaScipt".  While that may be true for some use cases including use of 
> perhaps more efficient UI updates due to compartmentalized use of 
> VirtualDOM, the actaul Javascript code generated by the compiler  is not 
> very efficient for many/most tight code cases.  The reason is often 
> unnecessary nested function calls that could easily be eliminated by making 
> full use of the type information that the Elm compiler has.
>
> Part I
>
> *An example;*  The following tight loop doesn't really do anything, so 
> should therefore compile into the very tightest of code (and I'm not 
> expecting the Elm compiler to recognize that the result is actually known 
> at compile time):
>
> range : Int
> range = 10
>
> testProg : Int -> Int
> testProg n = -- do some work
>   let lmt = min (n + 1) range in
>   let loop i =
> if i >= lmt then i else
> loop (i + 1) in loop n
>
> which compiles to the following JavaScript:
>
> var _user$project$Temp1482759649866537$range = 10;
> var _user$project$Temp1482759649866537$testProg = function (n) {
> var lmt = A2(_elm_lang$core$Basics$min, n + 100, 
> _user$project$Temp1482759649866537$range);
> var loop = function (i) {
> loop:
> while (true) {
> if (_elm_lang$core$Native_Utils.cmp(i, lmt) > -1) {
> return i;
> } else {
> var _v0 = i + 1;
> i = _v0;
> continue loop;
> }
> }
> };
> return loop(n);
> };
> All right, the code looks fairly good, and we can see that for the inner 
> `loop` function that the compiler used its new capability to do tail call 
> optimization and turn it into a while loop.  Also, one might expect that 
> any decent JIT compiler such as Chrome V8 will use constant folding and get 
> rigd of the `_v0 variable.  However, the real limitation of this loop is 
> the call to the `Native_Utils.cmp` function.  Function calls are expensive 
> at 10's of CPU clock cycles each!
>
> The pertinent JavaScript for `Native_Utils.cmp` is as follows:
>
> var LT = -1, EQ = 0, GT = 1;
>
> function cmp(x, y)
> {
> if (typeof x !== 'object')
> {
> return x === y ? EQ : x < y ? LT : GT;
> }
> ...
>
> Note that there are three native branches here (in addition to the 
> enclosing one):  one for the check to see it the arguments are objects 
> (which of course they are not in the case of Int's as here or Float's as 
> the compiler well knows), one to check if they are equal. and (given that 
> generally they won't be equal most of the time) one to see which is 
> greater.  Now these conditions are not so bad by themselves as they are 
> very predictable for modern CPU's branch prediction (i is almost always < 
> lmt), so that will cost at most a few CPU cycles; However, the call to the 
> function in the first place will cost 10's of CPU clock cycles!
>
> Given that the compiler already knows and strictly enforces that the 
> arguments are both Int's or Float's (which are both just Numbers in 
> JavaScript), there is no reason that it cannot directly output (i >= lmt) 
> instead of the function call and make the whole inner loop take only a few 
> CPU clock cycles (on a JavaScript engine such as Chrome V8).  If the 
> compiler were consistent in applying this specialization rule, there would 
> be no need for the `Native_Utils.cmp` function to do the check if the 
> arguments are objects, but for safety's sake and considering that one extra 
> check in the case of objects is likely negligible compare to the object 
> processing, it may as well be left in for its true best use case of 
> comparing objects of the various kinds.
>
> *The Elm Compiler only deals with two primitive types:  Int and Float 
> (which are both actual Number/Float to JavaScript), which makes direct use 
> of primitive operands very easy*
>
> *Part II*
>
> In a similar way, the definition of the Bitwise library to emulate 
> Haskell's definition of the Data.Bits library was silly for only five Int 
> functions, made even worse by a name collision with the Bool `xor` 
> operator.  Because these are library functions, there is at least one level 
> of function call for every use.
>
> *Just as for the above function call for known primitive types (in th

[elm-discuss] Re: JSON Decoder for list of objects

2016-12-26 Thread Sekib Omazic
Got it like this:

decodeNotes : Decoder (List DailyNotes)
decodeNotes =
list (field "day_entry" decodeDailyNotes)


decodeDailyNotes : Decoder DailyNotes
decodeDailyNotes =
map2 DailyNotes 
  (field "id" int) 
  (maybe (field "notes" string))

Didn't use type alias Notes at all and also added "maybe" to the "notes" 
field.

Hopefully it helps somebody.


Am Montag, 26. Dezember 2016 21:31:45 UTC+1 schrieb Sekib Omazic:
>
> Hi all,
>
> I got stuck trying to decode a list of JSON objects I get from server:
>
> -- JSON response from server
>
> [
>   {"day_entry": {"id":1234,"notes":"Map Json "} },
>   {"day_entry": {"id":5678,"notes":"Learn Elm"} }
> ]
>
> -- types
>
> type alias Notes =
> { dailyNotes : List DailyNotes
> }
>
>
> type alias DailyNotes =
> { id : Int
> , notes : String
> }
>
>
> -- my decoders 
>
> decodeNotes : Decoder Notes
> decodeNotes =
> map Notes (field "day_entry" (list decodeDailyNotes))
>
>
> decodeDailyNotes : Decoder DailyNotes
> decodeDailyNotes =
> map2 DailyNotes (field "id" int) (field "notes" string)
>
>
> It fails with Err BadPayload. 
>
> Any help is appreciated.
>
> Thanks!
>

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


[elm-discuss] Re: JSON Decoder for list of objects

2016-12-26 Thread Sekib Omazic
Actually I don't need:

type alias Notes =
{ dailyNotes : List DailyNotes
}


Am Montag, 26. Dezember 2016 21:31:45 UTC+1 schrieb Sekib Omazic:
>
> Hi all,
>
> I got stuck trying to decode a list of JSON objects I get from server:
>
> -- JSON response from server
>
> [
>   {"day_entry": {"id":1234,"notes":"Map Json "} },
>   {"day_entry": {"id":5678,"notes":"Learn Elm"} }
> ]
>
> -- types
>
> type alias Notes =
> { dailyNotes : List DailyNotes
> }
>
>
> type alias DailyNotes =
> { id : Int
> , notes : String
> }
>
>
> -- my decoders 
>
> decodeNotes : Decoder Notes
> decodeNotes =
> map Notes (field "day_entry" (list decodeDailyNotes))
>
>
> decodeDailyNotes : Decoder DailyNotes
> decodeDailyNotes =
> map2 DailyNotes (field "id" int) (field "notes" string)
>
>
> It fails with Err BadPayload. 
>
> Any help is appreciated.
>
> Thanks!
>

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


[elm-discuss] JSON Decoder for list of objects

2016-12-26 Thread Sekib Omazic
Hi all,

I got stuck trying to decode a list of JSON objects I get from server:

-- JSON response from server

[
  {"day_entry": {"id":1234,"notes":"Map Json "} },
  {"day_entry": {"id":5678,"notes":"Learn Elm"} }
]

-- types

type alias Notes =
{ dailyNotes : List DailyNotes
}


type alias DailyNotes =
{ id : Int
, notes : String
}


-- my decoders 

decodeNotes : Decoder Notes
decodeNotes =
map Notes (field "day_entry" (list decodeDailyNotes))


decodeDailyNotes : Decoder DailyNotes
decodeDailyNotes =
map2 DailyNotes (field "id" int) (field "notes" string)


It fails with Err BadPayload. 

Any help is appreciated.

Thanks!

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


[elm-discuss] Elm "faster than JavaScript" (version 0.18) - NOT - Parts I and II...

2016-12-26 Thread GordonBGood
*Synopsis:*  Some, including  Evan, maintain that Elm can be "faster than 
JavaScipt".  While that may be true for some use cases including use of 
perhaps more efficient UI updates due to compartmentalized use of 
VirtualDOM, the actaul Javascript code generated by the compiler  is not 
very efficient for many/most tight code cases.  The reason is often 
unnecessary nested function calls that could easily be eliminated by making 
full use of the type information that the Elm compiler has.

Part I

*An example;*  The following tight loop doesn't really do anything, so 
should therefore compile into the very tightest of code (and I'm not 
expecting the Elm compiler to recognize that the result is actually known 
at compile time):

range : Int
range = 10

testProg : Int -> Int
testProg n = -- do some work
  let lmt = min (n + 1) range in
  let loop i =
if i >= lmt then i else
loop (i + 1) in loop n

which compiles to the following JavaScript:

var _user$project$Temp1482759649866537$range = 10;
var _user$project$Temp1482759649866537$testProg = function (n) {
var lmt = A2(_elm_lang$core$Basics$min, n + 100, 
_user$project$Temp1482759649866537$range);
var loop = function (i) {
loop:
while (true) {
if (_elm_lang$core$Native_Utils.cmp(i, lmt) > -1) {
return i;
} else {
var _v0 = i + 1;
i = _v0;
continue loop;
}
}
};
return loop(n);
};
All right, the code looks fairly good, and we can see that for the inner 
`loop` function that the compiler used its new capability to do tail call 
optimization and turn it into a while loop.  Also, one might expect that 
any decent JIT compiler such as Chrome V8 will use constant folding and get 
rigd of the `_v0 variable.  However, the real limitation of this loop is 
the call to the `Native_Utils.cmp` function.  Function calls are expensive 
at 10's of CPU clock cycles each!

The pertinent JavaScript for `Native_Utils.cmp` is as follows:

var LT = -1, EQ = 0, GT = 1;

function cmp(x, y)
{
if (typeof x !== 'object')
{
return x === y ? EQ : x < y ? LT : GT;
}
...

Note that there are three native branches here (in addition to the 
enclosing one):  one for the check to see it the arguments are objects 
(which of course they are not in the case of Int's as here or Float's as 
the compiler well knows), one to check if they are equal. and (given that 
generally they won't be equal most of the time) one to see which is 
greater.  Now these conditions are not so bad by themselves as they are 
very predictable for modern CPU's branch prediction (i is almost always < 
lmt), so that will cost at most a few CPU cycles; However, the call to the 
function in the first place will cost 10's of CPU clock cycles!

Given that the compiler already knows and strictly enforces that the 
arguments are both Int's or Float's (which are both just Numbers in 
JavaScript), there is no reason that it cannot directly output (i >= lmt) 
instead of the function call and make the whole inner loop take only a few 
CPU clock cycles (on a JavaScript engine such as Chrome V8).  If the 
compiler were consistent in applying this specialization rule, there would 
be no need for the `Native_Utils.cmp` function to do the check if the 
arguments are objects, but for safety's sake and considering that one extra 
check in the case of objects is likely negligible compare to the object 
processing, it may as well be left in for its true best use case of 
comparing objects of the various kinds.

*The Elm Compiler only deals with two primitive types:  Int and Float 
(which are both actual Number/Float to JavaScript), which makes direct use 
of primitive operands very easy*

*Part II*

In a similar way, the definition of the Bitwise library to emulate 
Haskell's definition of the Data.Bits library was silly for only five Int 
functions, made even worse by a name collision with the Bool `xor` 
operator.  Because these are library functions, there is at least one level 
of function call for every use.

*Just as for the above function call for known primitive types (in this 
case only for Int), these functions should be added to the Basics library 
as operators with appropriate infix levels and with the names `&&&`, `|||`, 
`^^^` , `<<<`, and `>>>` just as for F# (which Elm emulates more and more), 
with the Elm compiler directly substituting the equivalent primitive 
JavaScript operators.  The Bitwise library, which should never have 
existed, should be canned.*

Note that although this will make bitwise operators much faster than 
currently, programmers should be aware that there are many operations 
taking place under the covers that may not make these operations as 
efficient as possible alternate means:  under the covers the arguments are 
and'ed to produce 32-bit values, the operation is carried out, and then the 
result is sign extended to convert back to a Number/Float, although for a 
sequence of bitwise operations, the JavaScript engines may only do the 
conversions at the beginnin

Re: [elm-discuss] How can I iterate over the list of records to apply a function

2016-12-26 Thread Aaron VonderHaar
Hello, the answer depends a bit on what you intend to do with the Bools
after you have them...

But if, as you describe, you just want to end up with a List of Bools, then

List.map (\r -> r.age >= 21) yourRecords

But I expect you may also be interested in one of `List.filter`,
`List.all`, or `List.any`.
http://package.elm-lang.org/packages/elm-lang/core/5.0.0/List


On Mon, Dec 26, 2016 at 5:40 AM,  wrote:

> Hello,
> I am new to elm syntax. I have a list of records with name and age. I want
> to apply a test function to each record. The function takes one record as
> input and returns a boolean value. Depending on True or false, I want to
> take a specific action for each record. How can I implement this in elm? If
> it was Python, I will just iterate over each item in the list and pass it
> as a parameter to the function.
>
>
> --
> 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 can I iterate over the list of records to apply a function

2016-12-26 Thread Duane Johnson
Hi Alex,

Perhaps this helps?

$ elm repl
 elm-repl 0.17.1
---
 :help for help, :exit to exit, more at <
https://github.com/elm-lang/elm-repl>

> a = [1, 2, 3, 4, 5]
[1,2,3,4,5] : List number

> isOdd n = (n % 2 == 1)
 : Int -> Bool

> odds = List.filter isOdd a
[1,3,5] : List Int

> doAction n = n + 1
 : number -> number

> List.map doAction odds
[2,4,6] : List Int


Here, I take a list of integers (in your case it would be records) and
filter on just the ones I want (in this case, odd numbers). Then I use the
`map` function to apply the `doAction` function to each.



On Mon, Dec 26, 2016 at 6:40 AM,  wrote:

> Hello,
> I am new to elm syntax. I have a list of records with name and age. I want
> to apply a test function to each record. The function takes one record as
> input and returns a boolean value. Depending on True or false, I want to
> take a specific action for each record. How can I implement this in elm? If
> it was Python, I will just iterate over each item in the list and pass it
> as a parameter to the function.
>
>
> --
> 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] How can I iterate over the list of records to apply a function

2016-12-26 Thread alexmurjani0
Hello,
I am new to elm syntax. I have a list of records with name and age. I want 
to apply a test function to each record. The function takes one record as 
input and returns a boolean value. Depending on True or false, I want to 
take a specific action for each record. How can I implement this in elm? If 
it was Python, I will just iterate over each item in the list and pass it 
as a parameter to the function.


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