Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syllabus docs #369

Merged
merged 44 commits into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
66f0996
Add syllabus docs
ErikSchierboom Jul 6, 2022
c3f3e3a
Draft introduction to syllabus design document
kytrinyx Aug 15, 2022
153846f
Tweak syllabus docs
kytrinyx Aug 15, 2022
1929f87
Add stub documents for syllabus-specific 'getting started' documents
ErikSchierboom Aug 16, 2022
b592ee8
Add some notes about first exercise in syllabus
ErikSchierboom Aug 16, 2022
52f8678
Add some notes about next exercises in syllabus
ErikSchierboom Aug 16, 2022
7b93abc
Add some notes about expanding exercises in syllabus
ErikSchierboom Aug 16, 2022
c529f30
Expand on building out the syllabus
kytrinyx Aug 17, 2022
d25afba
Flesh out syllabus docs
kytrinyx Aug 17, 2022
3931c94
Tweak syllabus docs
kytrinyx Aug 17, 2022
d7ce02b
Add note about creating issues to syllabus docs
kytrinyx Aug 18, 2022
e3fbb33
Update syllabus docs
kytrinyx Aug 30, 2022
258b4a1
Tweak wording on syllabus docs
kytrinyx Aug 30, 2022
7bce1ea
Tweak wording on syllabus docs
kytrinyx Aug 30, 2022
fa06929
Update syllabus docs
kytrinyx Aug 30, 2022
d66d32f
Add specifics about where and how to ask for help to syllabus docs
kytrinyx Sep 7, 2022
b908c38
Add a bit more about cyclic dependencies
kytrinyx Sep 7, 2022
6010970
Add a note about non-idiomatic code in syllabus docs
kytrinyx Sep 7, 2022
0cf5db7
Add spaces around emdash for readability
kytrinyx Sep 7, 2022
9e25304
Adjust initial goal explanation of first concept exercise
kytrinyx Sep 7, 2022
9856904
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
8736500
Add. missing spacing in syllabus docs
kytrinyx Sep 19, 2022
34a2ee0
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
7cfd5cd
Appease markdown linter in syllabus docs
kytrinyx Sep 19, 2022
c204316
Use more common form of gerund in syllabus docs
kytrinyx Sep 19, 2022
0a729f2
Use more common form of gerund in syllabus docs
kytrinyx Sep 19, 2022
2ab1502
Appease markdown linter in syllabus docs
kytrinyx Sep 19, 2022
c9825e8
Fix typo in syllabus docs
kytrinyx Sep 19, 2022
043046a
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
97b89f5
Change team name in syllabus docs
kytrinyx Sep 19, 2022
99c7565
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
b7f119a
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
4176c45
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
ef643ec
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
6930e41
Improve formatting in syllabus docs
kytrinyx Sep 19, 2022
3622c8c
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
c48692a
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
1e2ac24
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
9f62c7c
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
434f48d
Clarify syllabus docs
kytrinyx Sep 19, 2022
d646107
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
4708642
Improve wording in syllabus docs
kytrinyx Sep 19, 2022
a228bf1
Remove unnecessary 'here' when linking from syllabus docs
kytrinyx Sep 19, 2022
d29d0d7
Add suggestion to syllabus docs
kytrinyx Sep 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions building/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,34 @@
"title": "Concept Exercises",
"blurb": ""
},
{
"uuid": "038e26ee-891f-4592-92bd-c54cbd58d8bd",
"slug": "tracks/syllabus",
"path": "building/tracks/syllabus/README.md",
"title": "Syllabus",
"blurb": ""
},
{
"uuid": "af70ff3e-d4a4-4968-bcfe-1f197dc43380",
"slug": "tracks/syllabus/first-exercise",
"path": "building/tracks/syllabus/first-exercise.md",
"title": "First Exercise",
"blurb": ""
},
{
"uuid": "6f8d7376-70db-4f25-928c-4778bdf8a686",
"slug": "tracks/syllabus/next-exercises",
"path": "building/tracks/syllabus/next-exercises.md",
"title": "Next Exercises",
"blurb": ""
},
{
"uuid": "cb430e09-7710-43b8-ab0e-2f0ee3785cf9",
"slug": "tracks/syllabus/expanding",
"path": "building/tracks/syllabus/expanding.md",
"title": "Expanding",
"blurb": ""
},
{
"uuid": "ed318b17-01be-4868-92df-50a644adfdc7",
"slug": "tracks/concepts",
Expand Down
3 changes: 3 additions & 0 deletions building/tracks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ The track's configuration and metadata are specified in the `config.json` file.

All concept and practices exercises of a track involve _concepts_. These concepts are separate entities by themselves. Check the [documentation](/docs/building/tracks/concepts) for more information.

The concepts taught in the track's concept exercises form a _syllabus_.
For more information on how to design a syllabus, check the [syllabus documentation](/docs/building/tracks/syllabus).

## Exercises

Tracks have two types of exercises:
Expand Down
2 changes: 2 additions & 0 deletions building/tracks/concept-exercises.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Concept Exercises

[Concept Exercises](/docs/building/product/concept-exercises) are exercises designed to teach specific (programming) concepts.
The concepts taught by the concept exercises form a _syllabus_.
For more information on how to design a syllabus, check the [syllabus documentation](/docs/building/tracks/syllabus).

## Metadata

Expand Down
177 changes: 177 additions & 0 deletions building/tracks/syllabus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Syllabus
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

A fully featured Exercism track has two types of exercises: Practice Exercises and Concept Exercises.
Concept Exercises and Practice Exercises are fundamentally different and complement each other well.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

A track's [Concept Exercises](/docs/building/tracks/concept-exercises) are exercises designed to teach specific concepts that form the basis of a programming language.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
These concepts form a _syllabus_.

This documentation contains pointers and tips on how to succesfully design a syllabus for your track.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

## The goal of a syllabus

The end goal of a syllabus is to lead students to be comfortable with idiomatic code in the target language.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

Each individual Concept Exercise is very tightly focused.
It is a very small step that moves the student towards understanding something about the language.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
It builds only on concepts that have been introduced previously.

By solving the exercise, the student begins the process of becoming familiar with the concept.
Understanding comes primarily through doing, much less so through explanations.
The explanations are only there so that the student can do what needs to be done.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

We want to allow students to start writing code immediately, without having to understand everything up front.
In order to achieve this we hand-wave over details and we leave a lot of things unexplained.
We simplify and provide code stubs where possible.
This reduces the cognitive burden of getting started and provides the time and space for the knowledge to sink in.
By taking this approach we're not saying that the student doesn't need to know these things, we're saying that they don't need to know them _yet_.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

Often the earliest exercises need to contain non-idiomatic code.
This is because in the beginning most of the language is still unknown.
Most of the concepts have not yet been introduced.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
By allowing non-idiomatic code in the earliest exercises, students are able to take many smaller steps in familiar territory rather than a few big steps in unfamiliar territory.
The result is that they are able to reach the stage of idiomatic code more quickly and with less friction.
Comment on lines +31 to +32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to highlight both of these sentences in big flashy lights!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we leave them as they are, or add asterisks to make them bold?


## Basic structure

Exercises are structured as a tree with an introductory exercise at the top as the starting point.
Later exercises teach concepts that depend on having understood concepts that are taught earlier.

## Porting and borrowing

It can be worth looking at how other language tracks have built out their concept exercises.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
You can find examples of Concept Exercises from other language tracks [here](https://exercism.org/docs/building/tracks/stories).

That said, if you decide to use other exercises as a starting point for your own, be careful to ensure that the resulting exercise is about the concept as it exists in your language.
Sometimes concepts differ subtly, sometimes radically.
Sometimes concepts don't exist at all.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

The syllabus, and therefore the concept tree, should represent the concepts that exist in the language.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

Don't include concepts just because other tracks do.

In some cases it might be tempting to put a concept in because people often have to work around it by using concepts that do exist.
Rather than doing this, introduce the concept that the language _does_ use, and consider adding an exercise that explains how to use it in that type of situation.

For example, in Go there are no enums.
Instead the Go concept tree introduces constants, and teaches how to use constants in the type of situation where you might use enums in other languages.

## Asking for help
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
Don't hesitate to ask for help.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
It's better to ask up front or while working on an exercise rather than discussing during code review.

On GitHub you can mention the team @exercism/learning-mode-consultants.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
In Slack you can ask in the #learning-mode channel.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

## Getting started

Our experience has taught us that the most pragmatic way to develop a syllabus is to grow the concept tree organically, starting with the simplest concepts.
We don't have to get everything right up front, but it's really useful to not think too far ahead.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

We start with the track's easiest concepts.

Some things are easy because they are inherently simple.
Other things are not all that simple, but feel easy because they are familiar.
Familiar is good.
Familiar is not confusing.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

While the endpoint is to write idiomatic code, the stepping stones to get there are not always idiomatic.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
Using what is familiar — even if it is not a great example of code in that language — helps move a student more quickly toward the goal of code that is more typical of the language.

### Developing the first exercise

Rather than trying to map out the entire concept tree up front, just start with the first exercise.
Think of this exercise as the "Hello World" of concept exercises.
The goal of the first exercise is to allow the student to start learning with the least amount of friction as possible.
They are taking the very first step towards getting familiar with what code in this language looks like.
They might write a small piece of code, or perhaps just make a couple of additions to a stub in order to complete the exercise.
Try to optimize for a quick win and getting students familiar enough with the bare necessities of syntax to be able to move forward confidently.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

Read more about [developing the first exercise](/docs/building/tracks/syllabus/first-exercise.md) here.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

### The next exercises

The first exercise should unlock a handful of exercises that introduce fundamental concepts.
These will be things like primitives or basic types and simple operations on those types.

Read more about [developing the next exercises](/docs/building/tracks/syllabus/next-exercises.md) here.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

### And then what?

This is where it often starts getting interesting.
There is so much you _could_ introduce at this point.
How do you decide what concepts to tackle next?

It kind of doesn't matter.
As long as you start somewhere that seems reasonable, it will be fine.

Read more about what we think "reasonable" means in the context of [expanding the concept tree](/docs/building/tracks/syllabus/expanding.md).

## Do not convert practice exercises

A good Concept Exercise is extremely focused, and ideally teaches only one concept.
There will usually be only one expected approach to solving it.
This is in contrast to Practice Exercises, which are open ended and lend themselves to exploration.

A good Concept Exercise is usually a bad Practice Exercise, and vice versa.
Since the goals of Practice Exercises and Concept Exercises are completely different, we do not take Practice Exercises and convert them into Concept Exercises.
We write all Concept Exercises from scratch or base them on stories that were explicitly crafted for the purpose of teaching simple concepts.

## We encourage handwaving
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

Sometimes you'll feel like there is a deadlock.
Concept A requires understanding concept B, and B requires understanding A.

In this case simplify.
Handwave over some complexity in one so that you can get students familiar with the other.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
It's perfectly fine to say that something will be introduced in more depth later, and that for now the student just needs to understand this one bit.

Concepts are understood more deeply in stages and over time.

## Selecting stories
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

A concept exercise always has a story.

If you're forking an exercise from another track, then the exercise will already have a story.
In that case, you're all set.

To see if there are any existing stories you can use or exercises you can fork, check out the [list of stories](docs/building/tracks/stories).

If you have a concept but no story then our recommendation is to write a small, simple code example that uses the concept that you're introducing.
Then reverse engineer a story onto the code.
Keep the story stupidly simple.
It doesn't have to be good fiction.
It doesn't need a strong plot or character development.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
It can be just a couple of lines long.

Bounce ideas for stories with the Exercism team.
We have a lot of experience coming up with suitable stories.

Once you have a story you will likely need to tweak the code a bit to get it to fit the story.

## Contributions from the community

Working on a syllabus involves two separate but intertwined activities:

1. Syllabus design: selecting and ordering concepts
2. Exercise implementation: writing documentation and creating exercises to teach those concepts

We've found that it's both fun and enriching to get the wider community to contribute to implementing exercises.
The syllabus design itself, though, is easier to tackle with a small team of contributors who are all engaged in building up an understanding of the full syllabus with all of its intricacies.

That said, we recommend that the syllabus design team implements the first five or six concepts first, before opening up for community contributions.
This helps ensure that the people on the core team of syllabus designers understand the process themselves before having to review pull requests from people in the broader community.

It's also easier to create issues for these higher-order concepts and tends to be more fun for community members to work on them, since there are fewer constraints to worry about.

## Creating issues

We still haven't figured out how to best create issues for creating concept exercises.

In some tracks we've tried creating separate exercises for the concept itself and the exercise.
In others we've tried making issues that have a checklist to work through.
Overall, we think this is still too intimidating, and we'd like to find a better way.

Please talk to us about the process as you start making issues, and we will do our best to help figure out how to proceed.

We will update the documentation as we learn better ways of tackling this.
18 changes: 18 additions & 0 deletions building/tracks/syllabus/expanding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Syllabus - Expanding

Once you've built a few concept exercises it becomes easier to expand the syllabus.
This is because you now have access to more concepts that you can build on.

The two main ways that we expand a concept tree are to:
1. build on an existing concept (e.g. `time` => `timezones`)
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
2. introduce a new concept that depends on a concept that has already been introduced (e.g. `classes` => `interfaces`)

If you're at a loss for what to choose next, take a look at one or two of the simplest practice exercises that exist for your track.
Identify the concepts that are used, and pick one that hasn't been covered yet in the syllabus.

You might discover that the exercise you're working depends on understanding a concept that hasn't been introduced yet.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
Just make a note of it and finish the exercise with the assumption that the student already understands the missing concept.
Remember to set the status of the exercise to `wip`, as having gaps or jumps in the concept tree will be very confusing to students who are unfamiliar with the language.

It's worth taking a look at other tracks to see how they've structured their syllabuses.
For example the [Elixir track](https://exercism.org/tracks/elixir/concepts) has a really nice syllabus progression.
25 changes: 25 additions & 0 deletions building/tracks/syllabus/first-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Syllabus - The first exercise

The first exercise should cover the concept `basics`, and it should have no prerequisites.
It should provide only enough information to allow the student to solve the exercise at hand.

For example, if you need to compile a program to get it to work, this is something that you'll want to mention in the introduction to the exercise.

Other things that are often covered within the `basics` exercise are:
- function or method definitions
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
- calling functions
- passing arguments to functions
- assigning a value with a name (variables and/or constants)

Use as few data types as possible.
If you can manage, use only integers, as their notation is the same across most languages and will be well known to virtually everyone.

Each language is different, and you might find that you need to introduce more than other tracks do, or less.
Many tracks have already implemented an exercise covering `basics`.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved
If there's a track for a language that is similar to yours, go ahead and check if you can fork their exercise and use it as a starting point.

Aim to be concise; you don't want to overload students with information.
The introduction should explain _just enough_ that the student can look at the code and identify what the different parts are.
They don't need a deep understanding of any of it, but they should also not be left wondering what something is.

The student should only need to actively _use_ one or two concepts.
33 changes: 33 additions & 0 deletions building/tracks/syllabus/next-exercises.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Syllabus - Next Exercises
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

Having implemented your first concept exercise, the next few exercises should build on that.

We like to have three to five exercises that have no other prerequisites other than the `basics` concept.
kytrinyx marked this conversation as resolved.
Show resolved Hide resolved

Good options are the core primitives or data types of your language.
E.g. booleans, basic numeric types, strings, and atoms.

It's worth checking other tracks' concept exercises to see if there are any that are appropriate for your track.

Note that introducing a concept doesn't mean that you need to explain it fully in all its glory.
You can always defer complexity.
The language might have a dozen different numeric types that are useful in different scenarios.
The exercise can simply mention that there are others while introducing only the most commonly used integer type and most commonly used floating-point type.

Some core data types are too complex to introduce directly.
For example strings might be lists of chars.
In such a case you would need to defer the introduction of strings, and design a concept exercise for chars and another for lists.
Then you can add an exercise for strings that has both of those exercises as prerequisites.

Sometimes while working on an exercise you will realize that it's more complex than you expected.
That's totally fine.
Make a note of the concept that needs to be taught as a prerequisite.
Then pretend that such an exercise exists, and finish the exercise you're working on with that simplification in mind.
Then go back and create a new exercise for the prerequisite concept.
Remember to mark the exercise as `wip` until the prerequisite exercise has been added.

Another thing that can happen at this point is that you find that you have cyclical dependencies.
You need to introduce two concept, but each concept relies on the other.
In this case you may be able to use a stub.
Then you can explain that the dependent concept exists, but reassure them that they don't need to understand it yet.
Another option would be to give a bare minimum of an introduction, enough for the student to get past the hurdle, while reassuring that the concept will be covered in more depth later.