Browse Source

- Add metadata to markdown file
- Update docs on functions(topic variables, multi-dispatching)
- Update docs on traits in classes

tcheukueppo 2 years ago
parent
commit
19cd15fb85
1 changed files with 114 additions and 64 deletions
  1. 114 64
      docs/maat_dev_ref/maat.md

+ 114 - 64
docs/maat_dev_ref/maat.md

@@ -1,3 +1,9 @@
+---
+title: Maat Programming Language Specification
+author: Kueppo Tcheukam J. W.
+email: tcheukueppo@yandex.com
+---
+
 # Maat 
 
 `Maat` is a multi-paradigm general purpose programming language that empowers
@@ -34,7 +40,7 @@ for its for implementation.
 - `-`: (b) negate the operand
 - `+`: (b) 
 - `~`: (b) binary complement
-- `…` or `...`: (b) Array destruction operator in the context of list assingments and function calls
+- `…` or `...`: (b) Destructing operator in assignments and Accumulator operator in functions
 - `^`: (p) `^5` return an array of element i.e from `0` to `5`
 - `√`: (p) sqaure root operator
 - `⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹`: (b) super-script power operators
@@ -44,7 +50,8 @@ for its for implementation.
 - `defined`: (b) check if a varible is `nil` and return true otherwise
 - `sleep`: (b) call sleep() syscall
 - `return`: (b) return from a function
-- `exit`: exit program with given exit code
+- `assert`: (b) test an assertion
+- `exit`: (b) exit program with given exit code
 
 ## Named list operators
 
@@ -193,12 +200,12 @@ made to temporal variables remains local to the scope from where it was declare
 thus the referenced variables remains untouched. You cannot localize lexically scoped
 variables.
 
-Declare package variables with the keyword `global`, lexically scoped variables
+Declare package variables with the keyword `pkg`, lexically scoped variables
 with `var` and temporal variable with `temp`.
 
 ```js
 package One::Two {
-    glob x = a<one two three>
+    pkg x = qa<one two three>
 
     var a = { one => 1 }
     {
@@ -308,33 +315,34 @@ like simple variable we use in our Maat programs
 
 Maat has ... builtin objects, types are objects and objects are types, check details on each types here.
 
-- Any
-- Bool
-- Num
-- Str
-- Range
-- Array
-- Map
-- Set
-- MSet
-- Bag
-- MBag
-- Lazy
-- Fun
-- Regex
-- Ma
-- Work
-- Chan
-- Socket
-- Socket::Work
-- Proc
-- Proc::Work
-- Pipe
-- File
-- Dir
-- Date
-- Sys
-- Term
+- [`Any`](./objects/Any.md)
+- [`Bool`](./objects/Bool.md)
+- [`Num`](./objects/Num.md)
+- [`Str`](./objects/Str.md)
+- [`Range`](./objects/Range.md)
+- [`Array`](./objects/Array.md)
+- [`Map`](./objects/Map.md)
+- [`Set`](./objects/Set.md)
+- [`MSet`](./objects/MSet.md)
+- [`Bag`](./objects/Bag.md)
+- [`MBag`](./objects/MBag.md)
+- [`Lazy`](./objects/Lazy.md)
+- [`Fun`](./objects/Fun.md)
+- [`GFun`](./objects/GFun.md)
+- [`Regex`](./objects/Regex.md)
+- [`Ma`](./objects/Ma.md)
+- [`Work`](./objects/Work.md)
+- [`Chan`](./objects/Chan.md)
+- [`Socket`](./objects/Socket.md)
+- [`Socket::Work`](./objects/Socket::Work.md)
+- [`Proc`](./objects/Proc.md)
+- [`Proc::Work`](./objects/Proc::Work.md)
+- [`Pipe`](./objects/Pipe.md)
+- [`File`](./objects/File.md)
+- [`Dir`](./objects/Dir.md)
+- [`Date`](./objects/Date.md)
+- [`Sys`](./objects/Sys.md)
+- [`Term`](./objects/Term.md)
 
 **NB**: Take note of the following conventions about syntax definition
 
@@ -554,7 +562,7 @@ for a.lazy
 
 7. Generator function with `take`
 
-A generator 
+A generator function
 
 The `take` keyword pauses generator function execution and the 
 
@@ -767,30 +775,45 @@ sleep
 
 ## topic variable `_`
 
-The type I variable `_` is called a topic variable, this variable operates on anonymous
-functions and flow control blocks. Its usage in an anonymous function directly implies
-that the anonymous function in question is supposed to recieved a single argument when
-called but that argument was unamed and hence `_` defaults to it.
+The type I variable `_` is called a topic variable, this variable operates on
+anonymous functions and flow control blocks. The usage of a topic variable when
+calling an anonymous function implies the anonymous function takes a single
+argument whose parameter wasn't explicitly declared with `|...|` and hence
+defaults to `_`.
 
-You can omit the name of the topic variable when calling a method on the content it refers to.
+It is possible to omit `_` when calling a method on the content of the topic
+variable.
+
+```raku
+var anony = { say _.Str * 2 }
+
+# Output: tanzaniatanzania
+anony.call("tanzania")
+
+# Err: takes only one arg as the topic var is used in anony
+anony.call("a", "b")
 
-```
 # .ucfirst is the same as _.ucfirst
 var ar = qm{tcheukam madjou monthe}
 say ar.map({.ucfirst})
+```
+
+The topic variable in an anonymous function with declared or expecting no
+parameters refers to if exists from outer scopes.
 
+The method `.times` of the `Num` type expects no argument when called and thus
+refers to the topic variable from the lowest level outer scope.
+
+```raku
 # Output: 88888888 666666 666666
 ar.map(:.len).each { .times { .print } }
 ```
 
-```
-```
-
-Maat has support for multiple dispatching and named arguments. Mixing named arguments
-with unnamed ones brings a lot of confusion in your code and hence either you name all
-your arguments or you don't name anything at all.
+Maat has support for multiple dispatching and named arguments. Mixing named
+arguments with unnamed ones brings a lot of confusion in your code and hence
+either you name all your arguments or you don't name anything at all.
 
-```
+```ruby
 fun call(c, n) { c.call(_) for ^n }
 call({ .say }, 5)
 
@@ -814,18 +837,39 @@ fun mul(s)    { s * 2 }
 
 mul("one").say    # Output: oneone
 mul("two", 5).say # Output: twotwotwotwo
+```
+
+Maat has what we call an accumulator and destructor operator, let us cover
+everything here. The accumulator operator is a postfix operator used to collect
+the rest of extra indefinite number of arguments as an array into the last
+declared parameter of that called function/method. This is done by appending
+`…` to the last declared parameter at function definition.
 
+```
 # using the array accumulator operator for variadic arguments
-fun count(name, counts…) {
-    printfln "You have %d %ss", counts.sum, name
+fun count(name, counts) {
+    printf "You have %d %ss\n", count.len > 0 ? counts.sum : 0, name
 }
 
-count("pineaple", 2, 4, 10)
+count("pineaple", 2, 4, 10) # Output: "You have 16 pineaples"
+count("orange")             # Output: "You have 0 oranges"
+
+fun sum(...ar) { ar.sum }
+
+# does not make sense, fails at compilation
+fun bad_func(a, ...b, c)    { ... }
+fun bad_func(...a, b, ...c) { ... }
+fun bad_func(a, ...b, ...c) { ... }
 ```
 
-Function as well as methods do have support for the `save` trait, the `save` trait
-caches the return value of the function for letter retrieval if another call was
-made
+The destructor operator on the other hand is
+
+## Traits
+
+Functions as well as methods support the `:save` trait, the `:save` trait
+caches the return value of a function call to avoid recomputation of the
+same function call in recursive calls. This trait can help you do dynamic
+programming with less overhead.
 
 ```
 fun fib(n) :save {
@@ -837,18 +881,25 @@ fun fib(n) :save {
 
 ```
 role D { ... }
-role E { ... }
+
+role E {
+}
 
 class B { ... }
 class C { ... }
 
 # "is" for inheritance and "does" for roles
 class A :is(B, C) :does(D, E) {
-    has x :ro     # read-only attribute, ro: say A.x; not possible: A.x = "some value"
-    has y :rw = 0 # read-write attribute with default value '0', write: A.y = 2; read: say A.y
-    has z         # 
+    # read-only attribute, ro: say A.x; not possible: A.x = "some value"
+    has x :ro   
 
-    state count = 0 # static variable which is accessible to all objects via class 'A': A.count
+    # read-write attribute with default value '0', write: A.y = 2; read: say A.y
+    has y :rw = 0
+
+    has z
+
+    # static variable which is accessible to all objects via class 'A': A.count
+    state count = 0
 
     # static method (A.m()), self isn't valid here
     state meth m() {
@@ -860,23 +911,22 @@ class A :is(B, C) :does(D, E) {
         ...
     }
 
-    mul meth amethod() {}
+    mul meth amethod() { ... }
 
     # takes a parameter x
-    mul meth amethod(x) {}
+    mul meth amethod(x) { ... }
 
     # defining a method 'priv' as private, oi means only-in
-    meth priv() :oi {}
+    meth priv() :oi { ... }
 }
 ```
 
 List of traits supported by class attributes
 
-- `rw`: Attribute is read-write
-- `ro`: Attribute is read-only
-- `built`: Make attribute private but can only also be written from outside the object only via object instanciation
-
-We also have the `oi` trait which makes a method private
+- `rw`: Make attribute read-write
+- `ro`: Make attribute read-only
+- `built`: Make attribute private but can be set when instanciating
+- `oi`: Make method private to the class
 
 To every object is associated a metaobject which permits object introspection, given an object
 `obj`, you can introspect this method via its metaobject by using the `.^` method call operator.