Giter Club home page Giter Club logo

book-of-examples's Introduction

book website (WIP)

Software Design by Example in Roc

The best way to learn design in any field is to study examples. These lessons therefore build scale models of tools that programmers use every day to show how experienced software designers think. Along the way, they introduce some fundamental concepts about pure functional languages that most programmers have never encountered. SDXRoc is a sequel to previous books in JavaScript and Python.

Contributing

  1. Fork this repository on GitHub so that you have a copy under your own account.

  2. Clone your repository to your machine.

  3. Make your changes in a branch in the repository on your machine (or in main if you prefer).

  4. Push that branch to your forked repository on GitHub.

  5. Create a pull request from that branch of your repository on GitHub to the main repository.

We suggest that you add this repository as a remote to your desktop:

$ git remote add upstream [email protected]:roc-lang/book-of-examples

so that you can git pull upstream main periodically to stay up to date with changes.

Topics

Name GitHub ID Topic Slug
Shritesh Bhattarai shritesh SVG rendering svg
Luke Boswell lukewilliamboswell text editor editor
Sophie Collard sophiecollard property-based testing proptest
Ashley Davis ashleydavis thumbnail gallery gallery
Eli Dowling faldor20 autocompletion completion
Kyril Dziamura wontem file backup backup
Hristo Georgiev hristog file diffing diff
Norbert Hajagos HajagosNorbert file transfer ftp
Norbert Hajagos HajagosNorbert discrete event simulation des
Stuart Hinson stuarth pattern matching match
Stuart Hinson stuarth redis data store redis
Nathaniel Knight nathanielknight random number generation prng
Monica McGuigan monmcguigan JSON codec json
Noel Rivas noelrivasc logging framework logging
Abhinav Sarkar abhin4v pretty printing pretty
Fabian Schmalzried FabHof binary data packing binary
Isaac Van Doren isaacvando compression compress
Isaac Van Doren isaacvando HTML templates template
Jasper Woudenberg jwoudenberg continuous integration ci
Agustin Zubiaga agu-z HTML parser parser

Learner Persona

  1. Ning (26) has a college degree in software engineering and has been working as a programmer for four years. They are comfortable using JavaScript, Python, the Unix shell, Git, and Docker to build web applications in a team with half a dozen others.

  2. Ning is helping to convert a 20K line legacy front end from JavaScript to TypeScript. That experience sparked an interest in strongly-typed languages, which led them to experiment with Elm on some personal projects and to go through the Roc tutorial.

  3. Ning would like to learn more about functional programming, and about the differences between working in interpreted and compiled languages. They are also interested in getting involved with an active open source community where they might still be able to make a noticeable contribution.

  4. Ning has never done a course on compilers or programming language semantics, so they are worried that they don't know enough to start and will look foolish if they ask questions. In addition, their workload means they cannot commit to a regular learning schedule, so lessons must be usable in bursts of two or three hours at a time.

FAQ

  • Why Roc rather than a more established language like Haskell, Clojure, or Elixir? One of the lessons from the previous books is that a large language can make design harder to see: core ideas might actually have been clearer if those books had used a smaller language like Lua. This book is also partly an experiment: can a project like this early in a language's development accelerate its evolution by drawing attention to oversights and sources of friction while the language is still malleable?

  • What license are we using? The code is covered by the MIT License, so it can be copied, remixed, extended, and incorporated into other projects (both open and closed source). The prose (i.e., the text of the lessons) is covered by the CC-BY-NC-ND License, which means it is free to read but people must cite us as the source if they quote or copy it, cannot republish it commercially without our permission, and cannot create derivative works (e.g., translations) without our permission. We may remove some of these restrictions once we have a contract with a publisher, but they are in place now because it's much easier to relax a license after the fact than to tighten one up.

  • How do I propose a topic? Create an issue with "topic proposal:" in its title and a brief description of what you'd like to cover. Greg will triage issues, start discussions, and identify overlaps.

  • How do I know what topics are taken? Look at the "Topics" section of this file or for issues marked assigned in our repository.

  • What if I don't have an idea but still want to contribute? Issues labeled help wanted in our repo are topic proposals in search of authors. If you are interested in taking one of these on, please add a comment to the issue and mention @gvwilson to start discussion.

  • Where should code and notes go? For now, each topic should go in a subdirectory of the root directory whose name is a short hyphenated slug, e.g., editor or http-server. Each topic should be a standalone project; please include an index.md Markdown file with point-form notes about the design of the code.

