Skip to content

Commit

Permalink
Migrate doc comments to use '///' (#628)
Browse files Browse the repository at this point in the history
In preparation for @BinderDavid's #624,
I went through the stdlib
and tried to change doc comments to use `///` :)
  • Loading branch information
jiribenes authored Oct 4, 2024
1 parent 358316a commit 3e88cd9
Show file tree
Hide file tree
Showing 15 changed files with 479 additions and 614 deletions.
70 changes: 23 additions & 47 deletions libraries/common/array.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@ import effekt
import exception
import list

/**
* A mutable 0-indexed fixed-sized array.
*/
/// A mutable 0-indexed fixed-sized array.
extern type Array[T]

/**
* Allocates a new array of size `size`, keeping its values _undefined_.
* Prefer using `array` constructor instead to ensure that values are defined.
*/
/// Allocates a new array of size `size`, keeping its values _undefined_.
/// Prefer using `array` constructor instead to ensure that values are defined.
extern global def allocate[T](size: Int): Array[T] =
js "(new Array(${size}))"
chez "(make-vector ${size})" // creates an array filled with 0s on CS
Expand All @@ -21,9 +17,7 @@ extern global def allocate[T](size: Int): Array[T] =
ret %Pos %z
"""

/**
* Creates a new Array of size `size` filled with the value `init`
*/
/// Creates a new Array of size `size` filled with the value `init`
def array[T](size: Int, init: T): Array[T] = {
val arr = allocate[T](size);
each(0, size) { i =>
Expand All @@ -32,9 +26,7 @@ def array[T](size: Int, init: T): Array[T] = {
arr
}

/**
* Converts a List `list` to an Array
*/
/// Converts a List `list` to an Array
def fromList[T](list: List[T]): Array[T] = {
val listSize = list.size();
val arr = allocate(listSize);
Expand All @@ -45,9 +37,7 @@ def fromList[T](list: List[T]): Array[T] = {
return arr;
}

/**
* Gets the length of the array in constant time.
*/
/// Gets the length of the array in constant time.
extern pure def size[T](arr: Array[T]): Int =
js "${arr}.length"
chez "(vector-length ${arr})"
Expand All @@ -56,12 +46,10 @@ extern pure def size[T](arr: Array[T]): Int =
ret %Int %z
"""

/**
* Gets the element of the `arr` at given `index` in constant time.
* Unchecked Precondition: `index` is in bounds (0 ≤ index < arr.size)
*
* Prefer using `get` instead.
*/
/// Gets the element of the `arr` at given `index` in constant time.
/// Unchecked Precondition: `index` is in bounds (0 ≤ index < arr.size)
///
/// Prefer using `get` instead.
extern global def unsafeGet[T](arr: Array[T], index: Int): T =
js "${arr}[${index}]"
chez "(vector-ref ${arr} ${index})"
Expand All @@ -77,12 +65,10 @@ extern js """
}
"""

