From fb403858fe5d3a9ee136c956807bb00d5b8d6963 Mon Sep 17 00:00:00 2001 From: Abdullah Alhusaini Date: Wed, 3 May 2023 19:21:27 +0300 Subject: [PATCH 1/2] fixed typo and explained what generics do better --- docs/syntax_and_semantics/generics.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/syntax_and_semantics/generics.md b/docs/syntax_and_semantics/generics.md index cb8c68f58..6de96dc74 100644 --- a/docs/syntax_and_semantics/generics.md +++ b/docs/syntax_and_semantics/generics.md @@ -1,6 +1,6 @@ # Generics -Generics allow you to parameterize a type based on other type. Consider a Box type: +Generics allow you to parameterize a type based on another type. Generics provide type-polymorphism. Consider a Box type: ```crystal class MyBox(T) @@ -48,9 +48,9 @@ string_box = MyBox.new("hello") # : MyBox(String) In the above code we didn't have to specify the type arguments of `MyBox`, the compiler inferred them following this process: -* The compiler generates a `MyBox.new(value : T)` method, which has no explicitly defined free variables, from `MyBox#initialize(@value : T)` -* The `T` in `MyBox.new(value : T)` isn't bound to a type yet, and `T` is a type parameter of `MyBox`, so the compiler binds it to the type of the given argument -* The compiler-generated `MyBox.new(value : T)` calls `MyBox(T)#initialize(@value : T)`, where `T` is now bound +- The compiler generates a `MyBox.new(value : T)` method, which has no explicitly defined free variables, from `MyBox#initialize(@value : T)` +- The `T` in `MyBox.new(value : T)` isn't bound to a type yet, and `T` is a type parameter of `MyBox`, so the compiler binds it to the type of the given argument +- The compiler-generated `MyBox.new(value : T)` calls `MyBox(T)#initialize(@value : T)`, where `T` is now bound In this way generic types are less tedious to work with. Note that the `#initialize` method itself does not need to specify any free variables for this to work. From 770580a29911c3de448f317da56951d7a76bef26 Mon Sep 17 00:00:00 2001 From: Abdullah Alhusaini Date: Sat, 6 May 2023 00:04:46 +0300 Subject: [PATCH 2/2] added heading --- docs/syntax_and_semantics/modules.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/syntax_and_semantics/modules.md b/docs/syntax_and_semantics/modules.md index fdee1ed47..e7f0948f1 100644 --- a/docs/syntax_and_semantics/modules.md +++ b/docs/syntax_and_semantics/modules.md @@ -2,8 +2,8 @@ Modules serve two purposes: -* as namespaces for defining other types, methods and constants -* as partial types that can be mixed in other types +- as namespaces for defining other types, methods and constants +- as partial types that can be mixed in other types An example of a module as a namespace: @@ -18,6 +18,8 @@ Curses::Window.new Library authors are advised to put their definitions inside a module to avoid name clashes. The standard library usually doesn't have a namespace as its types and methods are very common, to avoid writing long names. +## `extend` and `include` + To use a module as a partial type you use `include` or `extend`. An `include` makes a type include methods defined in that module as instance methods: