diff options
Diffstat (limited to 'std/default')
-rw-r--r-- | std/default/format.pk | 51 | ||||
-rw-r--r-- | std/default/iterators.pk | 38 | ||||
-rw-r--r-- | std/default/options.pk | 18 | ||||
-rw-r--r-- | std/default/results.pk | 22 |
4 files changed, 111 insertions, 18 deletions
diff --git a/std/default/format.pk b/std/default/format.pk new file mode 100644 index 0000000..c7d7ab8 --- /dev/null +++ b/std/default/format.pk @@ -0,0 +1,51 @@ +## std/format: Niceties around printing and debugging. +## This module is imported by default. + +## The Display interface. Any type implementing `str` is printable. +## Any type that is Display must also implement Debug. +pub type Display = interface + str(Self): str + dbg(Self): str + +## The Debug interface. Broadly implemented for every type with magic, +## types can (and should) override the generic implementations. +pub type Debug = interface + dbg(Self): str + +## Prints all of its arguments to the command line. +pub func print(params: varargs[Display]) = + stdout.write(params.map(x => x.str).join(" "), "\n") + +## Prints all of its arguments to the command line, in Debug form. +pub func dbg(params: varargs[Debug]) = + stdout.write(params.map(x => x.dbg).join(" "), "\n") + +## A dummy implementation of the Display interface for strings. +pub func str(self: str): str = self +## An implementation of the Debug interface for strings. +pub func dbg(self: str): str = "\"" & self & "\"" + +## An implementation of the Debug interface for all structs. +## Uses the special `struct` typeclass. +pub func dbg(self: struct): str = + "{" & self.fields.map(field => field.id & field.value.dbg) & "}" + +## An implementation of the Debug interface for all tuples. +## Uses the special `tuple` typeclass. +pub func dbg(self: tuple): str = + result &= "(" + for i, field in self.fields.enumerate(): + result &= field.id.map(id => id & " = ").get_or("") + if i != self.fields.len: + result &= ", " + result &= ")" + +## An implementation of the Debug interface for all arrays and lists. +pub func dbg(self: Iter[Debug]): str = + "[" & self.map(x => x.str).join(", ") & "]" + +## The fmt macro. Builds a formatted string from its arguments. +pub macro fmt(formatted: static[str], args: varargs[Display]) = + # if not formatted of String: + # macro_error("fmt must take a static string parameter!") + ... diff --git a/std/default/iterators.pk b/std/default/iterators.pk new file mode 100644 index 0000000..f97c61a --- /dev/null +++ b/std/default/iterators.pk @@ -0,0 +1,38 @@ +## std/iterators: The Iter interface and associated functions. +## This module is imported by default. + +## The Iter interface. Any type implementing `next()` is iterable. +pub type Iter[T] = interface + next(mut Self): Option[T] + +# todo: useful functions for an iterator +# https://doc.rust-lang.org/std/iter/trait.Iterator.html#provided-methods + +pub func advance_by[T](self: Iter[T], n: uint): Result[T, ...] = + for i in 0 .. n: + if self.next().is_none(): + return Error(...) + Okay + +pub func get[T](self: Iter[T], at: uint): Option[T] + self.advance_by(at-1).ok? + self.next() + +# todo: implement iter[T](self: ...): Iter[T] funcs +# todo: efficient functional methods + +## The Peek interface. Any type implementing Iter, `peek`, and `peek_nth` is peekable. +pub type Peek[T] = interface + next(mut Self): Option[T] + peek(mut Self): Option[T] + peek_nth(mut Self, n: uint): Option[T] + +# todo: implement peek[T](self: Iter[T]): Peek[T] +# todo: implement Peekable struct +# https://github.com/LukeMathWalker/multipeek/blob/main/src/lib.rs + +## We don't want a Countable. It's not terribly useful. +# pub type Countable[T] = interface +# next(mut Self): Option[T] +# len(Self): uint +# get(Self, uint): Option[T] diff --git a/std/default/options.pk b/std/default/options.pk index f1bcac4..3aaea49 100644 --- a/std/default/options.pk +++ b/std/default/options.pk @@ -1,4 +1,4 @@ -## std/options +## std/options: Optional types. ## This module is imported by default. import std/format @@ -47,20 +47,20 @@ pub func flatten[T](self: Option[Option[T]]): Option[T] = # todo: better name? None ## Returns the inner value or a default. -pub func or[T](self: Option[T], default: T): T = +pub func get_or[T](self: Option[T], default: T): T = if self of Some(x): x else: default ## Directly accesses the inner value. Throws an exception if None. -pub yeet func get[T](self: Option[T]): T = +pub yeet func `!`[T](self: Option[T]): T = if self of Some(x): x else: raise Exception # todo: syntax?? -# todo: direct access, alias to get -macro `!`[T](self: Option[T]): T -# todo: indirect access, ??? do we propagate? is this useful? probably not -macro `?`[T](self: Option[T]): T -# todo: field access? useful? assignment? -macro `.?`[T](self: Option[T]) +## Indirect access. Propagates None. +pub macro `?`[T](self: Option[T]) = + quote: + match self + of Some(x): x + of None: return None ## Overloads the == operation for use on Options. pub func `==`[T](a, b: Option[T]): bool = diff --git a/std/default/results.pk b/std/default/results.pk index 2ac47d0..187ece9 100644 --- a/std/default/results.pk +++ b/std/default/results.pk @@ -1,4 +1,4 @@ -## std/results +## std/results: Result types. ## This module is imported by default. import std/[options, format] @@ -7,9 +7,11 @@ pub type Result[T, E] = union Okay: T Error: E +# todo: determine the difference between interfaces and types +# ErrorInterface? Errorable? Err? pub type Error = interface - func str(self: Self) - func dbg(self: Self) + str(Self): str + dbg(Self): str pub type Result[T] = Result[T, ref Error] @@ -79,11 +81,11 @@ pub func transpose[T, E](self: Option[Result[T, E]], error: E): Result[Option[T] Error(error) ## Returns the inner value or a default. -pub func or[T, E](self: Result[T, E], default: T): T = +pub func get_or[T, E](self: Result[T, E], default: T): T = if self of Okay(x): x else: default ## Directly accesses the inner value. Throws an exception if Error(e). -pub yeet func get[T, E](self: Result[T, E]): T = +pub yeet func `!`[T, E](self: Result[T, E]): T = match self of Okay(x): x of Error(e): raise Exception(e) # todo: syntax?? @@ -92,10 +94,12 @@ pub yeet func get_err[T, E](self: Result[T, E]): E = of Error(e): e of Okay(x): raise Exception(x) # todo: syntax?? -# todo: direct access, alias to get -macro `!`[T, E](self: Result[T, E]): T -# todo: indirect access, propagates Err -macro `?`[T, E](self: Result[T]): T +## Indirect access. Propagates Error. +macro `?`[T, E](self: Result[T, E]) = + quote: + match self + of Okay(x): x + of Error(e): return Error(e) ## Overloads the == operation for use on Results. pub func `==`[T, E, F](a: Result[T, E], b: Result[T, F]): bool = |