Hi all!
I wanted to show what I’ve been working on for the last 6 months:
NoKey, a password manager without a master password. Instead, you can unlock your passwords by confirming from another device. E.g. if you need a password on your PC, you only have to confirm this on your phone. No need to remember any passwords!
The vast majority of the code is written in Elm and it’s fully open source.
There is a browser extension for Chrome and Firefox and an Android app. The application is only useful with at least two devices, so to really test it out, you’ll have to install it on two devices. There is no iOS version and the web app doesn’t work on Safari either (it's missing some stuff from the Web Crypto API), sorry!
Any feedback or questions are greatly appreciated!
Elm version, just paste it into http://elm-lang.org/try and click the compile button
import Graphics.Collage exposing (..) import Graphics.Element exposing (..) import List exposing (..) import Signal import Time exposing (fps)
main : Signal Element main = Signal.foldp (+) 0 (fps 60) |> Signal.map scene
scene : Float -> Element scene t = t / 40 |> shape |> collage 460 460
shape : Float -> List Form shape t = let intervals = [1..19] |> map (\x -> (11*x, x*t, 360+x*t)) style = { defaultLine | width <- 8 } draw interval = interval |> arc |> path |> traced style in intervals |> map draw
arc : (Float, Float, Float) -> List (Float, Float) arc (radius, alpha, beta) = let circlePoint angle = (radius * sin angle, radius * cos angle) in [alpha..beta] |> map (\x -> x / 100) |> map circlePoint
Just remove the explicit type signature from your getName
function and you get the following general signature inferred by the compiler:
λ>:t view [l|name|] view [l|name|] :: FieldOwner "name" a s => s -> a
which will work on any record that has a field "name". So you can use that signature instead.
Generally it is the area of Extensible Records. I expect that some work will be done in that direction.
It's not Haskell, but I think you might find Elm pretty interesting. It has a similar flavor to Haskell but is geared towards the type of stuff that Processing is for, if I understand correctly. Give it a try! There are some nice demos on the website, IIRC.
Check out how Elm is doing it:
The type annotation is saying: [[ some type ]]
But I am inferring that the definition has the type: [[ some other type ]]
Incredibly clear and informative.
I'm reminded of functional reactive programming. That would normally necessitate a communication channel of some kind between the UI and the code doing the work.
Could a UI be designed as top-down updates in response to events in an event queue? Would that be too slow?
edit: I found a white paper describing the FRP design in ELM.
Dependencies are flat, and semantic versioning is strictly and automatically enforced by the package manager -- as in the package manager actually type checks your package and diffs the public APIs to assert with high confidence that breaking changes actually do require a major version increment.
You can read some about it in the elm 0.14 release and this discussion.
So, elm is a functional programming language which compiles to JavaScript. It's modeled around Reactive Programming, which avoids the need for callbacks.
Basically, you write a program in Elm, compile it, and get a generated JS file which you can use in a webpage. It also can generate the entire HTML page for you.
Because it's functional, you can write concise, easy to read code. Because it's statically typed, many bugs that manifest as JavaScript runtime type errors are caught by the compiler.
You can use it with PhoneGap or any other platform, as you would any JavaScript code that you wrote. Additionally, Elm has a beautiful system for interacting with other JavaScript modules.
For more learning and examples, see the Learning and Examples pages. You can even edit the examples in your browser and see how they change!
Heard of all of them bar Pony, Haxe, Agda, Gosu. I would have liked to see Elm (/r/elm/) on there.
Personally I am really excited to see Kotlin mature. I feel like it could reach a stage where it would become to default language for Android development.
Union types are in the docs. In particular they are tagged unions, which is one kind of union type, that's also known as a sum type.
Other related terms: structural typing and structural subtyping. You can draw a contrast between nominal typing and structural typing:
When things are nominally typed, the name of the type is the thing that determine if two types unify. So, in haskell, let's define two types:
data Person = Person {name :: Text, age :: Int} data Dog = Dog {name :: Text, age :: Int}
Ignore the whole problem with overloading labels for the moment. The types Person
and Dog
are not the same. You cannot pass one where the other is expected.
Structural typing means that types are determined by their structure, not by a name. Naming structurally defined types isn't usually required, and is done as a type alias. As an example, records in Elm have language-level support for this kind of thing. Here is an example of how this can be approximated in haskell:
type Person = '[ "name" :~> Text, "age" :~> Int ] type Dog = '[ "name" :~> Text, "age" :~> Int ]
You would need to define a :~>
combinator and use something like vinyl
, but this will work in GHC haskell today. The problem is that these attributes are a list of tuples, not a map. So, if in the example above, I had flipped the order of the two attributes in Dog
, then Person
and Dog
wouldn't be the same any more. It's also hard to prove things with them (hard but not impossible).
This one in particular is, IMO, a genius UX feat:
> http://elm-lang.org/assets/blog/error-messages/list.png
> Here let me explain to you human pleb what would happen if this code was reinterpreted as JS maybe then you'll understand what I mean by the list items not having the same type.
For static charts/plots/graphs the library Chart is really nice. Otherwise diagrams+an FRP library is probably your best bet.
Slightly outside of Haskell I have been playing with Elm recently and am incredibly impressed with its ease of creating interactive applications. Plus since it compiles to Javascript the ease of deployment is miles ahead of Haskell.
While if you know the rules, you can drop semicolons in JavaScript, many other syntax things aren't the same. JS doesn't enforce whitespace, doesn't do implicit returns, makes you define a variable with var
or let
, there's neither @var
for this.var
nor ..
for the head and tail, and requires parentheses and brackets everywhere you look. ES6 has a fat arrow but no concept of a thin arrow if you don't want that kind of variable scoping.
I'm not really for or against either technology, but they're still different beasts and require compilation at this juncture for production regardless of CS or ES6. It's a bit naïve to assume that one replaces the other.
The core issue comes from the fact that JS is the only browser scripting language and has one syntax that may not jive with some people's coding style. Take a look at Elm or PureScript for example which are Haskell-like and enforce immutability rather than using it as a convention in the same vein that JS/ES6 can't enforce whitespace the way CoffeeScript does.
I don't have anything like that right now, but I am currently working on some larger examples (e.g. complex forms, light-box). My thesis adviser is asking me the same question :)
The lack of large examples is definitely an important concern, and I have noticed this trend as well. One explanation is that FRP does not scale, but I think this simplistic view is mistaken. My guess is that, so far, no FRP language has really reached the maturity for real-world use. Much of the research has focused on the problems of the semantics and implementation of FRP, so the other details, such as the best representation for a functional input field, have not gotten much attention. Unfortunately, these details really matter when you want to make bigger examples.
tl;dr: I am working on it.
edit: The largest example that exists right now is the site itself. Excluding the code editor, the client-side code for elm-lang.org is written entirely in Elm. You can look at the source by inserting edit/
after the domain: http://elm-lang.org/edit/docs/Signal.elm. I know that's not the kind of example you are looking for, but it is the closest thing I have right now.
> The computer doesn't care what syntax or semantics we use or how error messages are phrased.
Elm has a pretty good approach here, that doesn't involve hamstringing the entire langauge.
I don't necessarily agree that Elm is definitely the go-to solution, but I have been following it for a while and it does a lot of things very well. I am continually impressed by the design decisions Evan Czaplicki makes, and what he has been doing with Elm has had a lot of ripple effects outwards.
> It's still Javascript, with its dynamic typing, awful prototype object design, and toxic culture (bower, node, grunt, etc).
Elm has a pretty great static type system, syntax and type-wise it is a lot closer to Haskell than Javascript. And as a relatively young language with not a lot of uptake, so far its culture has avoided inheriting many of the typical JS hangups and has a strong focus on quality. For example, its package manager can detect API changes and enforces semantic versioning whenever a publicly exposed API changes, take a look: http://elm-lang.org/blog/announce/0.14
You might want to actually check it out before passing judgement.
> Unless you've done a lot of work in a static Lang like GO, Java, C#, I think it's hard to understand why it sucks (...)
Come on, cut out the assumptions and condescension here. I have done a lot of work in languages with good static type systems. That is why I am interested in Elm.
I've mentioned some of my plans in a few places, mainly here in this subreddit, also a bit on IRC. I haven't written up anything in publicly available document like a blog post or a design doc on github yet. I'm happy to go through some of the details here.
My main inspiration is Elm, which targets the web. It manages to separate the concerns of UI state and representation nicely and it handles keeping the UI consistent with the state efficiently behind the scenes using a "virtual DOM" implementation that basically diffs the new UI representation from the old one and only applies the changes to the actual UI to minimise state changes. This allows the user to keep the majority of their UI logic functional, which greatly simplifies UI programming. I really like its approach to Functional Reactive Programming as well.
So far I have written (but not released) a concurrent implementation of Elm's FRP semantics for Rust that manages to be completely lock-free. I've also written a desktop "virtual DOM" implementation for generic UI applications (hierarchies of "elements"). Now that I have a foundation for good layout calculation I am working on creating UI backends for this system. I'm trying to take a layered, modular, approach so that users can pick and mix the aspects they like. My main goals at the moment are to have a backend that targets accelerated graphics APIs, ideal for games, and hopefully others that target native UI APIs. At the moment I'm focussing on designing an API for UI elements that manages to not limit the use of backend-specific features but still be usable for writing cross-platform(and backend) applications in a uniform manner. There are lessons to be learned here based on existing APIs.
There's Elm which isn't really Haskell, but it's still kind-of Haskell.
I recently got a job doing front and back-end development using AngularJS/Bootstrap on the front and Scala(Play + Slick) on the back-end, at a friend's small consultant company. We have decided that once we have the time and resources, we are going to try Elm for the front-end(and then probably Haskell for the back-end).
Gotta run, but I'll just leave this here:
http://elm-lang.org/blog/Interactive-Programming.elm
I'll say that I think you are right. Also, as much as I love static typing, dynamic can be nice too. But, you proposed something on the internet. So, expect most of the people who bother to respond will be those who disagree. ;p
I just downloaded and ran the wiki binary. I really like the minimalist approach so far!
Some notes:
#
headlines would result in h2
tags, not in h1
(that's already taken by the page name).Keep up the nice work :)
Some people have been recommending looking into some purely functional languages. I can recommend looking at elm (http://elm-lang.org/). It's a purely functional language made for the web, inspired by haskell (a subset plus minor differences), however with the focus on keeping it simple so that anyone can dig in (no explicit functors/monads to worry about)
The problem with “visual” programming languages is, they show something you see anyway but doesn't show things you don't see.
Specifically: they show you the the code but don't show you the data. But there's no point to make a yet another way to show the code in a fancy way. It doesn't make programming any easier. You already know what the code is like. To make programming easier, you should show things you don't see immediately. Like code behavior (how data transforms, for example). Or the project structure (a call graph, for example). That's what visual programming should visualize and that's what it fails to do.
I'll give you a few links for inspiration:
I would agree with Elm as well. On top of it being a simpler functional language, the elm architecture gives them a framework to build up so you don't have to teach them how to layout their code. It also has that "immediate usefulness" factor in that they can build web pages and other things that they would be able to show off to their friends and family, instead of just building terrible command line applications. This will hopefully keep them engaged better.
> friendly compiler
The compiler messages are really quite amazing and this feature on its own would be enough for me to recommend it as it should make the students a lot more self sufficient and stave off frustration. /u/m0d2 check out these two links for examples of elm compiler errors:
http://elm-lang.org/blog/compiler-errors-for-humans
http://elm-lang.org/blog/compilers-as-assistants
> 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
> http://elm-lang.org - "A delightful language for reliable webapps. Generate JavaScript with great performance and no runtime exceptions."
Is it bad that years of webdev experience have made me react to the word "delightful" with an intense desire to punch something?
I think horizontal alignment can often look better, but I don't think it's worth the maintenance overhead. To quote the Elm style guide:
> Changing the name Boolean ever will change the indentation on all subsequent lines. This leads to messy diffs and provides no concrete value.
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.
I am just going to second what yogthos said.
Clojurescript and it's tool's are amazing and fun to work with. I think there are a few reasons...
It has a great community and a lot of room for growth in the language environment. Highly recommend if for no other reason to get a feel for a different way of working in the web.
Also if you like Haskell, Elm is great to experience also though I feel Clojurescript has a large community.
Just throwing it out there, Elm has a neat record system. You can do all the usual haskell stuff along with accessing fields with foo.bar
. It also lets you declare a function that takes any record that contains specific fields, e.g
getNextPosition : {a | position : Vector2, velocity : Vector2} -> (Float, Float) getNextPosition object = (object.position.x + object.velocity.x, object.position.y + object.velocity.y)
I can't wait for them to get that model to a comfortable, powerful situation. As JS paradigms become more and more functional, I become increasingly tempted to leave behind original language altogether and move over to something like more Elm. In time, in time.
> Now how do you imagine a UI framework that doesn't allow mutations?
It's actually pretty easy, if you change your frame of reference.
Instead of having plain old functions, you have functions on time, and sometimes also lists of (time, discrete event) pairs. For example, suppose you want something simple like a particle rotating in a circle. The x position of the particle isn't a point; it's a function that takes the sin of the current time and adds it to the base x position. You want interactivity? Simple! The mouse position, for example, is a function from the current time to the current mouse position, and the keyboard can be a list of (time, key) pairs.
Now, you have a nice immutable description of the scene or UI. Obviously, explicit functions on time are bad because they enable bad things like time traveling (imagine calling yourself with a previous or future time), but it's the underlying idea that libraries like elm are based on.
This is a laudable effort but I feel that is missing the mark.
Best Getting Started with Elm should be a commentary on the syntax of Elm using the Mario example, aimed at a person coming from an imperative world (e.g. python).
The declarative nature of Elm requires quite a paradigm shift. Understanding currying is mandatory to understand
step (dt, keys) = jump keys >> gravity dt >> walk keys >> physics dt
Of course, people with a functional background (e.g. Haskell) would have no trouble but for someone like me it was both scary and wonderful.
"Elm is a functional reactive programming language meant to replace HTML/CSS/JavaScript." http://elm-lang.org/
(fld, txt) = Input.textField "Type here!" main = lift2 above (constant fld) (lift showLen txt) showLen n = text . monospace . toText $ "The string has " ++ show (length n) ++ " characters.
\disclaimer I'm not associated with the project, just trying to make it more accessible
I think there's also a lot to be improved with error messages. Elm has some wonderful error messages (which are becoming an inspiration for other languages):
https://twitter.com/GregorySchier/status/732830868562182144
Elm says farewell to Functional Reactive Programming (FRP).
http://elm-lang.org/blog/farewell-to-frp
TLDR "So is Elm about FRP anymore? No. Those days are over now. Elm is just a functional language that takes concurrency very seriously."
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
Constraints inform design. A designer, no matter what kind, must design something that can be built. An architect doesn't just draw shit that looks cool... she has to draw a thing that at the very least will stand up! An architect understands physics and the costs of materials, labor, etc. (I didn't make it past the article's architect analogy, because gag reflex.)
I've seen designs in PDF that seemed pretty oblivious to the constraints of the browser, network, etc., aka "reality"... that could have been at least as pretty had they been informed by the constraints of the medium. I suspect this kind of oblivion is a consistent source of jankiness all over the modern web. Especially in situations where the designers and coders have no direct line of communication. (Am I the only one who finds that absurd?!)
I'm learning Elm, a very high level language for UI development, and I want to apply it in a tight feedback loop with a designer while undertaking a serious study of UI/UX. I am imagining what it could be like with Elm as the medium, instead of Photoshop or Sketch or whatever.
In other words, I want to sit down with a designer and a stakeholder and live code the artifact directly. I'm not there yet, but near enough to see that it's going to be possible. I'd totally forgive you for being skeptical of the idea. (I know how crazy it sounds.)
But anyway... the browser is the medium. (Not your image editor.)
Maybe check out Elm which compiles a Haskell-y functional language to html/css/js. This is my senior thesis, and I am trying to answer some of your questions :) Keep in mind, it's a work in progress!
Note: I'm going to concentrate specifically on front-end tools, since you mention React, Webpack and Angular.
I believe that all of our "modern" tools are useless without a firm understanding in the basics and how it was done before.
Well, not useless, just that you lose some insight into why these things were made. Front end programming is still very young, and modern web front ends an even younger field.
The modern frameworks are not advanced level tools in my opinion. They're not easier or harder to learn than jQuery or doing manual DOM manipulation (since they basically just introduce a virtual DOM and you interact with that). However, making these frameworks is what I'd call "advanced front-end web programming". Now you start getting into scheduling, transpiling (like {Elm,Typescript,ReasonML,ES6, ...} -> ES5), Functional Reactive Programming (here's Evan Czaplicki's senior thesis on FRP. Evan is the creator of Elm), api design, tooling, developer experience, , how to write good documentation that can cater to beginners as well as advanced users (Imo this is one of the hardest things to do), etc.
What's the difference between either of those frameworks and Miso? Aren't they both based on FRP principles? AFAIK, Elm was strictly FR at the beginning, but eventually broke from it. And Miso is basically a Haskell implementation of Elm. I don't know what the consequences of Elm breaking from FRP were, however, nor how similar Elm was to something like Reflex before it happened.
I will give Haskell credit where it is due, its idea of isolating side effects is in fact a very good one (which unfortunately will not translate to BEAM well as every single message to a node is technically a "side effect") as well as its rich type expression. Both of those eliminate classes of bugs. I also believe Haskell is the only language that can do deterministic concurrency, which can allow you to replicate those super-hard-to-replicate-normally concurrency bugs. Of course, with immutable data structures, you will encounter far fewer concurrency bugs to begin with, so Elixir/Erlang/BEAM still win here over mutable/OO languages.
There is an interesting new language called Elm which compiles down to JS and guarantees no runtime bugs (which is possible to do due to its typed nature and Haskell inspiration). In fact, if you ever get a runtime bug, it's considered a compiler error. This blows my mind!
> 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). :)
If you know PureScript, Elm will be a snap. It's sort of like PureScript-lite, where the standard library includes a nicely simplified, streamlined React-ish thing. The type system is robust enough to keep everything in check but it's simpler than Haskell's or PureScript's, and the higher abstractions are missing or hidden.
I think it strikes a wonderful balance between all the helpful pros of statically-typed pure functional languages (building complex systems out of many small simple easy functions, catching a majority of bugs before they can become a problem, ability to study and work on parts of the program in total isolation from each other, super easy testing) while cutting down on the major con (wrapping your head around things), making it a great entry point for that world. And the debugging experience is fantastic, because having the compiler output helpful messages with clear explanations and explicit advice is one of their primary goals. For just about everything you can do wrong, the compiler will catch it and show you how to fix it, and if it compiles without problems, it's very likely to work.
If it isn't for something serious, but just for learning, then you could go with elm. I made this little snake clone with it once and I'm currently using it for a small infinite runner game. It is very enjoyable to work with, but elm isn't at its best when used for a game.
If you wanna make a real game, go with libgdx/unity/unreal etc.
Elm has frequently been associated with both the statically-typed and fast-feedback paradigms. One of its most famous contributions is a mainstream time-travelling debugger. In fact I think the video in which Evan demonstrates it, with Mario jumping with different gravity settings set on a slider, is the exact point that OP is trying to make.
Try Elm! It's Haskell-inspired, but you never see typeclasses, higher kinded types, or the word "monad." It's intentionally designed for real people who want to build useful things on the web. The talk Let's Be Mainstream: User-focused Design in Elm does a great job of explaining Elm's design philosophy.
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.
> You still have to understand the same things at the end of the day, though
You are, of course, right, but exposing someone to the IO Monad in the first example might be more frightening than this cute little example. :)
I'm actually becoming quite a fan of half indents combined with Elm style. Elm prefers many line breaks, so indenting all your where
and let
lines four spaces, then every line after that, means you move uncomfortably far to the right.
main = let x = "hi" y = "world" in print (join [x, y]) where join = unwords
This almost just looks like 2-space indentation, but I tend to save the 'odd' number of 2-space indents for keywords, to keep actual value terms aligned:
case list of [] -> putStrLn "no list" _ -> let len = length list in print len
(so print
and putStrLn
are aligned)
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.
Definitely check out Elm. It's a functional reactive programming language with an architecture that is conceptually very similar to Flux with a view library similar to React. I'm currently assessing it for use in a medium-large scale production app.
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!
I think this is a very nice example of where Elm is great!
Here is a working version of what you asked for. Just paste it into the online editor and try it out!
If you go through the Elm Architecture Tutorial, it will tell you a lot about what is going on here. Why the code is structured this way, etc.
Evan Czaplicki wrote Elm for his senior thesis.
Elliott Brossard wrote The Elan Programming Language for Field-Programmable Gate Arrays for his senior thesis.
Look at very simple languages like Forth, Lisp and Smalltalk, all of which can be implemented in a few weeks time in Java.
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.
Yep, I'm the author, and thank you! :D Though Elm has academic roots and we do stuff like this, Elm is not a research project: the goal is to make something so useful and accessible that typed FP can finally go mainstream. I'm hoping projects like elm-html will help make it clear that we can do real stuff and do it real fast!
I'm still not understanding your argument. On the one hand you're talking about idiomatic FP. On the other hand you're talking about conventional UI programming. Yes, it is true that OOP is suited to conventional UI programming. However, that does not mean that UI programming is non-idiomatic in an FP language; only that conventional UI programming is.
If you want to see idiomatic UI programming in an FP language, take a look at Elm.
> If you are motivated by pushing the web forward with... JavaScript.
You say this, then you say you want "the ability to learn new languages," "passion for clean, maintainable code," "interest in functional programming," and "strong opinions on software architecture."
So let me give you my strong opinion: given that you're literally the company sponsoring the development of the Elm programming language, this position should be in Elm, not in JavaScript.
EDIT: formatting
The GitHub contains documentation and examples, but for extra reference, here is:
Yes, of course there are modern non-OOP languages.
Idris, for example, is a Haskell-like dependently typed language that was started in 2009.
edit: There's a few other recent Haskell-like languages. For example, [Frege](https://en.wikipedia.org/wiki/Frege_(programming_language\)) is basically Haskell for the JVM and Elm is Haskell for the web (it compiles to html and javascript).
Same:
Actually, right now Elm is syntactically a subset of Haskell. I don't know what syntax Elm has that is not also in Haskell.
The type system is also a subset of Haskell's, meaning that the well-typed programs in Elm are a subset of the well-typed programs in Haskell. Elm does not have the more advanced type stuff such as type classes, but the fundamental stuff is all the same.
Different:
I think the semantic difference is the most important part! Strictness is a good fit for FRP!
The differences start to become more apparent in some of the libraries. The core libraries do not have Data.
prefixes. And very infrequently, there is a library function that does not have exactly the same name (for instance set combining functions are all verbs: union
, intersect
, diff
).
Big difference!
Elm's core libraries include most/all forms of basic input and a bunch of graphics primitives so that you can actually start programming for the web without thinking about HTML/CSS/JS. I want to replace everything, not just JS. Elm lets you do that today.
nice work!
just saw Haskell-style JS:
https://github.com/cies/yesod-js/blob/master/Yesod/Javascript.hs
and
all these "X-style Y" examples where either X or Y is Haskell show something very special about it.
Bien reçu capitaine. C'est mon premier post ici, pardon.
Elm est un langage de programmation (qui compile vers Javascript) permettant de créer des applications web (front-end) déclarativement. C'est un langage fonctionnel pure, extrêmement robuste, et en pleine croissance.
Le but du channel est de rassembler les intéressés, d'échanger, de publier des articles, des questions/réponses, d'aider au recrutement, etc.
Le channel est né hier, alors ne vous attendez pas à une population incroyable dès aujourd'hui, mais il faut bien commencer quelque part!
> > > 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.
Even though it does not produce binaries because it targets the browser, I think Elm Elm is a great way to start. At least it helped me a lot to get into FP.
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?
let decl1 = ..; decl2 = .. in (decl1,decl2)
) which it sends to the server to evaluate and then with the result it updates the display.I've been learning Elm over the past couple weeks to use for the beta implementation of this. This just a throw-away prototype. The real thing will have much more first-class support for rendering data structures visually (lists, vectors, maps, matrices, records, etc.).
In the JavaScript world, there's the Cycle.js framework which provides all of the same benefits of Redux and some of its own. The architectures are pretty different, but they both model state as a function of all past actions.
Also check out Elm. Elm is the direct inspiration for Redux. It isn't JavaScript, but it does compile to JS.
It's worth noting that classes and especially inheritance aren't necessary for SOLID code (and in fact inhibit it). You will have SOLID code for almost free if you write pure functions and avoid state. See Elm, Elixir, etc.
I realize that not everybody is comfortable with writing in a functional style (but look here if you are interested). You don't have to, either. Just don't make everything a class, make sure to understand the difference between classes and types, and avoid inheritance. Keep it simple.
It's good to remember this as many of the JS frameworks popping up lately (especially Angular 2) are making literally everything a class, even if it's a computation, just like Java.
I think I read somewhere that the lengthy startup time is due to Clojure, not the JVM.
The awful stack traces are a really big sticking point - Elm is so much nicer in that respect: http://elm-lang.org/blog/compiler-errors-for-humans
React.js gives me some hope that JS won't be hell forever. I've been enjoying it so far.
In general, as a python coder, I kind of expect to be pulling my hair out every time I get involved with any javascript. So React has been sort of nice, but still, because the history of JS is just so fucking bizarre there's only so much that can be done to help it. Just think of the amount of work devoted to building tools that generate JS so you don't have to write it (compile-to and superset languages, transpilers, etc.) And the "resurrection" somewhere around 2006 with node.js! What other language has had that!
I've been very curious about Elm but it's still too niche. (I'm hesitant to even write that for fear of contributing to its niche status.) IMO we need more stuff like Elm, then maybe eventually the browsers will pick them up natively and we can finally put the computing world's biggest collective clusterfuck to rest.
Edit: add link
Yes I know, new languages can compile to this binary target. We could even generate dynamic DOM programmatically and "get rid" of the html/css part. But it will still be html/css bellow, I am aiming for a new way to do web development.
The fragmented ecosystem we use today was born out of necessity. I think that with all the knowledge we have now we could recreate it better
.
Edit:
Elm is a good inspiration http://elm-lang.org/examples/pong
I was using Control.Concurrent.Chan
to implement section 4.4 of my thesis in Haskell. With the basic library, everything goes through, no computations occur, everything synchronizes at the end. This means putting computations on different threads did not actually say anything about when those computations happen, which was the whole point. This was not a viable path for me.
I then looked into Control.Concurrent.Chan.Strict
but that relies on on deepseq
which does a full crawl over a data structure. Say you are passing a large record around and it goes through a couple channels. It has a bunch of fields, holding long lists or large dictionaries. With deepseq you are crawling the entire data structure on every channel for no reason. This turns send
from O(1) to O(N) in the size of the value being sent across.
Neither option here was viable as far as I could tell. Maybe I could have tried harder and figured out some other tricks, but I could also use a strict language and not have these problems.
>Live coding is finally here
So, basically what Light Table has been doing for the past year?
There's also ClojureScript Figwheel, and Elm, welcome to the party MS. :)
The why is fairly complex. Anyone could make a programming language, so it's mostly a case of someone being motivated to do so. Common reasons include: trying a new paradigm/concept as a research project, (e.g. Elm, finding things to be inefficiently expressed in existing languages or simply because of political/pseudo-technical reasons (e.g. I'd say Swift does not add much to the landscape of languages).
The how of it is fairly easy though, on a very high level. (It gets difficult very fast when looking at the details though.) Basically, all you need to do is write a program in an existing language which tells your computer how to handle your new language. You'll need to make rules for your new language and convert what your language expresses into something your computer can already understand.
A simple example, Dogescript is just a silly language made for the fun of it. It compiles to JavaScript, which simply means any Dogescript code is converted into an equivalent JavaScript code.
My personal recommendation then is to start with Elm. It is quite haskellish, and I had very good experiences with it as a gateway drug. :) The very simple examples and the awesome community helped me a lot in having a pleasant start.
Don't Bore Us, Get to the Chorus!
In order for a kid to learn a system, he has to do something very interesting, very fast with that system. Games can be fun.
For me it was the BGI interface in Turbo Pascal. For my kid brother, almost 20 years later, it was pyGame.
The recipe is the same. Give kids better abstractions, better tools.
The kids today don't live in the world of the text-based user interfaces we saw 30 years ago. They live in a media rich, interconnected world. They will not see magic in "print 1+1" but they will see magic in writing text to program a rich multi-media world where their program can interact with other programs.
tl;dr: Not yet. The compiler and language are still pretty alpha (bad error message, limited set of language features, etc.), so I was planning on doing a release when the implementation settles down.
I am also doing my senior thesis on Elm's underlying FRP model. The thesis is my number one priority right now, so it will be a while before I can devote enough time to making a legitimate release. This is probably for the best as much work remains to be done on the language itself!
In case your curious, this is my tentative idea of how to release an Elm compiler at some point in the future: Given a directory tree of Elm files and media files (images, videos, markdown?, etc.), the compiler produces a server. In dev mode, you get a server on localhost that is actively updated as you make changes. This is pretty much how I develop elm-lang.org, and it is really pleasant. I think this also makes it really easy to install, develop, and deploy websites. Does this sound reasonable?
Edit - temporary solution: use the online compiler, compile to new tab, save html (and required js sources). I know this is not ideal, but that will work because the examples are hitting the full compiler. I'll PM you if I make this process more formal (i.e. an export button or something).
It seems that your comment contains 1 or more links that are hard to tap for mobile users. I will extend those so they're easier for our sausage fingers to click!
Here is link number 1 - Previous text "Elm"
^Please ^PM ^/u/eganwall ^with ^issues ^or ^feedback! ^| ^Delete
Wish granted: http://elm-lang.org/
It claims no run time exceptions in practise, and that claim really holds from my experience. (There are still some ways to produce run time errors, but they don't just happen in practise)
"If it compiles, it works" has been promised many times, but with elm it is actually true.
FRP is just one model. Elm is a good example of how to make web applications with simple pure functional code that doesn't mention FRP concepts like signals, streams or behaviors.
To some degree, you can also make games with Elm. However, since Elm produces HTML, there's no model for collision detection and response, or anything like that, so you'd have to write a lot of code to handle that. One could imagine an "Elm for games" that produced a 3D scene graph instead, where you could listen for collisions in the same manner you can listen for clicks in Elm.
For Scala, see the side bar for a list of libraries. I maintain a React-based library, React4s, that comes with support for writing purely functional webapps.
> 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.
Elm isn't a bad first language to learn. In fact, not having the baggage of other languages might help one learn Elm faster. I highly recommend frontendmasters.com course on Elm, as well as https://guide.elm-lang.org/ and http://elm-lang.org/examples
Sure, no worries!
No side effects is a good thing to some people. Other people look at that see it as too constrictive: Clojure is a "functional" language but it allows arbitrary side effects so you can put println
statements or spit wherever you want in your code. Clojure in this case is not a "totally pure" language, even though it encourages mostly pure functions.
However in Haskell, you can't just print or write to the filesystem whenever you want because it is a totally pure language. Any printing or reading/writing to the filesystem has to happen through the IO monad.
(FWIW If you are learning functional programming I would recommend not starting with the IO monad, it's really difficult and it still trips me up quite a lot. Start with something like Elm or Clojure or Scheme for a softer introduction.)
Haskell has a very advanced type system and can be compiled to JavaScript with GHCJS. It also has reflex-dom, a FRP framework for web development. The main problem is that GHCJS generates huge amounts of output that doesn't perform very well. There are also two languages derived from Haskell that were created specifically for web development, Elm and PureScript, but I've never tried them.
I think you're getting hung up on Union Types
. Consider the Maybe union type.
type Maybe sometype = Just sometype | Nothing
The lowercase sometype
is a placeholder (it's parameterization?) for any type.
What this means is I can declare a variable that is a Maybe String
, for example.
myVar : Maybe String myVar = Just "Hello World"
To learn more about union types look at these docs.
Back to your question..
div : List (Attribute msg) -> List (Html msg) -> Html msg
This is saying div
is a function with two parameters. The first is a List of Attributes (which is a parameterized union type). The second is a List of Html (another parameterized union type but the parameterized type is the same as Attribute). And the return value is similar.
msg
is simply literally any type that you want it to be. It's called msg
firstly because it has to be lowercase and secondly by convention Elm applications call the "actions" in the app Msg
.
Here's an example: http://elm-lang.org/examples/buttons
I hope that helps
> If there is a type error or parse error in your code generator you are probably in the process or writing it, so you should be able to spot where that came from.
It's not enough to know that there is an error in the code that I just wrote. I also need to know why there is an error. A good type system explains clearly what you did wrong and suggests how to fix it
Here's one very specific use case: web app middleware. It's really useful to keep a 'context' of all the data attached to a single request as it passes through layers of middleware and handlers. Many languages are either dynamically typed (so there's no way of knowing for sure what's in the context at any given moment) or encourage you to use dynamically-typed capabilities (Go's Context
).
I've always wanted to be able to, for example, write middleware that specifies in its type "adds a SignedInUser
to the context", and write a handler that says "I need a SignedInUser
in the context". You could do this with a non-extensible record full of Maybe x
s, which is certainly more type-safe than 'throw it all in a map[interface{}]interface{}
', but doesn't capture all the statically-available information it could.
Spock actually does this, but in a way I don't find as clear as it could be. (I'm sure Servant can do it, too, but I haven't looked into it.) Elm used to have extensible records that would be perfect for this use case, but a) it's not a server language and b) the record extension syntax was removed IIRC.
EDIT: actually it seems you can update records in Elm, which includes adding fields or changing their type.
EDIT: I wrote
> dynamically typed (so there's no way of knowing for sure what's in the context at any given moment)
But it's more accurate to say "there's no way of knowing statically what's in the context".
There is also a little trendiness at play. I think over the past few years the rise of Lodash and Underscore introduced the idea of FP to tons of new people. I think FP and languages that focus on it will be the preferred flavors of JS in the future.
Elm - for instance - it my absolute favorite framework right now.
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.
> # How should I think of messages (Msgs)?
The messages are elements of a tagged union. Read a little bit on the Algebraic data types and you will be good to go. The types are like 80% of Elm so, once you get this you get a huge chunk of Elm. :)
> # Why don't I need to explicitly call update?
Because The Elm Architecture became the only way to do things in Elm. Prior to 0.17 you could build your own reactive signal tree and The Elm Architecture was only one of the many ways you would structure that tree. With 0.17, things got tremendously simplified. So, if you use something that has messages generation (event handlers), you need to use one of the program
functions that receive a record describing including the update
function. These functions take care of the wiring. Also, the Html.Events functions produce Attribute msg
. Think of these are "facts about your desired behavior". These facts will then be used by the runtime to create and properly mount the event handlers that will deliver the provided msg
to the proper place that will allow the updating of the model. This is not something magical, if you want to understand the old way you could take a quick look at the way the old StartApp.Simple was implemented. It's only a few lines of code. All that Signal and Addresses were removed from the language and their functionality moved into the runtime.