Code Monkey home page Code Monkey logo

the-elmish-book's Introduction

The Elmish Book

The Elmish Book is a practical guide to building modern and reliable web applications in F# from first principles. We will be using the Fable compiler, which will take our F# code and turn it into JavaScript. This allows our code to run anywhere JavaScript runs, whether it is the browser, Node.js, or other runtimes. Fable is designed with interoperability in mind, which makes it simple to re-use and integrate with the vast ecosystem of JavaScript libraries, as we will see later on in the book.

Our primary focus will be building client applications for the browser. We will start by learning the development workflow around client applications, slowly understanding the tooling and the hybrid nature of Fable projects since we will be both using .NET and Node.js tools for development.

Using the Elmish library, we will build and design our applications following The Elm Architecture: A beautiful pattern for making genuinely modular user interfaces as popularized by the Elm programming language. We will spend a significant portion of the book talking about, understanding, and building applications that follow this architecture starting from scratch until it becomes second nature to the reader, hence the name of this book.

The premise of The Elm Architecture is the ability to build robust and reliable applications: applications that don't fail or break easily. Building a stable structure requires identifying the failure points of that structure and accounting for them. When it comes to web applications, many problems come down to the correct handling of data and syncing it with the user interface. Data can have many failure points, whether it is a failure when being retrieved, a failure when being processed from one form to another, or failure when assuming the data to be available and using it when in fact, it is not. To account for these problems, we will spend a lot of time discussing data modeling and ways to encode the data using types with the help of F#'s powerful type-system while having the compiler at our backs.

The pacing of the book is deliberately slow because learning front-end development can often be overwhelming. That is why each chapter is divided into bite-sized sections that are hopefully easy to understand on their own. These sections include working small samples to demonstrate the various concepts. As you progress through the book, the concepts start to become more apparent as we keep expanding upon the things we learn along the way.

Some parts of the book are opinionated and do not necessarily follow the tutorials and guidelines you have potentially read before. However, this is not to say that you should follow my advice and forget what you already know, it is the opposite: my goal is that you learn a lot and gain more experience to draw your conclusions and understand why one approach is better than the other. That is why I will try my best to explain my train of thought when going through the examples and the way they are implemented.

the-elmish-book's People

Contributors

aspnetde avatar benniecopeland avatar bzuu avatar dawedawe avatar dougferg avatar duebbers avatar eferfolja avatar l3m avatar mangelmaxime avatar markpattison avatar mhmd-azeez avatar mjarosie avatar nabeelvalley avatar nilshelmig avatar nordes avatar omanf avatar pbryon avatar quintusm avatar robmaw avatar rommsen avatar samme78 avatar samuel-dufour avatar spritefullake avatar sumeetdas avatar theimowski avatar thisfunctionaltom avatar vbfox avatar vitalybrusentsev avatar voroninp avatar zaid-ajaj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

the-elmish-book's Issues

Peaked vs. piqued

In the React in Elmish page, the line:
At this point, this render function has probably peaked your interest

should probably be:
At this point, this render function has probably piqued your interest

(Bold and italic to highlight change)
[label:typo]

Missing prop.className overload: (bool * string) list

According to the page Using CSS, section Conditional classes, there is supposed to be an overload for prop.className with an input parameter of type: (bool * string) list.

I checked Feliz/Properties.fs, there is no such overload.

hello world section: "starter template"

The hello world section first talks about fable-getting-started repository, but then it says " you can clone the starter template repository from github and compile the whole project"

It's a bit misleading - were you referring to the first repository instead?

For .NET 5 preview and F# 5 Async.Sleep now has an overload

So Delayed Increments section leads to the error:

A unique overload for method 'Sleep' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a

Candidates:

  • static member Async.Sleep : dueTime:System.TimeSpan -> Async
  • static member Async.Sleep : millisecondsDueTime:int -> Async

Now it should be do! Async.Sleep (ms: int) instead of do! Async.Sleep ms
or
let runAfter (ms: int) callback = instead of let runAfter ms callback =

Running `npm run build` for Hello-World Requires Webpack to Be Installed

tldr;

More of an FYI for someone who is working the the first example, I got some webpack errors which I was able to resolve. It might be worth adding an FYI box to let people know they might need to separately install webpack to get the first example working. Especially if they're new to node/F# it might throw them for a loop.

To get working I ran:

npm install -g webpack and npm install -g webpack-cli.

Full repo

I was working my way through your Fable Hello-World example. I cloned the repo, ran npm install, then when I ran npm run build I got the following error:

C:\dev\elmish_book\fable-getting-started [master ≡ +1 ~0 -0 !]> npm run build

> webpack

'webpack' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ build: `webpack`
npm ERR! Exit status 1
npm ERR! Failed at the @ build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\morga\AppData\Roaming\npm-cache\_logs\2020-06-13T02_09_59_881Z-debug.log

Which I ran npm install -g webpack to install then, then ran into an issue with webpack cli:

C:\dev\elmish_book\fable-getting-started [master ≡ +1 ~0 -0 !]> npm run build

> @ build C:\dev\elmish_book\fable-getting-started
> webpack

One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:
 - webpack-cli (https://github.com/webpack/webpack-cli)
   The original webpack full-featured CLI.
We will use "npm" to install the CLI via "npm install -D".
Do you want to install 'webpack-cli' (yes/no): y
Installing 'webpack-cli' (running 'npm install -D webpack-cli')...
+ [email protected]
updated 2 packages and audited 651 packages in 4.194s
found 16 vulnerabilities (15 low, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details
Error: Cannot find module 'webpack-cli'
Require stack:
- C:\Users\morga\AppData\Roaming\npm\node_modules\webpack\bin\webpack.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:797:15)
    at Function.Module._load (internal/modules/cjs/loader.js:690:27)
    at Module.require (internal/modules/cjs/loader.js:852:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at C:\Users\morga\AppData\Roaming\npm\node_modules\webpack\bin\webpack.js:143:5
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  requireStack: [
    'C:\\Users\\morga\\AppData\\Roaming\\npm\\node_modules\\webpack\\bin\\webpack.js'
  ]
}
npm ERR! code ELIFECYCLE
npm ERR! @ build: `webpack`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\morga\AppData\Roaming\npm-cache\_logs\2020-06-13T02_12_07_588Z-debug.log

And to fix that I ran npm install -g webpack-cli.

Links to exercise solution are dead

The link to the solution of the todo app is broken, leading to 404.
I assume but have not verified, the other exercise link is also dead.

Maybe because it leads to ...github.io/...? I don't know, only guessing.

I am not fond of the Program.mkSimple

Disclaimer:

  • I am only at the elm/counter example.
  • I am just trying to share my opinion and my experience when first learning TEA

Hello,

when I first learned the Elm architecture my main pain point has always been to move from mkSimple to mkProgram. And this had me stuck for a really good moment and draw me back 5-7 times before I finally forced myself to move on; non-surprisingly by using a code which used directly mkProgram. It took me almost three months to be able to understand this new concept.

The reason is that when you start to want to add Cmd then the errors coming from the compiler are really really hard to understand when it's your first time in a functional language (sometimes even if it is not).

I don't know yet how you are going to make the transition from mkSimple to mkProgram but in all the tutorials I read until now, it was never clear to me.

Another reason I don't like mkSimple is that I don't see a "real" world application working without commands and IHMO we should just have it deleted from Elmish core :).

If I take my first user experience with TEA, I think it would have made things much simpler if the tutorial just said: "Don't bother with Cmd.none for now".

The Elm architecture vs MVU

As far as I see the fable/elmish community embraced Model View Update (MVU) instead of "The Elm architecture". I would suggest to also use this term (of course still giving credit to Elm). Will make it easier to google or reference it later on. If you dont want to do it I would suggest to at least mention it.

Furthermore you decided for "render" instead of "view". Any specific reasons for this?

Placement of advanced content

It's really great to have the advanced (compat, fable packages, bindings, etc.) sections in the book, however I'm wondering if it'd be better to place them a bit further in the book - a beginner reader would likely follow chapter by chapter, and those advanced topics might be overwhelming. I've seen the note about advanced sections in ToC, but still thinking out loud if it'd be better to have them later in the course

Order of values inconsistent in todo list application parts

In part 1 of the todo list application the State record is defined as:

type State = {
    TodoList : string list
    NewTodo : string
}

then in part 2 the properties are suddenly flipped around:

