Giter Site home page Giter Site logo

purescript-contrib / purescript-book Goto Github PK

View Code? Open in Web Editor NEW

This project forked from paf31/purescript-book

346.0 346.0 189.0 15.14 MB

Sources for the PureScript book

Home Page: https://book.purescript.org/

HTML 0.64% JavaScript 2.75% PureScript 91.64% Dhall 4.07% Shell 0.90%

purescript-book's People

Contributors

cblp avatar chriz-zeller avatar dvail avatar dwhitney avatar emiel avatar franklinchen avatar gemmaro avatar gomain avatar hdgarrood avatar j-wenning avatar jbrains avatar jordanmartinez avatar keithlayne avatar klarkc avatar marcellourbani avatar milesfrain avatar mstream avatar ntwilson avatar oldfartdeveloper avatar othelarian avatar paf31 avatar pete-murphy avatar rabraham avatar s0kil avatar shaunplee avatar tssm avatar ursi avatar vlkrs avatar vmpstr avatar zelenya 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  avatar  avatar  avatar  avatar

purescript-book's Issues

Add tests for exercises

PRs for adding tests:

Open:

Complete:

Skipping:

  • ch9 #111 - not many of the canvas exercises are easy to test

Contributing:
We could use help with adding tests for the other chapters, so please feel free to assign yourself to any of the open PRs.

Reorganize chapter sequence

Proposing swapping Ch9 "Canvas Graphics" with Ch12 "Callback Hell" (to be rewritten as "Asynchronous Effects").

Ch10 covers async FFI, so it would be good to cover the async prerequisite in Ch9.

Will make this change once #27 and #29 are complete.

Example in Chapter 4 has warnings

In the follow example:

length' :: forall a. Array a -> Int
length' arr = length arr 0
  where
    length :: forall a. Array a -> Int -> Int
    length arr acc =
      if null arr
        then 0
        else length (fromMaybe [] $ tail arr) acc + 1

The two variables a and arr in length shadow declarations from length'. It might be good to call this out in the text.

Ch10 Add more details on FFI with effects

@paluh created a guide on this topic, and this material would be great to include in Ch10. I may get around to this after #57 is merged.

Some notes on content:

  • EffectFn1 is new and useful material
  • It's likely clearer to use window.alert instead of alert, even though they are equivalent in most cases.

Add content on Row Types and Variants

I'd like to see an explanation on how to use Prim.Row in the book.

Details on how to use Variant would also be nice. I think the existing readme could be expanded and either find a new home in the book or be linked to from the book.

Both of these related topics could fill a new chapter.

There's light coverage of rows in Chapter 5 and Chapter 9, and there used to be some other minor material in Chapter 8 with the older Eff.

Here's a list of articles on the topic, plus two more: 1 2. I'd like to distill some of this content and put in in the book so beginners don't have to do so much digging for it.

Tagging @drewolson, since this is another idea of a topic to cover.

Render book to single file

Would be nice to be able to render to book into a single file (like pdf). I know i can use pandoc, but i think it could use a little more like a Contents section.

Ch. 2 last exercise on spago installing purescript-globals behaves unexpectedly

Towards the end of the 2nd chapter is the last exercise which is as follows:


  1. (Medium) Use spago install to install the purescript-globals package as a dependency. Test out its functions in PSCi (Hint: you can use the :browse command in PSCi to browse the contents of a module).

When I do spago install purescript-globals, it yields the following:

[warn] The package 'purescript-globals' was not found in your package set, but 'globals' was. Using that instead.
[warn] Configuration file was not updated.
[info] Installation complete.

This sent me down a rabbit hole where I realized that bower install purescript-globals might have been used originally.

In any case, the existing behavior is sufficiently different to be confusing to at least this reader:

  1. globals is already available at this Purescript version level.
  2. But it's imported as Globals.

So I don't know what's expected in this exercise; much of the "connecting information" is missing.

Would the following work better?


  1. (Medium) Use spago ls packages to show where packages are stored in GitHub and what their global names are:
    1. In this command's response, locate the purescript-globals entry and browse its GitHub entry.
    2. Browse its Documentation link and click the link in its text.
    3. Observe what module names are implemented in this GitHub project.
    4. Test out its functions in PSCi (Hint: you can use the :browse command in PSCi to browse the contents of a module).

I'll be glad to do whatever the group decides as a PR.

Chapter 4 Accumulators example doesn't trigger TCO.

Hi, the example on how purescript will turn tail recursive functions into js while loops doesn't actually work as expected.

Code like this:

