Skip to content

Commit

Permalink
Update based on feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
meatball133 committed Aug 10, 2024
1 parent 9787f6c commit 7cec5cf
Show file tree
Hide file tree
Showing 17 changed files with 105 additions and 90 deletions.
4 changes: 2 additions & 2 deletions concepts/symbol/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"blurb": "Symbol represent a unique identifier through the program, which is created at compile time",
"blurb": "Symbols represent unique identifiers throughout the program, which is created at compile time",
"authors": ["meatball133"],
"contributors": []
"contributors": ["ryanplusplus"]
}
13 changes: 6 additions & 7 deletions concepts/symbol/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ They also allow for being written with quotes, e.g. `:"foo"`, which allows, for
:"foo boo" # => :"foo boo"
```

Symbols are used in many places in the language, including as keys in namedtuples, to represent method names and variable names.
Symbols are used in many places in the language, including as keys in namedtuples and to represent method and variable names.

## Symbols in Crystal

Symbols in Crystal is quite different from Ruby.
In Crystal is a symbol a form of constants and is thereby is assigned at compile time.
Symbols in Crystal are quite different from Ruby.
In Crystal a symbol is a type of constant and is thereby is assigned at compile time.
This means that symbols can't be created dynamically, which is possible in Ruby.

Symbols in Crystal is represented as an `Int32` which makes very efficient.
Symbols in Crystal are represented as `Int32`s which makes them very efficient.

## Identifier

What makes symbols different from strings is that they are identifiers, and do not represent data or text.
What makes symbols different from strings is that they are identifiers and do not represent data or text.
This means that two symbols with the same name are always the same object.

```ruby
Expand All @@ -34,11 +34,10 @@ This means that two symbols with the same name are always the same object.
## Conversion

Symbols can be converted to strings but not vice versa.
This is because symbols are created at compile time, and strings are created at runtime.
This is because symbols are created at compile time and strings are created at runtime.

```crystal
:foo.to_s # => "foo"
```

[symbols]: https://crystal-lang.org/reference/syntax_and_semantics/literals/symbol.html
[symbols-api]: https://crystal-lang.org/api/Symbol.html
12 changes: 6 additions & 6 deletions concepts/symbol/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ They also allow for being written with quotes, e.g. `:"foo"`, which allows, for
:"foo boo" # => :"foo boo"
```

Symbols are used in many places in the language, including as keys in namedtuples, to represent method names and variable names.
Symbols are used in many places in the language, including as keys in namedtuples and to represent method and variable names.

## Symbols in Crystal

Symbols in Crystal is quite different from Ruby.
In Crystal is a symbol a form of constants and is thereby is assigned at compile time.
Symbols in Crystal are quite different from Ruby.
In Crystal a symbol is a type of constant and is thereby is assigned at compile time.
This means that symbols can't be created dynamically, which is possible in Ruby.

Symbols in Crystal is represented as an `Int32` which makes very efficient.
Symbols in Crystal are represented as `Int32`s which makes them very efficient.

## Identifier

What makes symbols different from strings is that they are identifiers, and do not represent data or text.
What makes symbols different from strings is that they are identifiers and do not represent data or text.
This means that two symbols with the same name are always the same object.

```ruby
Expand All @@ -34,7 +34,7 @@ This means that two symbols with the same name are always the same object.
## Conversion

Symbols can be converted to strings but not vice versa.
This is because symbols are created at compile time, and strings are created at runtime.
This is because symbols are created at compile time and strings are created at runtime.

```crystal
:foo.to_s # => "foo"
Expand Down
5 changes: 5 additions & 0 deletions concepts/tuple/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"blurb": "Tuples are data structures which store a fixed number of elements. Tuples are indexable and immutable",
"authors": ["meatball133"],
"contributors": ["ryanplusplus"]
}
1 change: 1 addition & 0 deletions concepts/tuple/.meta/template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% $tuple \ $"tuple"."Tuples definition shorthand" %}
33 changes: 18 additions & 15 deletions concepts/tuples/about.md → concepts/tuple/about.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
# Tuples

A [tuple][tuple] is a finite ordered list of elements which is immutable.
Tuples requires all positions to have a fixed type this in turns means that the compiler knows what type each position is.
The types used in a tuple can be different, but the types must be known at compile time.
Tuples requires all positions to have a fixed type.
This in turns means that the compiler knows what type is at each position.
The types used in a tuple can be different at each position, but the types must be known at compile time.

## Creating a Tuple

Depending on if the tuples values types can be interprited under compilation, the tuple can be created in different ways.
It is also important that the types of the values match the types specified in the tuple and that the number of values match the number of types specified.
If the values are known at compile time, the tuple can be created using the tuple literal syntax.
Depending on if the tuples values types can be interpreted under compilation, the tuple can be created in different ways.
If the values are known at compile time, the tuple can be created using the tuple literal syntax, otherwise they need to be explicitly declared.
It is also important that the types of the values match the types specified in the tuple and that the number of values matches the number of types specified.
Here is an example of defning through tuple literal syntax:

```crystal
tuple = {1, "foo", 'c'} # Tuple(Int32, String, Char)
```

There is also possibility to create a tuple using the `Tuple` class.
There is also the possibility to create a tuple using the `Tuple` class.

```crystal
tuple = Tuple(Int32, String, Char).new(1, "foo", 'c')
Expand All @@ -26,7 +28,7 @@ Alternatively, you can explicitly specify the type of the variable assigned to t
tuple : Tuple(Int32, String, Char) = {1, "foo", 'c'}
```

Explicitly specifying the type of the tuple can be usefull since that allows for defining that a position should hold a union type.
Explicitly specifying the type of the tuple can be useful since that allows for defining that a position should hold a union type.
This means that a position can hold multiple types.

```crystal
Expand All @@ -48,6 +50,7 @@ tuple = Tuple(Int32, String, Char).from(array)
### Conversion to Array

