Carth

Purely functional programming with lisp-syntax. Less infix, more parens!

Table of Contents

Welcome to the homepage of the Carth programming language!

1 WORK IN PROGRESS

Just as a little disclaimer: this project is in the very early stages of development, so there are no guarantees of stability etc.

2 Why Carth?

3 Documentation

4 Development

All development on the Carth project happens openly on Github in bryal/carth. The source for this website is also on Github in bryal/carth-website.

5 Example

Just to give you a quick taste. More examples can be found in the examples directory in the repository.

;; Note that many of these functions are/will be in the standard
;; library in some shape or form. We just include them all in the same
;; file here to show off more of the syntax and features.

;; ~start~ is the programs entrypoint
(define (start _) (fizzbuzz unit))

(define (fizzbuzz _)
  (for (range 1 100)
       (comp display fizzbuzz')))

(define (fizzbuzz' n)
  (match (Pair (divisible? n 3) (divisible? n 5))
    (case (Pair false false) (my-show-int n))
    (case (Pair true false) "Fizz")
    (case (Pair false true) "Buzz")
    (case (Pair true true) "Fizzbuzz")))

(define my-show-int
  (fun-match
    (case 1 "one")
    (case 2 "two")
    (case n (show-int n))))

;; Apply an action to each element in an iterator
(define (for xs f)
  (match (next xs)
    (case None unit)
    (case (Some (Pair x xs'))
          (seq (f x) (for xs' f)))))

;; Iterator over the closed range $[a, b]$
(define (range a b)
  (Iter (Lazy (if (> a b)
                  (fun _ None)
                (fun _ (Some (Pair a (range (+ a 1) b))))))))

;; Advances an iterator, returning the next value and the rest of the
;; iterator
(define (next (Iter it)) (lively it))

;; An iterator / non-strict list
(type (Iter a)
  (Iter (Lazy (Maybe (Pair a (Iter a))))))

(define (lively (Lazy f))
  (f unit))

;; A lazy, or rather a non-strict value
(type (Lazy a)
  (Lazy (Fun Unit a)))

(type (Maybe a)
  None
  (Some a))

(define (seq a b)
  b)

;; Function composition
(define (comp f g a)
  (f (g a)))

(define (divisible? n m)
  (= (rem n m) 0))

(define (display s)
  (display-inline (str-append s "\n")))

;;; Currying wrappers

(define (rem a b)          (rem-int     (Pair a b)))
(define (= a b)            (eq-int      (Pair a b)))
(define (> a b)            (gt-int      (Pair a b)))
(define (+ a b)            (add-int     (Pair a b)))
(define (str-append s1 s2) (-str-append (Pair s1 s2)))

;;; External functions defined in the foreign-core library

(extern show-int (Fun Int Str))
(extern eq-int (Fun (Pair Int Int) Bool))
(extern gt-int (Fun (Pair Int Int) Bool))
(extern rem-int (Fun (Pair Int Int) Int))
(extern add-int (Fun (Pair Int Int) Int))
(extern display-inline (Fun Str Unit))
(extern -str-append (Fun (Pair Str Str) Str))

6 License

Both the Carth project and this website itself are licensed under the AGPL, version 3 or later. See LICENSE.

Note that by default, all programs written in Carth will have to be distributed under the AGPLv3 license as well, as not just the compiler itself, but also the standard library you include and the core library you link with are AGPLv3 licensed. Technically you could write your own standard library and core library with some non-copyleft license to avoid this, but I hope you won't! ;)

6.1 Notice

Copyright (C) 2020 Johan Johansson

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.