length_tail :: forall a. Array a -> Int
length_tail arr = len_ arr 0
    where
        len_ :: forall a. Array a -> Int -> Int
        len_ arr acc =
            if null arr then
                0
            else
                len_ (fromMaybe [] $ tail arr) acc + 1

Will become your stack overflowing call in javascript:

var length_tail = function (arr) {
    var len_ = function (arr1) {
        return function (acc) {
            var $10 = Data_Array["null"](arr1);
            if ($10) {
                return 0;
            };
            return len_(Data_Maybe.fromMaybe([  ])(Data_Array.tail(arr1)))(acc) + 1 | 0;
        };
    };
    return len_(arr)(0);
};

You need to change acc + 1 into (acc + 1):

length_tail :: forall a. Array a -> Int
length_tail arr = len_ arr 0
    where
        len_ :: forall a. Array a -> Int -> Int
        len_ arr acc =
            if null arr then
                0
            else
                len_ (fromMaybe [] $ tail arr) (acc + 1)

To get the while loop version:

var length_tail = function (arr) {
    var len_ = function ($copy_arr1) {
        return function ($copy_acc) {
            var $tco_var_arr1 = $copy_arr1;
            var $tco_done = false;
            var $tco_result;
            function $tco_loop(arr1, acc) {
                var $10 = Data_Array["null"](arr1);
                if ($10) {
                    $tco_done = true;
                    return 0;
                };
                $tco_var_arr1 = Data_Maybe.fromMaybe([  ])(Data_Array.tail(arr1));
                $copy_acc = acc + 1 | 0;
                return;
            };
            while (!$tco_done) {
                $tco_result = $tco_loop($tco_var_arr1, $copy_acc);
            };
            return $tco_result;
        };
    };
    return len_(arr)(0);
};

I just started learning purescript, so sorry if I'm missing something here.

This code was written in a project using:

  • spago: v0.10.0.0
  • purs: v0.13.4

Rethink Chapter 8

Chapter 8 required a complete rewrite once 0.12 was released because Effect replaced the old Eff Monad. I am personally not very satisfied with my rewrite. It's a tough chapter, and should probably be simplified. Thoughts and suggestions are welcome!

Ch 5: Cannot identify any realistic use for array literal pattern for exercise 'fromSingleton'

Here's the exercise statement:

(Medium) Write a function fromSingleton which uses an array literal pattern to extract the sole member of a singleton array. If the array is not a singleton, your function should return a provided default value. Your function should have type forall a. a -> Array a -> a

I don't think there's any scenario in which the array literal pattern makes sense. Here are 3 different implementations I explored:

fromSingleton ::  a. a -> Array a -> a
fromSingleton def arr = case uncons arr of
  Just { head: x, tail: xs } -> if 0 == length xs then x else def
  Nothing -> def

fromSingleton' ::  a. a -> Array a -> a
fromSingleton' def arr
  | 1 == length arr = fromMaybe def $ head arr
  | otherwise = def

fromSingleton'' ::  a. a -> Array a -> a
fromSingleton'' def [] = def
fromSingleton'' _ [ x ] = x
fromSingleton'' def _ = def

The exercise's clue recommends using the array literal pattern for the sole member of the singleton array. The problem I see is that the sole member never changes to another value, and so there's no need to use an array literal pattern to cache it.

If I'm correct, then this exercise does not successfully demonstrate the array literal pattern and should be deleted or changed.

I welcome "the answer" that I haven't thought of yet. Any takers?

Importing logShow