/**
* Sets the element of the `arr` at given `index` to `value` in constant time.
* Unchecked Precondition: `index` is in bounds (0 ≤ index < arr.size)
*
* Prefer using `set` instead.
*/
/// Sets the element of the `arr` at given `index` to `value` in constant time.
/// Unchecked Precondition: `index` is in bounds (0 ≤ index < arr.size)
///
/// Prefer using `set` instead.
extern global def unsafeSet[T](arr: Array[T], index: Int, value: T): Unit =
js "array$set(${arr}, ${index}, ${value})"
chez "(begin (vector-set! ${arr} ${index} ${value}) #f)"
Expand All @@ -91,9 +77,7 @@ extern global def unsafeSet[T](arr: Array[T], index: Int, value: T): Unit =
ret %Pos %z
"""

/**
* Creates a copy of `arr`
*/
/// Creates a copy of `arr`
def copy[T](arr: Array[T]): Array[T] = {
with on[OutOfBounds].default { <> }; // should not happen
val len = arr.size;
Expand All @@ -102,10 +86,8 @@ def copy[T](arr: Array[T]): Array[T] = {
newArray
}

/**
* Copies `length`-many elements from `from` to `to`
* starting at `start` (in `from`) and `offset` (in `to`)
*/
/// Copies `length`-many elements from `from` to `to`
/// starting at `start` (in `from`) and `offset` (in `to`)
def copy[T](from: Array[T], start: Int, to: Array[T], offset: Int, length: Int): Unit / Exception[OutOfBounds] = {
val startValid = start >= 0 && start + length <= from.size
val offsetValid = offset >= 0 && offset + length <= to.size
Expand All @@ -122,26 +104,20 @@ def copy[T](from: Array[T], start: Int, to: Array[T], offset: Int, length: Int):

// Derived operations:

/**
* Gets the element of the `arr` at given `index` in constant time,
* throwing an `Exception[OutOfBounds]` unless `0 ≤ index < arr.size`.
*/
/// Gets the element of the `arr` at given `index` in constant time,
/// throwing an `Exception[OutOfBounds]` unless `0 ≤ index < arr.size`.
def get[T](arr: Array[T], index: Int): T / Exception[OutOfBounds] =
if (index >= 0 && index < arr.size) arr.unsafeGet(index)
else do raise(OutOfBounds(), "Array index out of bounds: " ++ show(index))

/**
* Sets the element of the `arr` at given `index` to `value` in constant time,
* throwing an `Exception[OutOfBounds]` unless `0 ≤ index < arr.size`.
*/
/// Sets the element of the `arr` at given `index` to `value` in constant time,
/// throwing an `Exception[OutOfBounds]` unless `0 ≤ index < arr.size`.
def set[T](arr: Array[T], index: Int, value: T): Unit / Exception[OutOfBounds] =
if (index >= 0 && index < arr.size) unsafeSet(arr, index, value)
else do raise(OutOfBounds(), "Array index out of bounds: " ++ show(index))

/**
* Builds a new Array of size `size` from a computation `index` which gets an index
* and returns a value that will be on that position in the resulting array
*/
/// Builds a new Array of size `size` from a computation `index` which gets an index
/// and returns a value that will be on that position in the resulting array
def build[T](size: Int) { index: Int => T }: Array[T] = {
val arr = allocate[T](size);
each(0, size) { i =>
Expand Down
30 changes: 11 additions & 19 deletions libraries/common/bench.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ module bench

type Nanos = Int

/**
* The current time (since UNIX Epoch) in nanoseconds.
*
* The actual precision varies across the different backends.
* - js: Milliseconds
* - chez: Microseconds
*/
/// The current time (since UNIX Epoch) in nanoseconds.
///
/// The actual precision varies across the different backends.
/// - js: Milliseconds
/// - chez: Microseconds
extern io def timestamp(): Nanos =
js "Date.now() * 1000000"
chez "(timestamp)"
Expand All @@ -32,12 +30,10 @@ extern jsNode """
const { performance } = require('node:perf_hooks');
"""

/**
* High-precision timestamp in nanoseconds that should be for measurements.
*
* This timestamp should only be used for **relative** measurements,
* as gives no guarantees on the absolute time (unlike a UNIX timestamp).
*/
/// High-precision timestamp in nanoseconds that should be for measurements.
///
/// This timestamp should only be used for **relative** measurements,
/// as gives no guarantees on the absolute time (unlike a UNIX timestamp).
extern io def relativeTimestamp(): Nanos =
js "Math.round(performance.now() * 1000000)"
default { timestamp() }
Expand All @@ -48,9 +44,7 @@ namespace Duration {
def diff(fromNanos: Nanos, toNanos: Nanos): Duration = toNanos - fromNanos
}

/**
* Runs the block and returns the time in nanoseconds
*/
/// Runs the block and returns the time in nanoseconds
def timed { block: => Unit }: Duration = {
val before = relativeTimestamp()
block()
Expand All @@ -70,9 +64,7 @@ def measure(warmup: Int, iterations: Int) { block: => Unit }: Unit = {
run(iterations, true)
}

/**
* Takes a duration in nanoseconds and formats it in milliseconds with precision of two decimal digits.
*/
/// Takes a duration in nanoseconds and formats it in milliseconds with precision of two decimal digits.
def formatMs(nanos: Nanos): String = {
val micros = nanos / 1000000
val sub = (nanos.mod(1000000).toDouble / 10000.0).round
Expand Down
28 changes: 8 additions & 20 deletions libraries/common/buffer.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,22 @@ import array

record BufferOverflow()

/**
* Fixed-size ring buffers (queues) where one can write
* elements to the head and read from the tail.
*/
/// Fixed-size ring buffers (queues) where one can write
/// elements to the head and read from the tail.
interface Buffer[T] {
/**
* The remaining capacity
*/
/// The remaining capacity
def capacity(): Int

/**
* Is this buffer full?
*/
/// Is this buffer full?
def full?(): Bool

/**
* Is this buffer empty?
*/
/// Is this buffer empty?
def empty?(): Bool

/**
* Read an element from the tail of the buffer
*/
/// Read an element from the tail of the buffer
def read(): Option[T]

/**
* Write an element to the head of the buffer
*/
/// Write an element to the head of the buffer
def write(el: T): Unit / Exception[BufferOverflow]
}

Expand Down Expand Up @@ -120,4 +108,4 @@ namespace examples {
println(ringbuffer.read());
println(ringbuffer.read());
}
}
}
20 changes: 5 additions & 15 deletions libraries/common/bytes.effekt
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
module bytes

/**
* A memory managed, mutable, fixed-length buffer of bytes.
*/
/// A memory managed, mutable, fixed-length buffer of bytes.
extern type Bytes
// = llvm "%Pos"
// = js "Uint8Array"

/**
* Allocates new bytes with the given `capacity`, setting its values to `0`.
*/
/// Allocates new bytes with the given `capacity`, setting its values to `0`.
extern io def bytes(capacity: Int): Bytes =
js "(new Uint8Array(${capacity}))"
llvm """
Expand Down Expand Up @@ -55,9 +51,7 @@ extern io def write(b: Bytes, index: Int, value: Byte): Unit =
ret %Pos zeroinitializer
"""

/**
* Returns an *aliased* slice of b starting at offset with the given length
*/
/// Returns an *aliased* slice of b starting at offset with the given length
def slice(b: Bytes, offset: Int, length: Int): Bytes = {
def validOffset() = offset >= 0 && offset < b.size
def validLength() = length >= 0 && (offset + length) <= b.size
Expand All @@ -66,9 +60,7 @@ def slice(b: Bytes, offset: Int, length: Int): Bytes = {
}


/**
* Returns a view into the buffer, with the length truncated to n
*/
/// Returns a view into the buffer, with the length truncated to n
def truncated(b: Bytes, n: Int): Bytes =
b.slice(0, n)

Expand All @@ -88,9 +80,7 @@ extern pure def toUTF8(b: Bytes): String =
"""

