Shen in 15 Minutes


 

 

Shen in 15 Minutes

The Shen top level is a read-evaluate-print loop as in all functional languages. When you start it up, you get something this (depending on release and platform).

Shen, copyright (C) 2010-2015 Mark Tarver
www.shenlanguage.org, Shen 32
running under Common Lisp, implementation: SBCL
port 1.9 ported by Mark Tarver


(0-)

Unlike Lisp the quote (') is not used. Entering hello returns hello, so symbols are implicitly quoted.

Shen, copyright (C) 2010-2015 Mark Tarver
www.shenlanguage.org, Shen 32
running under Common Lisp, implementation: SBCL
port 3.0 ported by Mark Tarver


(0-) hello
hello

Each input is numbered starting with 0.

An input is repeated by typing !n where n is a natural number. Shen will print the nth input of the session and evaluate it. Typing !s where s is any series of symbols, will cause Shen to print and then evaluate the last input whose main function symbol begins with s. % works as ! except that the previous input(s) are printed off without being evaluated.

Shen, copyright (C) 2010-2015 Mark Tarver
www.shenlanguage.org, Shen 19
running under Common Lisp, implementation: SBCL
port 1.9 ported by Mark Tarver


(0-) hello
hello

(1-) (* 7 8)
56

(2-) !1
(* 7 8)
56

(3-) !*
(* 7 8)
56

(4-) %*
1. (* 7 8)
2. (* 7 8)
3. (* 7 8)

Functions are applied in prefix form just like Lisp. Unlike Lisp, Shen is case-sensitive, so b and B are not treated as the same. = is the general equality relation (unlike Lisp where it is used for only numbers). Unlike Lisp, Shen uses true and false as booleans. ^ breaks off input.

(4-) (and true false)
false

(5-) (or true false)
true

(6-) (not true)
false

(7-) (if true a b)
a

(8-) (= 1 1)
true

(9-) (= f ^
line read aborted

Shen permits currying, and also partial applications, which both generate closures.

(10-) ((* 7) 9)
63

(11-) (* 7)
#|FUNCTION :LAMBDA (#:Y18390) (multiply #:Y18389 #:Y18390)|

In lambda calculus, the identity function is (λ x x). In Shen it is written (/. X X), and evaluates to a closure. (/. X Y X) is acceptable shorthand for (λ x (λ y x)). In Shen an abstraction can always be used in place of a function.

(12-) (/. X X)
#|FUNCTION :LAMBDA (X) X|

(13-) ((/. X X) 9)
9

(14-) ((/. X Y Y) 6 7)
7

(15-) ((/. X Y (* X Y)) 6 7)
42

A list begins with a [ and ends with a ]. Spaces seperate items. cons, head and tail are standard. Note that Shen includes an infix |that works as Prolog. [1 2 | [3]] = [1 2 3].

(16-) [1 2 3]
[1 2 3]

(17-) (= [1 (+ 1 1) 3] [1 2 3])
true

(18-) (head [1])
1

(19-) (tail [1])
[]

(20-) (cons 1 [])
[1]

(21-) [1 2 | [3]]
[1 2 3]

Suppose we have to define a function f that, if it receives 1 returns 0 and if it returns 0 returns 1. In Shen this appears as a series of rewrite rules. If all rules fail an error is raised.

(22-) (define f
        0 -> 1
        1 -> 0)
f

(23-) (f 0)
1

(24-) (f 1)
0

(25-) (f 2)
partial function f;
track f? (y/n)

Now lets look at an example using variables. We define factorial, this requires a variable, which in Shen is any symbol beginning in uppercase.

(26-) (define factorial
        0 -> 1
        X -> (* X (factorial (- X 1))))
factorial

(27-) (factorial 6)
720

Here are two list processing functions in Shen; one that totals a list and the other that splits a lists into triples.

(28-) (define total
        [] -> 0
        [X | Y] -> (+ X (total Y)))
total

(29-) (define triples
        [] -> []
        [W X Y | Z] -> [[W X Y] | (triples Z)])
triples

(30-) (total [12 45 28])
85

(31-) (triples [1 2 3 4 5 6])
[[1 2 3] [4 5 6]]

Patterns can be non-left linear; repeated variables require equality. Shen supports guards.

(32-) (define id
        X X -> true
        _ _ -> false)
id
        
(33-) (id 4 4)
true

(34-) (define gter
        X Y -> X where (> X Y)
        X Y -> Y where (> Y X)
        _ _ -> ?)
gter

(35-) (gter 4 5)
5

(36-) (gter 14 5)
14

(37-) (gter 14 14)
?

Here is foldl in Shen.

(38-) (define foldl
        F Z [] -> Z
        F Z [X | Y] -> (foldl F (F Z X) Y))
foldl

(39-) (foldl (fn +) 0 [1 2 3])
6

(40-) (foldl (fn +) 0 [1 2 3])
6

load will load a Shen program.

(41-) \* Here is a 
                                          multiline comment *\ 
                                          \\ Here is a single line comment
                                          (load "factorial.shen")
factorial
0.05s
loaded

So far Shen looks like an untyped language (e.g. like SASL). Actually Shen does have type checking, but you have to switch it on. (tc +) does it. The + shows that you are now working in a statically typed environment. Shen will typecheck everything that is loaded or entered into the image. Like ML, mixed lists will not now be accepted. (tc -) switches the typechecker back off.

(42-) (tc +)
true

(43+) 123
123 : number

(44+) [1 a]
type error

(45+) (* 7)
# : (number --> number)

(45+) [1 2 3]
[1 2 3] : (list number)

The pair <1,2> is represented as (@p 1 2) in Shen. The functions 'fst' and 'snd' select the first and second elements of a pair. (@p 1 2 3) is just shorthand for (@p 1 (@p 2 3)).

(46+) (@p 1 2)
(@p 1 2) : (number * number)

(47+) (fst (@p 1 2))
1 : number

(48+) (snd (@p 1 2))
2 : number

(49+) (@p 1 2 3)
(@p 1 (@p 2 3)) : (number * (number * number))

Shen is like Hope in requiring explicit types to be attached to functions. It supports polymorphism and variables are allowed in types. You can use @p in a pattern-directed manner in function definitions.

(50+) (define total
        {(list number) --> number}
        [] -> 0
        [X | Y] -> (+ X (total Y)))
(fn total) : ((list number) --> number)

(51+) (define triples
        {(list A) --> (list (list A))}
        [] -> []
        [W X Y | Z] -> [[W X Y] | (triples Z)])
(fn triples) : (list A) --> (list (list A))

(52+) (define swap
        {(A * B) --> (B * A)}
        (@p X Y) -> (@p Y X))
(fn swap) : ((A * B) --> (B * A))
1. Introduction

2. License

3. History

4. The Core Language

4.1 Base Types
4.1.1 Symbols
4.1.2 Strings
4.1.3 Numbers
4.2 Function Applications
4.3 The Top Level
4.4 Arithmetic
4.5 Comments

4.6 Sequences

4.6.1 Lists
4.6.2 Tuples
4.6.3 Vectors

4.7 lambda and let
4.8 Global Assignments
4.9 Higher Order Functions
4.10 Lazy Evaluation
4.11 I/O
4.12 Loading Files
4.13 Streams
4.14 Exceptions
4.15 Hashing
4.16 Property Lists
4.17 Eval

5 Defining Functions

5.1 Partial Functions
5.2 List Handling Functions
5.3 String Handling Functions
5.4 Tuple Handling Functions
5.5 Vector Handling Functions
5.6 Guards
5.7 Backtracking
5.8 Writing in Kλ
5.9 Macros

6. Packages

7. Shen-YACC

7.1 Recognisor Generator
7.2 Semantic Actions

8. Shen Prolog

8.1 Sample Programs

9. Types

9.1 Types and Constructors
9.2 Functions and Types
9.3 Synonyms

10 Sequent Calculus

10.1 Recursive Types

10.2 Exotic Types

10.2.1 Dependent Types
10.2.2 Negative Types
10.2.3 Subtypes
10.2.4 The Type of All Sets

11 Glossary of Functions

12 The Syntax of Shen

Built by Shen Technology (c) Mark Tarver, September 2021