> I'd look to languages like Clojure and Python to get better expectations on how releases work.
Both Python and Clojure had several release this year. Both of these languages are mature languages where a slower release cycle is to be expected.
Elm is still in development and it is normal to expect a shorter release cycle. Not counting dev releases, there were 6 releases in 2014, 4 in 2015 and only 2 last year. This year will probably be the first year without any Elm release. Not even a patch release. This does not look healthy.
> And finally, with the amount that I am working, I'd say the concern is not warranted
I beg to differ. The concern is warranted but it has less to do with how much work you and others put in development of Elm and more to do with how transparent and well communicated this work is.
I wonder if maybe concerns like these have less to do with how healthy Elm is and more to do with how healthy Elm appears to be. The OP was trying to convince people who don't know Elm and, for such tasks, appearances might matter.
> or does it do some sort of a diff between the old model and the new
Close. Elm always renders the entire UI using view : Model -> Html
, but then uses a diff between the new Html
and the current Html
in order to figure out what DOM updates to make. This is done by a library called virtual-dom
. You can read more about this approach here: http://elm-lang.org/blog/blazing-fast-html
Hey! Elm is perfect for this. An adult with programming knowledge can get started by going through this. http://elm-lang.org/get-started especially 1-7 at the bottom. Evan has a talk where he shows cool stuff kids made with Elm. Check this out! https://youtu.be/oYk8CKH7OhE?t=17m38s
The best approach I found so far is to view each Page as an entire Elm application, each with its own model, update and view.
In your Main.elm you tie this together by saving some common context data that will be needed by all pages (something like a session) and either all the models of all the pages OR just the model of the current page.
type alias Model = { session : Session , pageOne : Pages.One.Model , pageTwo : Pages.Two.Model , currentPage : Route }
or
type Page = One Pages.One.Model | Two Pages.Two.Model
type alias Model = { session : Session , currentPage : Page }
Each approach has its own tradeoffs. The elm-spa-example uses the second approach.
This is how everyone has done it so far. There are quite a few companies using Elm, some much more than others: NoRedInk, CircuitHub, Gizra, TruQu, Prezi, Beautiful Destinations, and definitely more who have not contacted me directly. The trend seems to be towards smaller engineering teams where one of the more senior people knows that they'll have a nicer life with Elm, redoes a small part in Elm, that goes well, and it grows from there.
I'd say, if things go badly in that transition, don't use Elm yet and let us know about what happened. We want to fix it and we want anyone using Elm to be having a great experience.
Also, Elm 0.17 had some inspiration from Erlang and Elixir as well.
> That release also introduced a scheduler that was able to switch between work whenever it wanted. Elm 0.17 improves this scheduler quite significantly, taking some basic insights from the BEAM VM used by Erlang and Elixir.
From https://dev.to/rtfeldman/tour-of-an-open-source-elm-spa
> Fair warning: This is not a gentle introduction to Elm. I built this to be something I'd like to maintain, and did not hold back. This is how I'd build this application with the full power of Elm at my fingertips. > > If you're looking for a less drink-from-the-firehose introduction to Elm, I can recommend a book, a video tutorial, and of course the Official Guide.
The links to those are in the article.
type Username
= Username String
This is about encapsulating the String type. This protects any random String value to be used as Username or vice versa.
As a general advice on your question. The functional programming style makes for very declarative code. So I'd say read the code function by function. When you see another function being called, just assume for a second it just does what is says it does. Once you've figured out the exact purpose of the current function you can move on to the next.
This question comes up often on the mailing list and is something the community is working hard to provide better initial documentation around!
One amazing reference that was produced recently is Richard's elm-spa-example: https://dev.to/rtfeldman/tour-of-an-open-source-elm-spa.
I've written a couple applications with a similar structure and I plan to refactor them soon to be extremely similar to this, as it works very well as the application grows.
One tip though—make sure not to prematurely-modularize! I did that recently with a small internal utility with a few standalone widgets—one per page. Every widget's page was its own entire module subdirectory with its own view, update, model, etc. While the separation is quite clean, it's a ton of boilerplate for widgets that often could've been written as just 20-30 more lines in the top level module view/model files.
Hello, I want to share with you https://momentum.earth that we (me as a programmer and a designer friend) did over the course of the last year. You can use the app to create lists to structure your ideas into actionable steps. Based on "getting things done" from David Allen.
The navigation and ui concept is a new approach directly linked to "getting things done", that might be a bit confusing first.
It is a single page app and pwa(progressive web app) with service-worker and offline mode. The UI is written in elm and is connected via ports to xStream(CycleJS). CycleJS manages the events between elm, firebase, indexedDb, web crypto api and a javascript drag & drop implementation.
The most benefiting part with elm is that I can mess around in about 11000 loc without much worry :), I just let me guide back to a compilable version with the compiler (of course logic errors still occur ;)
I think a lot of the answers here are missing the point. Function overloading is generally not a direct feature of functional languages (Haskell has type classes for this). Take a look at this post for an explanation why. In short:
> Overloading is frequently neglected because it is difficult. The more advanced your type system, the more difficult overloading can be.
Elm tries to have a reasonably advanced (yet easy to understand) type system in order to guarantee no runtime errors and give good compiler messages. Java doesn't have this.
If you want to use redux-style "reducer composition", just create a small update function for each field in your model record:
type Action = Increment | Decrement | AddTodo String
type alias Model = { counter : Int , todos : List String }
counterUpdate : Action -> Int -> Int counterUpdate action state = case action of Increment -> state + 1 Decrement -> state - 1 _ -> state
todosUpdate : Action -> List String -> List String
todosUpdate action state =
case action of
AddTodo text ->
state List.append
[text]
_ ->
state
update : Action -> Model -> Model update action model = { counter = counterUpdate action model.counter , todos = todosUpdate action model.todos }
From what I can tell about applyMiddleware
(I haven't used redux that much), it seems to allow the developer to insert side effects before the update
function is called. Elm is pure language, so you're going to have a very hard time emulating that functionality exactly, although you can do some impure actions like writing to the console with the Debug
module. If you want to perform asynchronous tasks, take a look at the Task library
I also think this is what OP should have asked, e.g. how can elm be faster than react?
The answer to that has to do with immutability, the full answer can be found here
If you just want a nice looking website, I'd suggest you use a simple css only library instead of using an elm specific library. (this looks good to me, but there are countless other choices)
The reason for this is that I don't think the elm community has figured out a good answer to styling yet. There are various ideas, but each comes with a drawback.
> since the final output is html, wouldn't it be better just to write that, with templates containing bindings to Elm, rather than have to create lists of nodes in Elm that just end up getting transpiled to html?
This is a great question!
The trick is that this isn't quite accurate. The final output is actually DOM nodes, not HTML. The DOM is the in-memory representation of the structure of the page. When you Inspect Element on this page, what you're seeing is the current DOM.
HTML is a language that can describe a DOM structure. It's a popular way to describe it, but it's by no means the only way! There are plenty of other ways to represent a DOM, including the approach Elm takes.
In practice, it turns out that this approach has excellent performance compared to libraries that use HTML to represent DOM structures, such as Ember, Angular, and React (via JSX). :)
Yes, this is definitely possible. You can write your logic in Elm and then export the resulting values via "ports". You can create a headless Elm app by using Elm.worker()
instead of the usual Elm.embed()
. In JS land, just subscribe to the ports and listen for changes.
http://elm-lang.org/guide/interop
Here's an example of a headless Elm app:
https://gist.github.com/evancz/8521339
Edit: note that this example is slightly out of date, but the same concepts apply in the current version of Elm.
I'm curious to learn more about your reaction. I'm also not into the "untyped = bad" line of thinking, but maybe for different reasons?
I think Elm has been successful (to the degree it has) in large part because I always use constructive communication. I try to say "look at this cool thing, here's some concrete usable evidence that it is nice to use" as opposed to "look at this bad thing, I claim that my thing is better but provide only verbal arguments". This was a goal of mine in this and this, no need to tear anyone down if you have something that is obviously useful. I hope folks claiming to represent Elm feel this way too!
Anyway, that's how I feel. What was your reaction to that kind of framing of things?
Check out the "Tasks" section of http://elm-lang.org/guide/reactivity.
> To actually perform a task, we hand it to a port. Think of ports as a way of asking the Elm runtime to do something for you. In this case, it means run the task.
In other words, from my understanding, tasks (like what Http.get
returns) are things you need to hand off to the Elm runtime which then executes it, and you do that by giving it to a port.
I think the link between tasks and ports is not well-clarified in the documentation and tutorials. Til then, ports just seem like they're purely for general interop rather than Elm's core abstraction for executing tasks/side-effects. I just learned this yesterday.
If you look at the boilerplate for StartApp (http://package.elm-lang.org/packages/evancz/start-app/2.0.2/StartApp#start) you can see that it hooks a signal of your app's tasks into a port so that they actually run.
Hi, and welcome to /r/elm. There are a few examples of doing this on elm's website (Here is a simple clock that really helped me at first). In addition, I recommend looking through the documentation for the Time module.
Here is a very bare-bones example of a counter that increments every second to give you a feel for how it can be like working with a time signal in elm.
import Html import Signal import Time
main : Signal Html.Html main = Signal.map Html.text counter
increment : Signal Time.Time increment = Time.fps 1
counter : Signal String counter = Signal.map toString <| Signal.foldp (_ n -> n + 1) 0 increment
If I haven't answered your question, please let me know and I can try to clarify.
Have a great day!
Just use a Tick and check to see if the time of the slide is done. You don't need to check every few milliseconds, half a second should be precise enough (I think).
Here is an implementation using the Elm Architecture which should qualify as the "Elm way". Just copy & paste the code in Try Elm Page to see it working.
Hello!
Elm can absolutely be used as a frontend for any type of backend application. Elm apps are built and served just like any javascript SPA.
Your Django backend should expose JSON endpoints which your Elm app will fetch using a package like elm-lang/http
.
There is a bit of work involved to map your JSON responses to Elm data types through JSON decoders, but there are tools online to assist (like this Json-To-Elm project).
For a fully working example of this, check out this article and linked github repo: https://dev.to/rtfeldman/tour-of-an-open-source-elm-spa
Elm's development can certainly seem slow compared to Javascript frameworks, but this is deliberate. Evan takes his time to carefully plan the language and ensure new features are solid before releasing them. He recently posted a roadmap, which should be within the first couple pages on r/elm
.
I'm pretty new at Elm, but based on the documentation I've read, I think I can provide an answer. The idea is to use the fps
function to generate a signal for physics updates, use foldp
over that to generate a signal for the physics state, then use map2
to combine that state with the latest frame delta coming from another signal that updates every frame. This should produce a signal that updates every frame, but uses the physics state that has been updated at a fixed rate. You can then use this as the view update signal. The question then is how to produce the every-frame signal. I can't find a definitive source, but there is some discussion here. It is quite old, and there may be something better that has arisen since.
> > > Making Pong - An Intro to Games in Elm (http://elm-lang.org/blog/making-pong)
This appears to be written for an old version of Elm, that uses the Signal model that was removed in Elm 0.17 in 2016. (And indeed, it was written in 2012).
Now I wonder, is there a way to use old libraries, based on Signal, with current Elm?
This is actually the most successful strategy so far with Elm.
It's what NoRedInk did in their code base (they just started implementing components in Elm instead of React).
There is even a blog post about it.
Read the Complete Guide further down in the page first!. The syntax and library references only make sense once you've first read the guide.
On a side note, it's really nice to get a basic grasp of functional programming before visiting Elm. Besides including common features like currying and function composition, Elm includes weirder concepts like the Hindley-Milner type system and monads, both of which are also found in Haskell. Learning Haskell first isn't necessary though. Instead, check out the Mostly Adequate Guide to Functional Programming. It introduces FP from the ground up using only vanilla Javascript so you can get a better idea of what's going on in an environment already familiar to you. Reading up to Chapter 9 or 10 will get you to a really comfortable place and will make learning Elm so much easier.
Evan's talk "Controlling Time and Space" will help you better understand FRP which is the underlying model for what's happening in Elm.
Have you read The Reactivity Guide?
I use Atom (with language-elm package) and it's good. You get code completion and stuff. To be able to jump to functions I needed to install this goto package (https://atom.io/packages/goto), because symbols-view (ctags) wouldn't work.
My comments in this thread go into some of this stuff.
I think "isomorphic" apps will be possible one day, but we are not there yet. The elm-discuss thread goes into more detail on that!
Let me know if that is helpful!
I think this will work better on elm-discuss, but we can try here. To really help we need to know what you are actually trying to do, not just the feature you think you need to do it.
It's easy to get XY problems and it seems like you are asking for a feature when the answer may be "what if you think about it like ____ instead?"
I know Max used Elm on an Arduino but I don't know of other cases.
I think it would be really pleasant to use Elm's signals to work with robots, but I haven't gotten a chance to work on it myself. My robot programming experiences have always been pretty bad language-wise, so I think this is a very promising platform to explore!
I'm presumably qualified (see https://github.com/rtfeldman/dreamwriter) but unfortunately don't have the time...just wanted to stop by and say it's exciting to see another production Elm code base in the wild!
Evan already posted on the mailing list - https://groups.google.com/forum/#!topic/elm-discuss/OJ6YltkJgf8 - about this, but it doesn't look like there are any takers yet.
If there's any less hands-on way I can contribute - talking through solving particular architectural problems in Elm, etc. - I'd be more than happy to help!
Well said!
I was just reading some brunch.js docs. (Great software and mostly great documentation!) But it threads this unhelpful "brunch" analogy through the entire getting started document instead of having useful headings:
http://brunch.io/docs/getting-started
Seems like a somewhat related problem. Maybe I'm just old and grumpy and don't like fun anymore. Anyways, yay useful names! (And headings!)
> I'm kind of stuck with Elm. Advice?
Go through the elm-lang.org/examples and for each of them try to make it your own. Try to change something in it. For example, take the hello world and try to output a h1
instead of the text. Open the developer console and look at the output.
Use Ellie to play with styling your elm code. For example, this is the buttons example altered a little bit with styling.
I’m not sure, but read this http://elm-lang.org/blog/blazing-fast-html
And, if you only use the parts needed for the view in the view functions there’s no need calculate the virtual dom diff for the model you’re trying to change in the background.
Custom Elements, the technology, has not been widely adopted and I would be surprised to see official support in Elm anytime soon. Pleasantly surprised, I might add. :)
I guess the approach used for React Components implemented in Elm could be used.
> Even if we ignore the setTimeout part and if I wanted the AI to make its move immediately it would be "dispatching" an action from within the update function which seems weird to me.
It is not weird at all. This is how the Effects work. The Elm Architecture Tutorial examples 5 to 8 show how this works.
Here is a gist with the code from SpiningSquare (Elm Architeture Tutorial example 8) with minimal changes just to make it behave like a TurnBase. (You can copy&paste the code in elm-lang.org/try ) If you click the square, it will "switch" to the computer and then back to the Player.
Of course, in your code you can have an action that switches to the computer (sets the state so you can display "The Computer is thinking..." and returns an Effect that interrogates a server for some king of solving of the move and generates an action that returns the control back to the player with the results from the interrogation (the AI move).
I haven't been using Elm for very long but based on that blog post I can tell you that the import syntax has changed. For example:
> import List (map)
is now
> import List exposing (map)
Elm has an interop mechanism.
In theory you should be able to do whatever you like in Elm and push the result through a port back into JS.
In practice, I imagine that working in any field you need libraries and I'm not aware of AI libraries in Elm... but hey... as the shoes salesman story said it.... glorious opportunity! ^_^
I have a very minimal example with using elm with highcharts. Mainly it is a combination of elm-html and ports.
https://github.com/yogsototh/elm-highchart
In fact the ports documentation was both simple and easy to follow.
http://elm-lang.org/learn/Ports.elm
Now, the ideal for me would be to find a way on how to integrate highcharts inside native elm. I didn't looked on how to do it for now. Any pointer would be welcome.
A simple audio library, similar to this: https://github.com/kittykatattack/sound.js
A full featured 2D sprite library like Pixi (http://www.pixijs.com) with a animation state player/manager, texture atlas support, and a fixed-time-variable-render game loop.
I am sure /u/rtfeldman could give useful input here. If you have not read the excellent post defense against the dark arts CSRF attacks, do it now!
Nice write up :)
I use the browser-plus plugin for Atom to have a browser right in Atom. It also supports live reloading (you have to activate it by clicking the lightning icon). Which is nice.
Alternatively if you want to use an external browser you could use the browser-refresh plugin. It will refresh your (last used(?)) browser tab after hitting F5 in Atom. It also brings the browser in the foreground and makes it focused.
Really nice work. One thing to note with this approach (small outer container, large inner container) is that you can't truly have an unlimited number of items in your list, because browsers have limits on how tall and wide elements can be. In chrome, it's about 33554400px. This might not apply for most people, but if you try to render 10,000,000 items with a line height of 20px, the list will get truncated.
I've been experimenting with another approach that listens for mouse wheel
events instead of scroll
events. The upside of this approach is that you can truly render as many items as you want. The downside is that you don't get a real, native scroll bar, so you have to render your own.
Edit: Also, it's much more efficient to slice
an Array
than to filter a List
for items that have an index within a given range.
I can confirm that the issues are present with 0.16 on OS X. Chrome is choppy but Safari is beyond bad on your sample. :)
I don't have a solution but please report this as an issue on the mailing-list too. Maybe someone there has deeper knowledge about this.
> "The difference would be that our signal graph now extends over the network and implicitly persists the values flowing through it."
I have a feeling we're discussing two different aspects of the same thing. Let's use an email-based analogy to explore this...
In some email clients, you receive new email as soon as it is available to you, in other email clients you have to make a request to receive new email. In terms of Elm, I believe you prefer the first approach, that's fine, I like that approach too.
But I'm not really concerned about how new email is sent through the system, I'm asking about how to define the email addresses, the end points of the system.
> "That makes sense. I just think it can (and feel like it should) look pretty much the same as it does now with the Elm Architecture."
I can't find anything in the current Elm Architecture that relates to describing database objects. Can you describe how this currently works in Elm?
From what I've seen we currently rely on pulling in data via REST APIs and similar, but I haven't seen anything related to this in the Elm Architecture itself. The closest I found to something describing using Elm code to interface with databases was this Google Groups discussion from back in 2013...
https://groups.google.com/forum/#!topic/elm-discuss/T7xPMKA0VAk
I know very little about Elm, so it's possible I've missed it, and I'm not criticising Elm, I respect it's a young language that is still evolving, I just want to make sure we have (or can find) an elegant solution for handling external data in Elm.
Check out how it works in this code. If you still need help, the folks on the mailing list are friendly and can give you pretty detailed advice!
What is most useful will depend in part on your coding background. Personally I found of most importance was to get my head around functional programming, so I found working my way though https://www.gitbook.com/book/johncrane/ninety-nine-elm-problems/details invaluable. They are nicely graded and have answers and hints to help you on your way. I find writing apps, so much easier now as a consequence.
I'm not sure if any of the devs hang out here but the example program http://elm-lang.org/examples/field linked from https://guide.elm-lang.org/architecture/user_input/text_fields.html does not match up with the tutorial text.
Or maybe there's a better place to report this, educate me!
I just checked and it appears in the docs here http://elm-lang.org/docs/syntax#modules but it is explained poorly.
I remember being stuck with this same issue, I don't remember if I figured it out from the docs or by looking at someone else's code.
As Evan said, you don't need type classes for that.
With the current Elm semantics we have the idea of a restricted type variable, for example comparable
. All tuples, lists and records of things that are comparable
are themselves comparable
. Now, there could be a new restricted type variable serializable
or encodable
and a pair of encode
/decode
that could produce the JSON or produce the type from the JSON. If this is coupled with adopting an official JSON representation of Union Types, a lot of the current encoder/decoder code could disappear.
To give you a practical example. We could have the following signatures in the Http
package:
send : (Result Error encodable -> msg) -> Request encodable -> Cmd msg
and
get : String -> Request encodable
and then have the http example become:
getRandomGif : String -> Cmd Msg getRandomGif topic = let url = "https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=" ++ topic
extractImage { data } = data.image_url in Http.send (NewGif << extractImage) (Http.get url)
Hey! Just getting into elm myself. I was looking at the examples on the Elm website, and I noticed something about the radio button example: the text starts at 'medium', but the 'medium' button isn't selected when the program starts.
What's the best way to adapt that example to make the radio for the original size start selected?
You specified all the needed information so the compiler is happy.
Take this definition type alias ParticleList particle = List { particle | id : Int }
, ParticleList ParticleExample
is not the same type as List ParticleExample
. if you have type alias Identifiable r = { r | id : Int }
, ParticleList ParticleExample
is the same as List (Identifiable ParticleExample)
With the definitions above you can have function that would work on any Identifiable r
including Identifiable ParticleExample
.
Maybe the Records docs can shed more light on this.
>React is well behind Elm in terms of performance: http://elm-lang.org/blog/blazing-fast-html-round-two
Currently with the same library size footprint but with 0.19 it'll be much smaller.
the line import Html exposing (Html, button, div, text)
is saying "import the module Html
exposing the type Html
and the functions button
, div
, and text
. Similarly for the other lines, you're importing some specific functions from a module. While you're starting out, it might be easier to do this.
import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..)
This has the effect of importing everything from those three modules, so you have access to basically anything you'd want to do with html.
exposing (..)
becomes a problem when 2 modules might export types or functions with the same names. For instance, if we want to add some svg to our html using the Svg
module, we'd get a ton of name collisions because a lot of the elements and attributes have the same names. So in that case, we have to "qualify" (read: give a name to) an import. There are two ways of pulling this off
import Html
still gives you access to the whole api of that module, but you have to say Html.div
and Html.Events.onClick
and suchimport Html.Events as Events
, and now you have access to Events.onClick
and such. You can also combine as
and import lists to get the best of both worlds. If you need more help figuring out syntax (which is normal, its weird!) check out this reference . Also, the slack community tends to be very good at helping people drill down to their learning blockers and provide help
> they created it, they use it, cool.
Elm was initially designed by Evan Czaplicki as his thesis in 2012. While it is true that he currently works at NRI, this is only a recent development (he joined them this year). They were already pushing 30k LoC long before Evan joined them.
> Is there anyone else?
At the bottom of the elm-org main page there are a series of featured users. Some of these users (like NRI) use Elm in their own product, others use Elm in implementing solutions for their clients.
> And yes, we're well aware it is 0.17-0.18 still. But so far it looks so good we're going to use it anyway.
You're betting on Elm. I think this is a good bet. May the Force be with you!
I think for your show
example I would write it using the Html
module instead, which currently has better performance than Graphics.Element
and seems to be what the community is centering around. Something like (tested at http://elm-lang.org/try):
import Html exposing (Html) import Time exposing (Time)
line: a -> Html line value = Html.div [] [Html.text (toString value)]
view: Time -> Html view time = Html.div [] [line "v", line time]
main: Signal Html main = Signal.map view (Time.every Time.second)
(line
is a simple helper function I use in some of my test code that acts kind of like show
- take an arbitrary object and show it as a string in a div.)
It is true that every Elm function can only return a single value, so to return multiple values you have to combine them first and then return the single combined value (e.g. in the above code, the two output lines are combined as children of an overall div). However, Elm does have something like 'multiple expression functions' using the let
expression, which lets you declare intermediate values that are ultimately combined into a final result; you could rewrite the view
function above as something like
view: Time -> Html view time = let vLine = line "v" timeLine = line time lines = [vLine, timeLine] in Html.div [] lines
which can be very useful to help break up complex expressions.
Regarding code highlighting in the browser, Code Mirror has Elm support
For a live demo, you need a compilation server. The code for elm-lang.org is open source, so... if you have some Haskell knowledge maybe you can reuse the bits that power http://elm-lang.org/try
You can access the current time through Signal Time
. For example, you can use the every second
signal to give you a "pulse" of the current time every second.
http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Time
Here's an example of every second
in action:
http://elm-lang.org/examples/clock
Since you only need the current time as a seed, another option is to use a port
. You could do something like this:
Main.elm
port currentTimestamp : Int
index.html
var div = document.getElementById('app'); Elm.embed(Elm.Main, div, { currentTimestamp: Date.now() });
Maybe those JS frameworks are not "minimal". They probably have a lot of cruft, things that you're not even using in your project but may impact performance.
I agree that theoretically, a well written program in pure JavaScript with just the necessary stuff and a good design, could be optimized to have the best performance possible. But that is not happening in the real world, which leads me to think that one or more of the above is not true. People use a lot of libraries, frameworks and stuff in JavaScript, any of those might have a bad design, be poorly written, have bugs and so on, and all of those things will have an impact on performance. You can see in the same benchmark that even between the JS frameworks there's a lot of difference in performance.
Evan says that the design of Elm+ Virtual DOM is what makes this optimization possible, by being sure the data is immutable Elm can avoid rewriting the DOM unnecessarily. Read more about it here: http://elm-lang.org/blog/blazing-fast-html
Disclaimer: Somewhat new to Elm as well... So forgive me if I steer you incorrectly.
Bullet #1 - A good lead would be to consider foldp -- It's a way to advance the state overtime.
Bullet #2 - That is a great idea. I believe what you need is what you see here Tagged Unions (Ctrl/CMD F)
The way it does it is like:
numberOfMoves 3 = 2 * (numberOfMoves 2) + 1 = 2 * (2 * (numberOfMoves 1) + 1) + 1 = 2 * (2 * 1 + 1) + 1 = 2 * 3 + 1 = 7
So, basically, when it gets to that new call of numberOfMoves it just calls itself again with that new value. As you said, when you call it with three, it then calls itself with two and then with one, and then when you get to one you get an answer and that answer propagates. It's called recursion. It's super common in Elm.
You can check out some examples on recursion here: http://elm-lang.org/examples
That would make for a complete tutorial on Elm and functional programming. You can find much more in http://elm-lang.org/docs, which includes a complete guide about Elm. I'll try to answer your questions, but please let me know if there's anything else missing.
Let's use the init
function, which takes a String
and turns it into what we defined as a model (a list of letters and booleans):
init : String -> Model init word = String.foldr (::) [] word |> List.map (\letter -> (letter, False))
Here, String.foldr
is used to reduce a String
to a List Char
using (::)
(which adds an element to the front of a list) and the empty list. For example, "elm"
is reduced to 'e' :: 'l' :: 'm' :: []
(['e', 'l', 'm']
) one letter at a time. We can then map over that list to turn each letter into a tuple with the guessed value set to False
.
Action
and Status
are types. We defined Action
as type alias Action = Char
, so it's just a name that we use for Char
and we use alias
to define such a type. We defined Status
as type Status = Lost | Playing Int | Won
, which is a type with three constructors, one for each possible status in the game.
update
and view
are just functions, but they're also the names for the fields of the record type that we need to have as argument for the start
function in main
.
Finally, the important thing to know about the Signal.Address Action
here is that view
takes an address and creates an event to report to it whenever the user presses a key (which means entering a Char
, our action). It's probably better to read the reactivity section of the documentation (http://elm-lang.org/guide/reactivity) here.
simply toString (Basics.toString) will do
import Html
strOfInt = toString 10 strOfFloat = toString 3.2
main = Html.text (strOfInt ++ " " ++ strOfFloat)
Try it in http://elm-lang.org/try
Thanks for the solution! I hadn't considered merge, and now I see it's described here http://elm-lang.org/guide/reactivity
I'm still struggling to grok how to combine time updates and several user inputs in Elm, but I guess the solution lies in merging the signals.
I am a bit more familiar with Racket's big-bang function, where you can just list time-ticks, key events etc. See http://docs.racket-lang.org/teachpack/2htdpuniverse.html
Example (corresponding to Elm's main function):
(define (main initial-state) (big-bang initial-state (on-tick change-state) (on-key interpret-keypress) (on-mouse interpret-mouse-input) (to-draw render-world)))
The way this is done in Racket is quite easy, since you can just add an arbitrarily long list of thing that should happen on time-ticks and input events.
I'm not quite sure though if the way this is done in Racket could be called FRP the same way it is in Elm(?).
There's a chapter on Elm in "Seven More Languages in Seven Weeks".
Here's a free online book called "Elm by Example": http://elm-by-example.org/index.html
Also suggest reading the Elm "white paper": http://elm-lang.org/papers/concurrent-frp.pdf
I know there are some folks on the mailing list who have done more tuning of collage
rendering than myself.
One thing you might consider is using the Array
library depending on how big this list is getting. This post talks about how arrays work, and should give some hints as to why they'd be faster than linked lists for this kind of thing.
Does that help at all?
This isn't an official tutorial (although a very good one), it probably just outdated. For official examples check out: http://elm-lang.org/Examples.elm
About your problem I suppose it caused by recent import changes, it should be fixed by:
import Color ... Color.blue
If it doesn't help don't hesitate to post a SO question under the 'Elm' tag, it actively supported by community and you likely to get a good answer in few hours.
Works pretty well for me on chrome.
But I also had some pretty bad lags with just a very simple game example.
I'm pretty sure that if you used canvas naively in javascript, you'd get similar performance problems. A game engine does a lot of optimizations, many render using webgl (As does pixijs).
Another problem that elm has with games is the default game loop. You're using fps 35
which is not ideal. An ideal game loop has a fixed logic timestep and a variable rendering timestep (as described here). I don't know if this is even possible in Elm.
Some other languages have features that are similar, but weaker and uglier (and are maybe meant for a different purpose anyway). For example Haxe lets you define a type that exists only at compile time as an abstraction over a runtime type. The problem with using that for things like units and conversions is it's not generalized, you end up writing a <u>lot</u> of boilerplate code, and you don't get to write "meters per second" as just m/s
The cleanest way to sepate your front-end and your backend is to serve your backend from a different subdomain. Like api.yourdomain.com
. It will also help you when you decide that your front and your back won't be served from the same machine at all. You could for instance decide to put your frontend directly in a CDN with for instance Netlify.
> what if you wanted ten theme-pickers scattered around the page...?
Actually Elm Architecture Tutorial example 3 models something like this very nicely (A list of counters). You can modify only the CounterList.elm file and have the app display which of the counters was triggered and what is its current value, which would be the equivalent of having those theme-pickers. :)
Anyway, please join the elm-discuss Google group. Maybe someone there can suggest a better strategy.
I don't know the specific answer to your question, but folks have definitely discussed this on the mailing list before.
My guess though would be "are you changing your attributes or your uniforms?" There's more about that distinction here. You want to get your attributes set up once and for all, and then send tiny uniforms across to the GPU.
The title of this post has nothing to do with the content. There is nothing mobile about your issues with Elm and TodoMVC.
That being said, I did find a good thread about using Elm for mobile dev - https://groups.google.com/forum/#!searchin/elm-discuss/mobile%7Csort:relevance/elm-discuss/pQj5aoZne5Q/eoPcZhTWAaAJ
To attempt to be more helpful, it may be good to try to find discussions like this one that get into how to architect programs with effects. The goal is to have little effect handlers at the edges of your program that talk back to a mailbox.
Whenever you find yourself trying to bring this structure into your app, Elm is going to push back on you. I think this is a great benefit in that Elm wants you to have an architecture that is going to work well as your code base grows.
Do you mind asking about this on the mailing list? I'm having trouble getting to all the questions and I think folks on the list can help.
The short version is that Element maps onto HTML, but is a bit behind elm-html in terms of features. Collage goes down to canvas and HTML sometimes. The same tricks can be used as with elm-html, but this stuff was all created well before that so some of the more sophisticated tricks are not added yet.
Trying Elm is very pleasant. It is a very good educational language for an introduction to functional programming. It's small which is a very good thing for learning a new paradigm, the documentation if very well done and you'll have to code in FP style. For these reasons, I like to lovingly call it the Scratch of functional programming.
The Elm community is also very nice. There are lots of open minded people who will spend lots of time helping you. That's what is frustrating in Elm: it's a neat language with a charming community but the leadership cause some problems.
For big projects, you must know the risks: major versions may break compatibility so hard that the best option may be to rewrite your projects in another language, there is no private package repo (the only option seem to still be GitHub), and there are a few other things like that you must be aware of before jumping in.
If you can take those risks, then Elm is a good option and a good stairway to other languages like Haskell, PureScript, O'Caml/ReasonML, etc.
Is there a particular set of tools that you find better? PureScript heavily relies on NPM, and even though there are pure non-js package managers, the official docs regularly recommend using NPM on target platforms. That's not my definition of better tooling, it's quite contrary, and I think some Elm developers would feel the same way towards having to rely on NPM.
My personal webpage uses Miso+GHCJS brotli-compressed bundle, which is 71KB in total size. According to this benchmark from last year, it's somewhere between Elm and React+MobX. I think it's a reasonbable result, especially if we consider that this bundle includes the whole GHC runtime suitable for running in the browser, which includes most of the higher level abstractions not available in Elm and JS.
I myself am a big fan of VSCode with the new remote extensions, I can have my whole Elm toolchain in a container but still use the editor on the host and then you can specify which extensions you'd like to run inside the container via .devcontainer.json
The modern chat clients have support for html formatted messages. In these messages you can have pre elements that would allow for nice enough display of code. Some chat clients, like Slack, also allow for sharing code snippets. These are basically pre
elements with some hints about the syntax of the code.
There is not. Can you share your findings on the email list if you try to make something? I know there are minor compatibility issues with the runtime and node right now, so it'd be good to know what you run into.
SOLVED
yarn run elm make src/Main.elm
works, although it overwrites the original index.html.
I removed the global elm binary and use the local one. Currently I'm getting the following error.:
yarn run parcel build index.html
yarn run v1.12.3 $ /home/michiel/trip/node_modules/.bin/parcel build index.html ⠴ Building Main.elm...Unknown Elm compiler option: optimize Could not find Elm compiler "elm-make". Is it installed? error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
edit: I had some issues with nvm and system node, although using yarn.
Great news, u/mewhit had recommended http://elm-lang.org/examples/drag to me and I was getting an import error through elm-reactor so thank you for clarifying which of these packages said example was trying to import.
Example runs smoothly now, so I've just got to work out how to adapt that to my more specific needs but it appears I've got all the tools I'll need to get that done now. So thank you everyone. :D
> One of the confusing things I've found in my journey is that different Elm versions are so different there's a lot of outdated advice out there.
Elm is a young language and it is still in development. In the last two years the rate of change slowed significantly and I doubt that we will see the kind of change we saw in 0.17 (when Signals were removed).
As a rule, if you find code that was written prior to 0.17 you might be better off ignore it. Most of the code that worked in 0.17 will work in 0.18 with minimal changes (see the Less Syntax section from the 0.18 announcement ).
Trying elm in VSCode but feeling let down the intellisense, is it the plugin/editor/language or me that's at fault?
For example I was experimenting with the http://elm-lang.org/examples/http code. There's a Http.Error call that seems to work correctly but if I do Http followed by a dot intellinsense pops up but Error is not in the list, if I type in Err it asks if I mean Error.
Any reason this doesn't work? I find these hints such a powerful way to learn a new language.
AFAIK that was <-
. Maybe it's a related story: both left arrows were removed at the same time, and the motivation in the case of <-
had an aesthetic side.
Yeah probably years since the virtual DOM was introduced with https://github.com/evancz/virtual-dom and the blog post about it: http://elm-lang.org/blog/blazing-fast-html (23 July 2014). There were probably an issue on it with the old repository (evancz) but not available now.
Hello, I have problems adding onClick handler to input with disabled attribute. It works just all right though if input element is not disabled. Is there anything I can do to make this work?
The example code is here, you can paste it to Elm-try to check it online (sadly Elm-try doesn't support gists).
Thanks in advance.
I don't think this was mentioned, but it looks like your record update syntax is a bit off. You have:
{ model | translated = content | errorMsg = "" }
but the correct syntax is:
{ model | translated = content, errorMsg = "" }
But. As a side note. I do really like the imaginary syntax you were using. I think it is much prettier!
Here is a link to the docs for record updates: http://elm-lang.org/docs/syntax#records
Well, one thing that might help with the second function is that you can replace that big if/else chain with a case statement.
I would pull that case statement out into a named function that operates on one word at a time:
meowthifyWord : String -> String meowthifyWord word = case word of "JERK" -> "JOIK" -- etc
Then your meowthify
function becomes easier to think through, you want to take the string you start with, split it into words, then map over the words, then join back, something like:
meowthify : String -> String meowthify s = s |> String.split " " |> List.map meowthifyWord |> String.join " "
HTH. PS. Don't forget to deal with lowercase...
Thanks! It looks like it doesn't work if you copy/paste it into http://elm-lang.org/try though. It doesn't seem to like the Dom module. I get this error:
I cannot find module 'Dom'.
Module 'Temp1474577168177632' is trying to import it.
Potential problems could be: * Misspelled the module name * Need to add a source directory or new dependency to elm-package.json
Array.concat is O(n), so building a longer list by concatenating an item at a time would be unacceptably slow. Building lists this way would be O(n²). On the other hand, appending to functional lists is O(1).
Compare performance:
https://jsfiddle.net/6quL5d1t/
function range(a, b) { var array = []; for (; a < b; a++) { array = array.concat([a]); } return array; }
range(0, 20000); console.log('done');
vs
import Html exposing (text) import List
range a b = let loop b accum = if a > b then accum else loop (b - 1) (b :: accum) in loop (b - 1) []
main = let lst = range 0 1000000 in text "done"
The Elm code runs circles around Array.concat.
No problem. Signals have been a bit confusing for me too. Though, it looks like with 0.17 that just released, they changed signals and "ports" (the js interop bit) and now they are all contained in the concept of "subscriptions" and "messages". I believe the official elm docs got updated too. Here, in case you want to read the announcement: http://elm-lang.org/blog/farewell-to-frp
This tutorial is amazing.
If you want to take it further, you can add some instructions from electron packager and create a full OS X App.
You can use the Mario Example code for this.
It might make sense to use the JavaScript FFI in such cases. From my (limited) understanding of Elm, it seems to me that you can't selectively introduce local state without subverting the whole architecture.
Folds are a way of combining things together. Say you have a list of numbers, and you want to add them up.
import List exposing (..) import Graphics.Element exposing (show)
sum = foldl (+) 0 [1, 1, 1] main = show sum
Paste this into Try Elm and play with it.
What is happening here is that the list is being "folded" from the left. So the first thing that happens is that the initial value, 0, is added to the first element, 1. 1 is now the initial value, and 2 added to it, and so on. The following lines are equivalent as the list is "folded up":
foldl (+) 0 [1, 2, 3] foldl (+) (1 + 0) [2, 3] foldl (+) (2 + 1 + 0) [3] (3 + 2 + 1 + 0) 6
You can also fold a list from the right, where these lines are equivalent as the fold is computed:
foldr (+) 0 [1, 2, 3] foldr (+) (3 + 0) [1, 2] foldr (+) (2 + 3 + 0) [1] (1 + 2 + 3 + 0) 6
Remember to read foldl and foldr as "fold from the left" and "fold from the right" respectively. That makes it easy to remember what end of the list elements are folded from. It also helps make foldp more sense, because if is folding from the past.
So you only need to do the UI portion? In that case you should start by taking a look at the collage documentation and an example of how to draw shapes.
I don't know if it helps but you could take a look at the code that solves the first 5 challenges from here. This is the progression of the challenges that I received when I set up to learn Elm.
I was able to do them because I've spent a lot of time reading the Elm examples. Some of the code was lifted from there.
Coming from python, there were a lot of moments of painful struggle but I believe the result is worth the trouble.