[elm-discuss] How are people deploying their Elm applications?
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...
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...
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
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
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
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...
*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
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
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
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.