So a friend of mine started reading trough the book, and when he got to the getting-started section - which told him to use the logShow function - he was really confused because he got an error (caused by the fact logShow wasn't imported).

So that section already explains importing Math and Prelude so I think we should add another note on importing the logShow function.

Test examples and solutions in CI

Edit (May 26 2020): This is simpler now with #154.
Also, see notes on how examples should be tested: #158 (comment)


We can ensure all tests and solutions are in good working order by adding them to our Travis CI job.
I'm envisioning the following steps in the job config:

  1. Rebase the solutions branch onto master. Fail CI if there are merge conflicts.
  2. Run spago test in all chapters and monitor error status

Solutions PRs for a few chapters are in #101 and #102, and anyone is free to start working on this issue. Just post your status here so we don't duplicate efforts.

Update Chapter 2 - Testing Code Using the Interactive Mode

After following the step up to the secion Testing Code Using the Interactive Mode, executing
$ spago repl will throw:

purs repl: PSCi requires the psci-support package.
For help getting started, visit https://github.com/purescript/documentation/blob/master/guides/PSCi.md
spago: callCommand: purs repl ".spago/console/v4.4.0/src/**/*.purs" ".spago/effect/v2.0.1/src/**/*.purs" ".spago/prelude/v4.1.1/src/**/*.purs" ".spago/psci-support/v4.0.0/src/**/*.purs" "src/**/*.purs" "test/**/*.purs"  (exit 1): failed

Please add current instructions to load the psci-support package, like so:

spago install psci-support

This code was written on MacOSX Mojave 10.14.6 using:

  • spago==v0.14.0.0
  • purs==v0.13.6
  • npm==6.14.4

A few comments on issues with Chapter 1

After reading through it, here's a few issues that come to mind:

  • What is the purpose of the book and who is it for? The LeanPub summary isn't mentioned anywhere here.
  • Why should one use PureScript? At the very least, there might be links to other articles that cover that, like the one written by Phil himself.
  • Why is my learning reference not mentioned in the 'getting started' guide? If this was the first learning resource one came across, they would have to go to the documentation repo and find my resource in a section on the ReadMe.
  • Is the PureScript IRC channel still a valid communication line? I thought Slack was the main one for that now.
  • Try PureScript is likewise outdated and should probably be unlinked until after core contributors finish updating it to the 0.13 release. We should also include a note about this resource's outdatedness to forewarn people.

Ch8 Add exercise for `ST`

We should add a replacement for this original ST exercise:

(Difficult) The following is a simple way to estimate pi: randomly choose a large number N of points in the unit square, and count the number n which lie in the inscribed circle. An estimate for pi is 4n/N. Use the random and ST effects with the for function to write a function which estimates pi in this way.

Effect.random can no longer be blended with ST, so we can't complete this "Monte Calro Method" exercise.

It is still possible to estimate pi using a grid of points, but it's not as interesting without random, and the grid method could actually be tackled in ch4 like so:

estimatePi :: Int -> Number
estimatePi r =
  let
    bigN = r * r

    n =
      sum do
        x <- 1 .. r
        y <- 1 .. r
        guard $ x * x + y * y < r * r
        pure 1
  in
    (toNumber (4 * n)) / (toNumber bigN)

I'm not sure if adding this to ch4 would be an improvement, since it doesn't test any new language concepts.

It is possible to complete this exercise using Effect.Ref, but that's covered in Ch9. We could move Ref content to Ch8.


Some additional information:

ST may eventually be merged with Effect purescript/purescript-st#31

Summary of ways to track mutable state:

  • Control.Monad.ST - local mutations
    • Covered in this section of Ch8
  • Effect.Ref - global mutations
    • Covered in Ch9
    • Use with forE from Effect
    • "Note: Control.Moad.ST provides a safe alternative to global mutable variables when mutation is restricted to a local scope."
  • Control.Monad.State - passing around (technically immutable) state without having to thread parameters through a bunch of functions.
    • Covered in Ch11
    • This section of the original book contrasts this with ST and Ref.
    • Transformer

Previous discussion of this issue in #94

Remove `purescript-` prefixes from packages

As discussed in #61, these package prefixes are unnecessary (and warned against) when installing via spago.

What are maintainers thoughts on stripping out all purescript- prefixes from packages mentioned in the book text?

I think all packages can be assumed to be part of the purescript ecosystem unless otherwise specified (eg, "request module via NPM" in ch12).

Exercises/Conclusion header names clash in Livebook

See #73 and #75 for more context.

If you click on the ToC's 'Exercises' header links to a chapter other than the second one, it'll redirect to the second chapter's Exercises section, not the corresponding section of that chapter. This is due to the headers using the same text.

Review whether AddressBook records should be wrapped in `newtype`

I'm questioning the benefits of wrapping record types in newtype. It doesn't seem to be required for anything except custom Show instances, which seem to just mimic the default record show.

This is a major annoyance in Chapter 8 (example still in progress to be merged back in), but affects other chapters as well. So a few chapters will need to be modified if this simplification of removing newtype is applied.

Here's a summary of the dilemma. Note that this situation is partially improved by using separate state for each field, but it would be even simpler with a single person state and no newtype wrapping, and we should strive for simplicity for our beginner readers.

I find myself doing this:

pp@(Person p@{ homeAddress: Address a }) /\ setPerson <- useState examplePerson

setPerson \_ -> Person p { homeAddress = Address a { street = s } }

When I'd rather do this:

person /\ setPerson <- useState examplePerson

setPerson \_ -> person { homeAddress { street = s } }

Here are the wrapped records for reference:

newtype Person = Person
  { homeAddress :: Address
  }

newtype Address = Address
  { street :: String
  }

I'd rather just use basic records:

type Person =
  { homeAddress :: Address
  }

type Address =
  { street :: String
  }

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.