namespace unsafe {
/**
* Unsafe: offset and length are not checked.
*/
/// Unsafe: offset and length are not checked.
extern io def slice(b: Bytes, offset: Int, length: Int): Bytes =
js "new Uint8Array(${b}.buffer, ${offset}, ${length})"
llvm """
Expand Down
10 changes: 5 additions & 5 deletions libraries/common/dequeue.effekt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module dequeue


// An implementation of a functional dequeue, using Okasaki's
// bankers dequeue implementation.
//
// Translation from the Haskell implementation:
// https://hackage.haskell.org/package/dequeue-0.1.12/docs/src/Data-Dequeue.html#Dequeue
/// An implementation of a functional dequeue, using Okasaki's
/// bankers dequeue implementation.
///
/// Translation from the Haskell implementation:
/// https://hackage.haskell.org/package/dequeue-0.1.12/docs/src/Data-Dequeue.html#Dequeue
record Dequeue[R](front: List[R], frontSize: Int, rear: List[R], rearSize: Int)

def emptyQueue[R](): Dequeue[R] = Dequeue(Nil(), 0, Nil(), 0)
Expand Down
36 changes: 13 additions & 23 deletions libraries/common/effekt.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,12 @@ extern io def random(): Double =

// Equality
// ========
/**
* Result of comparison between two objects according to some order:
*
* - `Less()` means that the first object is *before* the first in the order,
* - `Equal()` means that the two objects are the same in the order,
* - and `Greater()` means that the second object is *before* the first in the order.
*/

/// Result of comparison between two objects according to some order:
///
/// - `Less()` means that the first object is *before* the first in the order,
/// - `Equal()` means that the two objects are the same in the order,
/// - and `Greater()` means that the second object is *before* the first in the order.
type Ordering {
Less();
Equal();
Expand All @@ -160,7 +159,8 @@ type Ordering {
extern pure def genericCompareImpl[R](x: R, y: R): Int =
js "$effekt.compare(${x}, ${y})"

// Compares two values of the same type, returning an `Ordering`.
/// Compares two values of the same type, returning an `Ordering`.
/// Only available on the JavaScript backend.
def genericCompare[R](x: R, y: R): Ordering = {
genericCompareImpl(x, y) match {
case -1 => Less()
Expand All @@ -182,9 +182,7 @@ def println(o: Ordering): Unit = println(o.show)
// Comparison ops
// ==============

/**
* Structural equality: Not available in the LLVM backend
*/
/// Structural equality: Not available in the LLVM backend
extern pure def equals[R](x: R, y: R): Bool =
js "$effekt.equals(${x}, ${y})"
chez "(equal? ${x} ${y})"
Expand Down Expand Up @@ -594,16 +592,12 @@ extern pure def toInt(n: Byte): Int =
// chez: #f
// llvm: null?

/**
* The value used by the FFI to represent undefined values
*/
/// The value used by the FFI to represent undefined values
extern pure def undefined[A](): A =
js "undefined"
chez "#f"

/**
* Is an FFI value undefined?
*/
/// Is an FFI value undefined?
extern pure def isUndefined[A](value: A): Bool =
js "(${value} === undefined || ${value} === null)"
chez "(eq? ${value} #f)"
Expand Down Expand Up @@ -638,19 +632,15 @@ def loop { f: {Control} => Unit }: Unit = try {
def continue() = loop { f }
}

/**
* Calls provided action repeatedly. `start` is inclusive, `end` is not.
*/
/// Calls provided action repeatedly. `start` is inclusive, `end` is not.
def each(start: Int, end: Int) { action: (Int) => Unit } = {
def loop(i: Int): Unit =
if (i < end) { action(i); loop(i + 1) }

loop(start)
}

/**
* Calls provided action repeatedly with support for breaking. `start` is inclusive, `end` is not.
*/
/// Calls provided action repeatedly with support for breaking. `start` is inclusive, `end` is not.
def each(start: Int, end: Int) { action: (Int) {Control} => Unit } = {
var i = start;
loop { {l} =>
Expand Down
Loading

0 comments on commit 3e88cd9

Please sign in to comment.