You can convert a tuple to an array using the `to_a` method.
The resulting array's element type is the union of the type of each field in the tuple.

```crystal
tuple = {1, "foo", 'c'}
Expand Down Expand Up @@ -81,21 +84,21 @@ typeof(tuple[0]) # => Int32
```

Another difference when it comes to accessing elements from arrays is that if the index is specified, then the compiler will check that the index is within the bounds of the tuple.
Meaning you will get a compile time error instead of a runtime error.
This means you will get a compile time error instead of a runtime error.

```crystal
tuple = {1, "foo", 'c'}
tuple[3]
# => Error: index out of bounds for Tuple(Int32, String, Char) (3 not in -3..2)
```

However, if the index is stored in a variable, then the compiler will not be able to check if the index is within the bounds of the tuple at compile time and will as such give a runtime error.
However, if the index is stored in a variable, then the compiler will not be able to check if the index is within the bounds of the tuple at compile time and will instead give a runtime error.

## Subtuple

You can get a subtuple of a tuple by using the `[]` operator with a range.
What is returned is a new tuple with the elements from the range specified.
The range has to be given at compile time, since otherwise the compiler will not be able to know the types of the elements in the subtuple.
The range has to be given at compile time, otherwise the compiler will not be able to know the types of the elements in the subtuple.
This means that the range has to be a range literal and not assigned to a variable.

```crystal
Expand All @@ -109,11 +112,11 @@ tuple[i]

## When to use a Tuple

Tuples are useful when you want to group a fixed number of values together, where the types of the values are known at compile time.
This is because tuples require less memory and is faster than arrays due to the immutability of tuples.
Another use case is when you want to return multiple fixed values from a method.
This is particular helpful if the values have different types since each position in the tuple can have a different type.
Tuples are useful when you want to group a fixed number of values together where the types of the values are known at compile time.
This is because tuples require less memory and are faster than arrays due to the immutability of tuples.
Another use case is returning multiple values from a method.
This is particularly helpful if the values have different types since each position in the tuple can have a different type.

When to not use a Tuple is if a datastructure is needed that can grow or shrink in size or often needs to be modified.
Tuples should not be used when a data structure is needed that can grow or shrink in size or often needs to be modified.

[tuple]: https://crystal-lang.org/reference/syntax_and_semantics/literals/tuple.html
33 changes: 18 additions & 15 deletions concepts/tuples/introduction.md → concepts/tuple/introduction.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
# Tuples

A [tuple][tuple] is a finite ordered list of elements which is immutable.
Tuples requires all positions to have a fixed type this in turns means that the compiler knows what type each position is.
The types used in a tuple can be different, but the types must be known at compile time.
Tuples requires all positions to have a fixed type.
This in turns means that the compiler knows what type is at each position.
The types used in a tuple can be different at each position, but the types must be known at compile time.

## Creating a Tuple

Depending on if the tuples values types can be interprited under compilation, the tuple can be created in different ways.
It is also important that the types of the values match the types specified in the tuple and that the number of values match the number of types specified.
If the values are known at compile time, the tuple can be created using the tuple literal syntax.
Depending on if the tuples values types can be interpreted under compilation, the tuple can be created in different ways.
If the values are known at compile time, the tuple can be created using the tuple literal syntax, otherwise they need to be explicitly declared.
It is also important that the types of the values match the types specified in the tuple and that the number of values matches the number of types specified.
Here is an example of defning through tuple literal syntax:

```crystal
tuple = {1, "foo", 'c'} # Tuple(Int32, String, Char)
```

There is also possibility to create a tuple using the `Tuple` class.
There is also the possibility to create a tuple using the `Tuple` class.

```crystal
tuple = Tuple(Int32, String, Char).new(1, "foo", 'c')
Expand All @@ -26,7 +28,7 @@ Alternatively, you can explicitly specify the type of the variable assigned to t
tuple : Tuple(Int32, String, Char) = {1, "foo", 'c'}
```

Explicitly specifying the type of the tuple can be usefull since that allows for defining that a position should hold a union type.
Explicitly specifying the type of the tuple can be useful since that allows for defining that a position should hold a union type.
This means that a position can hold multiple types.

```crystal
Expand All @@ -48,6 +50,7 @@ tuple = Tuple(Int32, String, Char).from(array)
### Conversion to Array