Structure

We are currently building this site using Jekyll (the default static site generator for GitHub Pages); we will convert to something Roc-based soon.

  • Project
    • ./CODE_OF_CONDUCT.md: code of conduct
    • ./GOVERNANCE.md: how this project is run`
    • ./LICENSE.md: license
    • ./README.md: this file
  • ./index.md: home page
  • ./*_.md (trailing underscore): create website pages for project files
  • */index.md: chapters and appendices
  • ./*.css and ./favicon.svg: for generated website
  • Jekyll
    • ./_config.yml: configuration
    • ./_data/: data files (see below)
    • ./_includes/: inclusions
    • ./_layouts/default.html: our page template
  • Data files
    • _data/contrib.yml: contributors (use GitHub ID as primary key)
    • _data/order.yml: chapters and appendices in order (use slug as primary key)
    • _data/topic.yml: chapter and appendix information (use slug as primary key)

book-of-examples's People

Contributors

agu-z avatar anton-4 avatar fabhof avatar faldor20 avatar gvwilson avatar hajagosnorbert avatar hristog avatar isaacvando avatar jwoudenberg avatar lukewilliamboswell avatar nathanielknight avatar noelrivasc avatar rtfeldman avatar shritesh avatar stuarth avatar

Stargazers

 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

book-of-examples's Issues

topic proposal: logging framework

Original proposal:

  • discovering tests
  • running them
  • mocking external dependencies

Revised proposal (see thread below): implement a logging framework on top of two different platforms to compare/contrast the ways those platforms affect design.

topic: JSON ADT and codecs

I'm imagining writing an ADT for JSON structure and then showing how you can write encoders/decoders for this representation.

It would cover modelling data with algebraic data types, pattern matching, encoding/decoding etc.

I like this topic because I feel like there's lots of different details and levels you can dive into.

topic proposal: Parser combinator library

Something that could be quite fun and useful to do is showing how to implement a simple parser combinator library.

Could build on some of the BSON encoding/decoding, where we can take that shape of data and show how you would extend it to parse it into the ADT representing it.

I'd include showing how to combine simple operations for parsing like A | B, A ~ B, as well as for simple data types like strings, bools, digits etc.

meeting 2024-04-10

Agenda

  • Welcome new participants
  • Vote: temporary GHP site #50
  • Vote: prohibiting external packages #46
  • Discuss: lesson patterns
    • PETE (problem, example, theory, elaboration)
    • PRIMM (predict, run, investigate, modify, make)
    • C&R (challenge and response)
  • Next steps for April

topic: diff tool

  • A git-like, minimalistic version control system.
  • If the term isn't deemed too hyped up (and as such distract from the actual substance), the chapter could also touch upon the connection to and parallels with blockchain technologies.

topic: file backup

The problem

Create a system that allows creating a backup of a directory and restoring directory state from the backup

Technical challenges

  • Multiple backups with little overhead

Takeaways

  • Hash functions: how to represent smth big with smth small
  • Testing of inversion functions, in this case, dirState == restore(backup(dirState))

Storytelling ideas

  • The Library of Babel

topic: package manager

@rtfeldman discussed several ways to manage packages with Louis Pinfold in a recent podcast; implementing some of those options in Roc in order to show why it's such a hard problem might not reveal anything about functional programming per se, but would help people understand Roc's design choices.

topic: text editor

I would like to work on the test editor chapter. I have a package for handling ANSI escape sequences which are supported in most modern terminals, and is most useful when working with the basic-cli platform.

Here is an illustration of an app using this package, and the code for the tui-menu example.

I think I can expand this example to include opening, editing, and saving files. The main limitation I can think of is limiting this to ASCII and not supporting full unicode.

topic: compression

Data compression is used all the time by software engineers, but I suspect many do not have a clear understanding of how it is implemented. I believe this makes it a good topic for the book. @bhansconnect recommended the LZ77 algorithm. I have not investigated it heavily, but it seems doable in a chapter and it is a component of gzip which is also valuable. However, there could be another more suitable algorithm to use instead. I am interested in working on this if we decide to do it.

topic proposal: SSH

I don't know how doable it would be, but I think a chapter on a small version of SSH would be great.

CC0-1.0 license for code?

I really like the CC0-1.0 license we currently use for the Roc examples repo. It's a license with minimal restrictions. It allows users to just copy-paste an example into their codebase (even commercial) without needing to learn about attributions.

The current license for this project (CC-BY-NC-ND-4.0) requires users to include an attribution, prohibits commercial use, and does not allow code with any modifications to be included in for example a Roc package.

The CC-BY-NC-ND-4.0 license feels like a net negative to me. I think the CC0-1.0 license would make the book more beneficial to society and lead to a better user experience without making any real sacrifices.

It seems so strange to show high quality examples but not allow people to just copy-paste them into their own projects.

Opinions welcome :)

topic proposal: pseudorandom number generators

We already have an implementation of PCG pseudorandom number generation in roc-random but implementing random generators in a purely functional language seems like a good fit for this book because:

  • Most languages have something like a random() function which isn't pure (since it potentially returns a different answer each time it's called). Because of this, it's a common beginner surprise to discover that a random number generator in a pure FP language has to present a different API.
  • There are a bunch of different PRNG algorithms out there, including ones that are simple enough that you can write the "randomness" part in a few lines of code, and then focus on the concept of how computers do "randomness" and pure FP API differences (including generating things other than numbers) for the rest of the chapter - which are the more interesting parts.
  • There's a good opportunity for some "further reading" notes on why algorithms like PCG and xoroshiro provide better distributions of outputs, performance tradeoffs, entropy sources for secure randomness, etc.

topic proposal: a parser with useful error messages

#2 proposes an HTML parser; this chapter would be a follow-on that would show how to generate useful error messages from such a parser. (This suggestion motivated in part by the strengths and weaknesses of Roc's own error messages and the fact that most undergrad courses on compilers give this important topic very little attention.)

proposal: use Jekyll/GitHub Pages _temporarily_ to build a website for this material

I propose using standard GitHub Pages tooling (i.e., Jekyll) to build a website for this material while we are working on rough drafts, and to move to something Roc-based once we have a better idea of what we need.

Pros:

  1. Immediately available: see the website branch of this repo, which uses a template from previous book-ish projects I've worked on.
  2. Having something up right away will give us a better idea of what we actually want from whatever static site generator we eventually choose.
  3. "Use GHP's default" can save a lot of arguing over what's the best SSG and why.

Cons:

  1. Local preview requires Jekyll.
    • Contributors shouldn't be worried about formatting at this point (@gvwilson can tidy that up as PRs come in if necessary).
    • Jekyll is straightforward to set up for people who do want to preview.
  2. We ought to use a Roc-based SSG.
    • Translation will be low effort, since the templating is very simple.
    • Building this with an off-the-shelf tool will give us a better idea of what we actually need in that SSG.

proposal: Prohibit external packages

Writing the simulation chapter, I'm currently using an external pseudo-random package. Obviously I don't want to implement it while teaching simulations, so a package is needed in this case. That begs the question: How should we handle packages?
I have 2 related proposals:

  1. We should restrict the use of packages to those that are created in one of the chapters. (I know there will be a chapter on PRNG, so simulation would be covered) I suspect the reader would find great satisfaction in using his/her own implementation of a package. That way, every used line of Roc code would be explained in the book. If an external package is needed to implement a chapter's code, that package needs explaining as well in one of the chapters. That being said, we can't expect the reader to first write the package code and then use it. Some may do it, others won't, so the packages need to be hosted somewhere.

  2. This github repo should host the package releases which would be used by other chapters. External packages imported from an url are fragile, especially if those urls are out of our control. Those urls will be physically printed out, so they should strive to be as stable as the page they are written onto. Hosting them under roc-lang's github would yield us more control and also make things be in a single place.

Related question to the 2. point of the proposal:

I know little about Roc packages, but I think they need to have a pre-defined structure. Adhering to that structure while teaching a concept inside a chapter could be distracting to the learner (but I don't know by how much). Should the hosted packages be the same as the content of the chapters, or should the chapters focus on teaching the concept in expense of not being a proper package that the user could import locally, thus later in a different chapter needing to import it from a url regardless if he/she has written it already?

Note: By packages, I mean Roc packages, not platform packages.

topic: pretty-printing library

The idea is to implement a pretty printing library based on Philip Wadler's "A prettier printer" paper.

The paper already contains code for an implementation, though it is a bit rudimentary. The wl-print Haskell package contains an extension of it, with some extra bells and whistle for convenience.

We can stick with the paper's implementation or something in-between that and wl-print's. We would also demonstrate the library usage by pretty printing one of these:

  • An ADT, such as the JSON value representation
  • An AST representation of s-exps (simple AST)
  • An AST representing some simple imperative language (complex AST)

This has been done before in the chapter 5 of the Real World Haskell book.

The Roc implementation may not be exactly same as the Haskell implementations because of strict-vs-lazy nature of the two languages.

discuss: how to manage inter-chapter dependencies?

Following on from #46: how should dependencies between chapters be managed? I.e., if Chapter B uses code developed in Chapter A, how should Chapter A be structured and how should Chapter B get what it needs? Please add comments to this issue with thoughts and proposals.

topic proposal: machine learning from first principles

This is a bit more general than #4.

The proposal involves introducing fundamental machine learning concepts such as data preprocessing, feature engineering, model training, validation and evaluation (essentially, steps which make up a machine learning pipeline).

I've been working on a library called RocLearn, with API that is close to Python's sklearn library. The idea is to implement fundamental machine learning algorithms (k-nearest neighbours, Principal Component Analysis, Support Vector Machines, Linear Regression etc) from first principles and at the same time abstract out the details of each one, in order to enable them to be viewed as modules that could be plugged in and out, as part of the more general steps, associated with a machine learning pipeline.

topic: dynamic thumbnail gallery layout

I have a photo gallery layout algorithm that I'd like to port from TypeScript to Roc.

It is capable of doing incremental layout (as new assets are downloaded in the background) which allows it to do the layout for 100k images without the user even noticing.

Live demo with 100k assets: https://photosphere-100k.codecapers.com.au

The TypeScript type signature looks like this:

export interface IGalleryItem {
    _id: string;
    width: number;
    height: number;
    thumbWidth?: number;
    thumbHeight?: number;
    aspectRatio?: number;
    // --snip--
}

export interface IGalleryRow {
    items: IGalleryItem[];
    offsetY: number;
    width: number;
    height: number;
    // --snip--
}

export interface IGalleryLayout {
    rows: IGalleryRow[];
    galleryHeight: number;
}

function computePartialLayout(layout: IGalleryLayout | undefined, items: IGalleryItem[], 
    galleryWidth: number, targetRowHeight: number): IGalleryLayout;

It will be interesting to benchmark the TypeScript code against the Roc code.

It would be nice to do the entire gallery frontend in Roc, but for the book it is possible to demonstrate the layout algorithm in code that is runnable from the CLI.

Here are some other ideas related to this that might also be worth considering:

  • Virtual view port
    • Only showing the rows of the gallery that are visible (making it possible to render a gallery with 100k assets). Performance is key here, because we have to rerender as the user is scrolling through the gallery.
  • Prioritized download queue
    • Thumbnails are queued for download to be displayed in the gallery.
    • There are two priorities:
      • High priority for thumbnails that should currently be on screen (we need to download and show these in the shortest possible time).
      • Low priority for thumbnails in the pages before and after the current page being rendered (these are the thumbnails that the user will scroll to next, so they don't need to be displayed immediately).
  • Page-based loading of thumbnails
    • Loading individual thumbnails from AWS S3 is very slow.
    • To make a big set of thumbnails load quickly they are aggregated into a "page" containing 100 thumbnails. This means that one request replaces 100 when loading thumbnails. The "page" is packed on the backend (and cached in S3) and unpacked on the frontend.

topic: file transfer (FTP)

I'd like to go forth with this chapter, which includes sending files between a client and a server via network.

topic proposal: discrete event simulator

Simulation was one of the reasons OOP was invented, and interacting objects with their own state and control flow is a natural way to represent things like the flow of messages through a complex tangle of microservices. Showing how to do such simulations in a pure functional language would put a spotlight on the differences between the two paradigms.

topic: SVG rendering

IMO the book should showcase a platform implementation and turtle graphics is a fun and simple one to do.

infrastructure proposal: create a blog for this book

RSS is an easy way for interested parties to keep up with occasional announcements and progress reports. We can easily set up a GitHub Pages blog (https://roc-lang.github.io/book-of-examples/) using Jekyll for now, and switch to a Roc-based tool if there's interest while recycling the posts. I envision posts consisting of things like "person X has taken on topic Y", "person Q has a first draft of topic P ready for review", and, "we've made the following decisions about managing the glossary".

Please add thoughts below: in particular, is this Yet Another Distraction and everything should stay in Zulip or some other channel?

topic proposal: property-based testing framework

A simple property-based testing framework, with generators provided for primitive types and collections and the ability to define generators for your own custom types.

Advanced features like shrinking may have to be skipped to keep the project reasonably small though.

Topic proposal: A transpiler to JavaScript

Topic proposal: A transpiler to JavaScript

I propose a new topic for the book: A transpiler to JavaScript. The idea to write a transpiler (a source-to-source compiler) for a simple imperative programming language to JavaScript (JS). This new language — that I call KahwahScript1 or KS for short — is similar to JS in syntax, but has fewer constructs and simpler/different semantics.

Some examples of different semantics:

  • Dynamically typed like JS, but strongly typed like Python.
  • Variable declaration requires initialization.
  • Only false and null are falsey.
  • All variables are lexically scoped.
  • Functions have fixed arity.
  • No undefined.

Some examples of missing constructs:

  • No anonymous functions.
  • No for loops, only while loops.
  • Only number, boolean, string and function types.
  • No classes or objects.

In terms of code, we’ll need to write a Tokenizer, a Parser, a Translator and a CodeGenerator. This can be structured as two chapters, first for the first two components, and second of the last two.

Alternatively, we can make writing the Tokenizer and Parser an exercise for the readers while providing hints for their implementations, because there may be other chapters about parsing. In such case, we can have only one chapter that focuses on translation of KS to JS, and code generation.

We limit the scope to these components only, and leave the rest of the work as exercises for the readers. This may include:

  • Writing an interpreter for KS.
  • Using the interpreter to test the transpiler implementation.
  • Writing a REPL for KS.
  • Enriching the language/transpiler and the runtime to enable writing a self-hosted KS-to-JS transpiler.

The main takeaways from the chapter(s) will be:

  • Writing an AST-to-AST translation based compiler.
  • Learning the nuances of JS, and work around them to maintain the semantics of the source language.
  • Optionally, if we choose to have a chapter on tokenization and parsing, how to use parser combinators to write a tokenizer and a recursive descent parser.

The main potential complication that I see is, the readers may have to learn too much about the idiosyncrasies of JS.

For a proof of this concept, I’ve already written an implementation of the transpiler in Haskell.

Footnotes

  1. Kahwah is a traditional preparation of green tea consumed in the North Indian subcontinent, and in this case, a word play on Java (a coffee).

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.