Pen is the parallel, concurrent, and functional programming language focused on application programming following Go's philosophy. It aims for further simplicity, testability, and portability to empower team (v. individual) and/or long-term (v. short-term) productivity.
Pen provides the two built-in functions of go
and race
to construct concurrent/parallel computation. Thanks to its syntax, type system, and the state-of-the-art reference counting garbage collection, programs are always data-race free.
System libraries and runtime in Pen are detachable from applications. Therefore, Pen can compile the same applications even for WebAssembly and WASI. Pen also provides Rust/C FFI to reuse existing resources written in those languages.
import Core'Number
import Os'File
# The `\` prefix for λ denotes a function.
findAnswer = \(kind string) number {
# Secret source...
21
}
main = \(ctx context) none {
# The `go` function runs a given function in parallel.
# `x` is a future for the computed value.
x = go(\() number { findAnswer("humanity") })
y = findAnswer("dolphins")
_ = File'Write(ctx, File'StdOut(), Number'String(x() + y))
none
}
Pen is available via Homebrew.
brew install pen-lang/pen/pen
For more information, see Install.
- Getting started
- Guides
- Language reference
Comparison with Go
Pen | Go | |
---|---|---|
Domain | Application programming | System programming |
Paradigm | Functional | Imperative / object-oriented |
Memory management | Reference counting | Concurrent mark-and-sweep |
System library | Your choice! | Built-in |
Values | Immutable | Mutable |
Pen | Go | |
---|---|---|
Context switch | Continuations | Platform dependent |
Concurrent computation | Built-in functions | go expression |
Synchronization | Futures, lazy lists | Channels, concurrent data structures |
Data race prevention | Built into GC | Dynamic analysis |
Resource management | Built into GC | defer statement |
Error handling | error type, ? operator |
error type, multi-value return |
Exception | None | panic and recover functions |
Pen | Go | |
---|---|---|
Number | number (IEEE 754) |
int , float64 , ... |
Sequence | [number] (lazy list) |
[]int (array or slice) |
Map | {string: number} |
map[string]int |
Concurrent queue | [number] , built-in functions |
chan int |
Optional value | none , union types |
null pointer (or zero value) |
Function | \(number, boolean) string |
func(int, bool) string |
Union | number | string |
Interface |
Top type | any |
any (interface{} ) |
Interface | Records | Interface |
The \
(lambda, λ) notation in function types and literals originates from other functional programming languages like Haskell.
Like Go, every function in Pen is suspendable and can be called asynchronously. This is realized by intermediate representation compiled into Continuation Passing Style (CPS) which also enables proper tail calls. Thus, Pen implements context switch without any platform-dependent codes for slight sacrifice of performance while Go requires logic written in assembly languages.
Currently, Pen does not use delimited continuations for the following reasons.
- Traditional continuations are sufficient for our use cases, such as asynchronous programming.
- Delimited continuations require heap allocations although the second-class continuations do not.
Pen implements the Perceus reference counting as its GC. Thanks to the state-of-the-art ownership-based RC algorithm, programs written in Pen performs much less than traditional RC where every data transfer or mutation requires counting operations. In addition, the algorithm reduces heap allocations significantly for records behind unique references, which brings practical performance without introducing unsafe mutability.
See also How to Implement the Perceus Reference Counting Garbage Collection.
TBD
TBD
TBD
Pen is under heavy development. Feel free to post Issues and Discussions!
See Install.
tools/build.sh
tools/unit_test.sh
tools/build.sh
tools/integration_test.sh
Those benchmarks include ones written in both Pen and Rust.
tools/benchmark.sh
tools/lint.sh
tools/format.sh
cmd
: Commandspen
:pen
command
lib
: Libraries for compiler, formatter, documentation generator, etc.app
: Platform-agnostic application logic forpen
commandinfra
: Platform-dependent logic forpen
commandast
: Abstract Syntax Tree (AST) typeshir
: High-level Intermediate Representation (HIR) types and semanticsmir
: Mid-level Intermediate Representation (MIR)ast-hir
: AST to HIR compilerhir-mir
: HIR to MIR compilermir-fmm
: MIR to F-- compiler
packages
: Packages written in Pentools
: Developer and CI toolsdoc
: Documentation at pen-lang.org
Pen is dual-licensed under MIT and Apache 2.0.