type State = {
  NewTodo: string
  TodoList : Todo list
}

This is somewhat confusing and it breaks the init() function.

I'd be happy to submit a pull request with a fix, but not sure which part(s) you'd prefer to be rewritten/reordered. I guess rewriting part 1 would be easiest.

Broken Link

At the end of the chapter scaling/introducing-url-type there is a reference to a page Routing With Login which is not found. I guess it is still not written?

Rewrite HTTP

Assume readers know some HTTP and explain examples in terms of webpack dev server as a static file server

Remove explanation of obvious things like "HTTP request has a method"

Remove examples and explanation of Fable.SimpleJson

Now that I am re-reading a lot of this, the mentioning of Fable.SimpleJson feels so extra, jarring and overall not very useful. I think I will remove the examples and comparison to better focus on Thoth.Json and only mention that Fable.SimpleJson exists and it most suitable for infrastructure and libraries

Not an Issue, but a guide to convert to epub

It's not perfect, but for those who want'S to read it on a e-ink reader or something. M;aybe that helps.

  1. download pandoc (https://pandoc.org/)

  2. convert all images in the md-files to a proper md-format (I used notpad++)
    replace in all files:

    the images-tags
    (<resolved-image source=")(.*)(" />) to ![.$2]\(.$2\)

    the highlight-tags inside the code blocks
    \{highlight: \[.*\]\} to (empty-string)
    \{ highlight: \[.*\]\ } to (empty-string)
    \{\s*highlight:\s*\[.*\]\s*\} to (empty-string)

  3. use following script (state: 2020-03-18) (cmd for windows - sorry guys)

REM Please adjust the path for pandoc if needed

"C:\Program Files\Pandoc\pandoc" ^
-o the-elmisch-book.epub ^
.\title.txt ^
.\ReadMe.md ^
.\chapters\audience.md ^
.\chapters\overview.md ^
.\chapters\planned-chapters.md ^
.\chapters\contributing.md ^
.\chapters\acknowledgment.md ^
.\license.md ^
.\chapters\fable\readme.md ^
.\chapters\fable\hello-world.md ^
.\chapters\fable\development-mode.md ^
.\chapters\fable\counter.md ^
.\chapters\fable\observations.md ^
.\chapters\fable\compatibility.md ^
.\chapters\fable\fable-packages.md ^
.\chapters\fable\fable-bindings.md ^
.\chapters\fable\node-packages.md ^
.\chapters\fable\how-fable-works.md ^
.\chapters\elm\readme.md ^
.\chapters\elm\the-architecture.md ^
.\chapters\elm\counter.md ^
.\chapters\elm\render-html.md ^
.\chapters\elm\conditional-rendering.md ^
.\chapters\elm\using-css.md ^
.\chapters\elm\form-inputs.md ^
.\chapters\elm\react-in-elmish.md ^
.\chapters\elm\todo-app.md ^
.\chapters\elm\todo-app-part1.md ^
.\chapters\elm\todo-app-part2.md ^
.\chapters\elm\todo-app-part3.md ^
.\chapters\elm\todo-app-exercises.md ^
.\chapters\elm\project-structure.md ^
.\chapters\commands\readme.md ^
.\chapters\commands\commands.md ^
.\chapters\commands\definition.md ^
.\chapters\commands\async-updates.md ^
.\chapters\commands\async-to-cmd.md ^
.\chapters\commands\failing-async.md ^
.\chapters\commands\async-state.md ^
.\chapters\commands\deferred-module-utilities.md ^
.\chapters\commands\recursive-updates.md ^
.\chapters\commands\async-recursive-updates.md ^
.\chapters\commands\http.md ^
.\chapters\commands\xhr-elmish.md ^
.\chapters\commands\async-xhr.md ^
.\chapters\commands\working-with-json.md ^
.\chapters\commands\using-json.md ^
.\chapters\commands\elmish-hackernews.md ^
.\chapters\commands\elmish-hackernews-part1.md ^
.\chapters\commands\elmish-hackernews-part2.md ^
.\chapters\commands\elmish-hackernews-part3.md ^
.\chapters\commands\elmish-hackernews-exercises.md ^
.\chapters\scaling\readme.md ^
.\chapters\scaling\pages-as-programs.md ^
.\chapters\scaling\splitting-programs.md ^
.\chapters\scaling\integrating-commands.md ^
.\chapters\scaling\composition-forms.md ^
.\chapters\scaling\understanding-data-communication.md ^
.\chapters\scaling\intent.md ^
.\chapters\scaling\routing.md ^
.\chapters\scaling\parsing-url-segments.md ^
.\chapters\scaling\parsing-date-segments.md ^
.\chapters\scaling\programmatic-navigation.md ^
.\chapters\scaling\introducing-url-type.md ^
.\chapters\scaling\modelling-nested-routes.md ^
.\chapters\scaling\multi-page-routing.md ^
.\chapters\dev-flow\readme.md ^
.\chapters\dev-flow\webpack-mode.md ^
.\chapters\dev-flow\compiler-directives.md ^
.\chapters\dev-flow\configuration-variables.md ^
.\chapters\dev-flow\hot-module-replacement.md ^
.\chapters\dev-flow\understanding-webpack-loaders.md ^
.\chapters\dev-flow\static-images.md ^
.\chapters\dev-flow\styling-with-sass.md ^
.\chapters\dev-flow\introducing-femto.md

Update: had to adjust the highlight replace regex

Mention built-in commands in the Cmd module

The third chapter 3 hand-waves its way around built-in commands and instead defines its own commands Cmd.fromAsync that is used in the rest of the chapter. The chapter should give a note on why we are building our own commands instead of using built-in ones

  • To better understand commands (not just a black box)
  • Because built-in commands have "weird" conventions and namings that don't make sense for me

FontAwesome icons not showing

I updated the index.html file with the style sheet from To-Do List Application (the intro section), to make sure I'm not making any typos I copy-pasted the code snippets from Part 1, ran it and... everything works correctly, functionality-wise, but the + sign is not showing.

More interesting, when inspecting the code, I see the DOM node, , which indeed has the classes "fa" and "fa-plus", but no actual icon in the GUI.

This is true on (the latest) Firefox, Chrom, and Chromium on Linux.

Simplify webpack sample config

Maybe the webpack configuration shown should be simplified. This part specifically :

 var path = require("path");
 
 module.exports = {
     mode: "development",
     entry: "./src/App.fsproj",
-    output: {
-        path: path.join(__dirname, "./public"),
-        filename: "bundle.js",
-    },
-    devServer: {
-        contentBase: "./public",
-        port: 8080,
-    },
     module: {
         rules: [{
             test: /\.fs(x|proj)?$/,
             use: "fable-loader"
         }]
     }
 }

Webpack since v4 has a zero configuration mode with good defaults for most options. We can't be fully 0 conf as we need the F# module but we can get a simpler config.

Output by default is in ./dist and the dev server already serve the output folder on 8080 for example.

This will give less things to look at for people starting up and also unify Fable projects with the rest of the javascript ecosystem that is standardizing on these values.

Delay introduction to Emit instruction

On this page, you are using [<Emit(..)>] in one of the snippet.

Perhaps, we should avoid showing this code that early and prefers to the DOM API. The DOM API was introduced in the previous chapter.

Missing some information in developement mode

In /chapters/fable/development-mode there is a good explanation of the dev server but the page reference package.json run scripts instead of the webpack commands (Or explaining where the link come from)

It result in a weird situation as the link between npm build or npm start and webpack is magic and could lead people to think it's something natural to npm and not a configuration specific to the sample project.

Idea: Add a section about i18n

We're currently using a homegrown approach for i18n in our Elmish application.

I would be interested in best practices for the support of multiple languages.

Inconsistent Msg for NewTodo between todo part 1 and 2

In the Todo Part 1, we can see AddTodo while in the part 2 we see AddNewTodo. Probably, it would be better to stay consistent in order for someone to pass from part 1 to part 2. Personally Add and New seems pretty much similar and AddTodo makes more sense.

Also, at the beginning of the part 2, we can see clearly that it is still AddTodo in the scenario, but not in the code sample later in the page.

https://zaid-ajaj.github.io/the-elmish-book/#/chapters/elm/todo-app-part1
https://zaid-ajaj.github.io/the-elmish-book/#/chapters/elm/todo-app-part2

Incorrect location for index.html referenced

In the Counter with Elmish page, you refer to the following location for index.html :

For part (1), lets examine public/index.html, we will see the placeholder element that will be replaced by the application when it is bootstrapped.

I think this should be 'examine dist/index.html...'

[label:typo]

Do higher versions of nugets used in the project contain breaking changes (WRT the project, of course)?

First of all, I obviously understand the notion of package locks and why they're there.
That said, I always like having my projects using the latest working version of as many dependencies as possible.

I'm following the book along, and have coded the examples in Elmish Hackernews (Pt. 1).
Not getting any compilation errors, comparing with the reference code (linked at the end of the chapter looks the same).

When the page loads I do get the spinner, but then, after all the stories have been downloaded and parsed, I get nothing on the screen. Empty.
Inspecting the browser, it's not that I have something white-on-white... the HTML is the header tag and the script tag for main.js.
Nothing got loaded, though the networking tab of the developer tools show that the stories are all 200.

Then I run the reference code and, lo and behold, all stories are there with neat boxes and all.

The difference is that, as a learning experience, I'm using Paket to manage the pulled dependencies, and that I don't lock the pulled Nugets to a specific version, but rather the latest.
I also bumped all Node.js dependencies (on the package.json file) to the highest version they have on NPM.

Considering all this, I'm guessing at least one dependency, be it JS or F#, has some breaking change that makes the display broken.

Does that sound correct or should I look at what I'm implementing wrong?

Thanks.

Pointing lines

There are a few places in the book where you point line numbers in code samples, but none of the code samples have line numbers displayed. At least the samples where line numbers are referenced should show them.

image

Where does the state value come from?

Hi Zaid,

In the section Modelling nested routes >> Passing URLs to child programs there is a value state that I'm not sure where it came from:

// App.fs
let init() =
  let currentUrl = parseUrl(Router.currentUrl())
  match currentUrl with
  | Url.User userUrl ->
      let (userState, userCmd) = User.init userUrl
      { state with
          CurrentUrl = currentUrl
          CurrentPage = Page.User userState }, Cmd.map UserMsg userCmd
  // ...

Peeking at the next chapter I saw that you initialized a defaultState inside init(), is this what you are doing here?

Route.Query error in examples

Route.Query should to expand query string parameters into a (string * string) list, but in the chapter "Parsing Date Segments" all examples have a semicolon instead of a comma:
[ "orders"; "filter"; Route.Query [ "from"; dateSegment ] ]

let activePage =
  match state.CurrentUrl with
  | [ "visitors"; "report"; dateSegment ] ->
      match dateSegment.Split '-' with
      | [| Route.Int day; Route.Int month; Route.Int year |] ->
          match Date.create { day = day; month = month; year = year } with
          | Some date -> Html.h1 "Show visitors report"
          | None -> Html.h1 "Not Found"
      | _ ->
        Html.h1 "Not Found"

  | [ "orders"; "filter"; Route.Query [ "from"; dateSegment ] ] ->
      match dateSegment.Split '-' with
      | [| Route.Int day; Route.Int month; Route.Int year |] ->
          match Date.create { day = day; month = month; year = year } with
          | Some date -> Html.h1 "Show filtered orders"
          | None -> Html.h1 "Not Found"
      | _ ->
        Html.h1 "Not Found"

  | _ ->
    Html.h1 "Not Found"

and so on..

Sorry for my English

Ideas for the application to build at the end of chapter 3

For chapter 2, I built a To-Do list application in three different parts, adding more features as I went and was able to make nice exercises for it. I would like to do the same for chapter 3 and end it with an application that will solidify the discussed theory during the chapter.

My current idea is to cover the JSON stuff and then build a Hackernews application since we don't need a backend to work with for now. I am still thinking about how to split it up in multiple sections /features the same way I did for the To-Do list application, let alone make exercises for it so if you have suggestions and ideas for example applications, please share them here 🙏

Feliz

I feel that the "Rendering HTML" chapter should state clearly at the top that the Feliz syntax is different from the normal one and that's why the code that follow will differ from all other samples that can be found around the web.

(Obviously this is if the book is published before Feliz become the main view DSL in fable and take over the world)

Clarification about the SetTextInput example in form-inputs.md.

Are you accepting questions here as GitHub issues?

The following text appears in the-elmish-book\chapters\elm\form-inputs.md. It is in the context of a code sample which copies input text from an input element to an adjacent span element.

We should mention here that even when the UI is re-rendered, the input box element preserves the text that has been entered. We didn't tell the input element that it should use state.TextInput but still with each render cycle, the text is kept as it is. This makes sense because if it did reset the internal state with every cycle, then the text box would be cleared after each keyboard stroke which is not exactly what your users would be expecting.

This happens because HTML input elements such as a text box keep track of an internal state of their own so we don't have to tell the input box what text it should have now.

I am trying to understand this more clearly. The render function is called after every call to the update function, correct? Surely the generated JavaScript is not instantiating new HTML elements after every call to the update function. Or does it? I would have expected that some kind of React binding mechanism is being used under-the-hood. However, that seems inconsistent with calling the render function after every update. Instead, is there some kind of diff going on between the previous rendering and the next rendering that "manually" updates the elements based on changes? If "conditional rendering" inside the render function were to place the input box at a different place in the HTML hierarchy, would that result in a new text box instance? and a resulting loss of the previous text box's internal state?

Suggestion on Modelling Async State Page

This is very minor, but you might want to change the order of your operations in the F# code to match the text written below it.

The f# code is
type Msg =
// messages for Operation 1 -> might fail
| StartOperationOne
| FinishOperationOneSuccessfully of ResultOfOne
| FinishOperationOneWithError of exn
// messages for Operation 2 -> always succeeds
| StartOperationTwo
| FinishOperationTwo of ResultOfTwo

and the text below says:
(1) Operations that always succeed (for example, a delay)
(2) Operations that fail

It might be better to change the Messages to reflect the order in which you discuss them in the text.
type Msg =
// messages for Operation 1 -> might fail
| StartOperationOne
| FinishOperationOne of ResultOfOne`
// messages for Operation 1 -> always succeeds
| StartOperationTwo
| FinishOperationTwoSuccessfully of ResultOfTwo
| FinishOperationTwoWithError of exn

Using Fulma with Feliz?

in todo-app-exercises chapter there's this:

image

It's confusing since you changed from prop.text to str
The question that arises is whether you can combine Fulma with Feliz so that you don't need to drop Feliz helpers?
If not then it'd be good to add explanation on why not

Mention the opinionatedness of the book

If you have read the content so far, you know the book is kind of opinionated, this is why it is book that discusses different approaches to different problems and not just documentation on how to do things. Also this is why the pacing is so slow. The idea behind this, is that the reader should gain enough knowledge to draw his or her own conclusions from it and not necessarily follow my guidelines for building applications

Who is actually compiling Fable?

What is missing in the awesome fable documentation is who is actually compiling Fable. You mention that it is the fable-compiler package referenced in package.json. This sounds as if everything is done by Javascript. Is there any F# tooling involved. When is the F# deamon started, what is it doing?

React component and optimization best practices in general

I was expecting the chapter about react to go deeper into the optimizations possible with using memo and components in general (Well ok maybe it's because it's me). With maybe an introduction to the React dev tools.

I was also expecting key in the react todo list example, as it's introduced pretty late it would be a perfect place to show ofList, key and a few components for each part of the view.

Section: elm>conditional-rendering about yield statement at the end

Hi Zaid, thank you for your work.

In the page https://zaid-ajaj.github.io/the-elmish-book/#/chapters/elm/conditional-rendering you mention that the yield keyword will become implicit. The link point to one of the issue, but it is now been implemented in dotnet/fsharp#6806

The only downside of this approach is that all other elements need to be yielded as well. Because this pattern is used a lot in Fable/F# projects, there are discussions of making yield implicit in the coming versions of F#, see F# RFC FS-1069 - Implicit yields .

Mismatch between code snippets in 'To-Do List Application: Part 2'

In the section Modelling the State, the type is defined as below:

...
type State = {
  NewTodo: string
  TodoList : Todo list
}

However in the Implementing State Updates section, the field has changed from NewTodo to NewTodoDescription

let update msg state =
  match msg with
  | SetNewTodo desc ->
      { state with NewTodoDescription = desc }

Please advise which is correct, and I can make the updates in the documentation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.