You can convert a tuple to an array using the `to_a` method.
The resulting array's element type is the union of the type of each field in the tuple.

```crystal
tuple = {1, "foo", 'c'}
Expand All @@ -72,21 +75,21 @@ typeof(tuple[0]) # => Int32
```

Another difference when it comes to accessing elements from arrays is that if the index is specified, then the compiler will check that the index is within the bounds of the tuple.
Meaning you will get a compile time error instead of a runtime error.
This means you will get a compile time error instead of a runtime error.

```crystal
tuple = {1, "foo", 'c'}
tuple[3]
# => Error: index out of bounds for Tuple(Int32, String, Char) (3 not in -3..2)
```

However, if the index is stored in a variable, then the compiler will not be able to check if the index is within the bounds of the tuple at compile time and will as such give a runtime error.
However, if the index is stored in a variable, then the compiler will not be able to check if the index is within the bounds of the tuple at compile time and will instead give a runtime error.

## Subtuple

You can get a subtuple of a tuple by using the `[]` operator with a range.
What is returned is a new tuple with the elements from the range specified.
The range has to be given at compile time, since otherwise the compiler will not be able to know the types of the elements in the subtuple.
The range has to be given at compile time, otherwise the compiler will not be able to know the types of the elements in the subtuple.
This means that the range has to be a range literal and not assigned to a variable.

```crystal
Expand All @@ -100,11 +103,11 @@ tuple[i]

## When to use a Tuple

Tuples are useful when you want to group a fixed number of values together, where the types of the values are known at compile time.
This is because tuples require less memory and is faster than arrays due to the immutability of tuples.
Another use case is when you want to return multiple fixed values from a method.
This is particular helpful if the values have different types since each position in the tuple can have a different type.
Tuples are useful when you want to group a fixed number of values together where the types of the values are known at compile time.
This is because tuples require less memory and are faster than arrays due to the immutability of tuples.
Another use case is returning multiple values from a method.
This is particularly helpful if the values have different types since each position in the tuple can have a different type.

When to not use a Tuple is if a datastructure is needed that can grow or shrink in size or often needs to be modified.
Tuples should not be used when a data structure is needed that can grow or shrink in size or often needs to be modified.

[tuple]: https://crystal-lang.org/reference/syntax_and_semantics/literals/tuple.html
File renamed without changes.
5 changes: 0 additions & 5 deletions concepts/tuples/.meta/config.json

This file was deleted.

1 change: 0 additions & 1 deletion concepts/tuples/.meta/template.md

This file was deleted.

8 changes: 4 additions & 4 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,11 @@
},
{
"slug": "kitchen-calculator",
"name": "Kitcen Calculator",
"name": "Kitchen Calculator",
"uuid": "e7250ff1-967d-4b5d-8fa8-a57fdbbe24c5",
"concepts": [
"symbol",
"tuples"
"tuple"
],
"prerequisites": [
"iteration"
Expand Down Expand Up @@ -1593,8 +1593,8 @@
},
{
"uuid": "a36e93cb-5ab0-4693-a6ab-ce698a3550ce",
"slug": "tuples",
"name": "Tuples"
"slug": "tuple",
"name": "Tuple"
},
{
"uuid": "268c4865-1a15-4f65-88d9-5a1bb1ba5ac4",
Expand Down
4 changes: 2 additions & 2 deletions exercises/concept/kitchen-calculator/.docs/hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

## General

- [Tuples][tuple] are data structures which are inmutable, have a fixed size, and can hold any data-type.
- Symbols may be used to denote finite states, as this exercise uses `:cup`, `:fluid_ounce`, `:teaspoon`, `:tablespoon`, `:milliliter` to denote the units used.
- [Tuples][tuple] are data structures which are immutable, have a fixed size, and can hold any data-type.
- Symbols may be used to denote finite states: this exercise uses `:cup`, `:fluid_ounce`, `:teaspoon`, `:tablespoon`, `:milliliter` to denote the units used.

## 1. Get the numeric component from a volume-pair

Expand Down
4 changes: 2 additions & 2 deletions exercises/concept/kitchen-calculator/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Instructions

While preparing to bake cookies for your friends, you have found that you have to convert some of the measurements used in the recipe.
Being only familiar with the metric system, you need to come up with a way to convert common US baking measurements to milliliters (mL) for your own ease.
Only being familiar with the metric system, you need to come up with a way to convert common US baking measurements to milliliters (mL) for your own ease.

Use this conversion chart for your solution:

Expand Down Expand Up @@ -53,4 +53,4 @@ Given a volume-pair tuple and the desired unit, it should convert the given volu
```crystal
KitchenCalculator.convert({:teaspoon, 9.0}, :tablespoon)
# => {:tablespoon, 3.0}
```
```
Loading

0 comments on commit 7cec5cf

Please sign in to comment.