1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-29 01:40:26 +00:00

Update Intro.

Calvin Rose 2018-11-30 23:07:32 -05:00
parent 14a1cfc892
commit f310d478be

@ -74,7 +74,7 @@ notation with a radix besides 10, use the `&` symbol to indicate the exponent ra
Besides the 5 main arithmetic functions, janet also supports a number of math functions Besides the 5 main arithmetic functions, janet also supports a number of math functions
taken from the C libary `<math.h>`, as well as bitwise operators that behave like they taken from the C libary `<math.h>`, as well as bitwise operators that behave like they
do in C or Java. Functions like `math.sin`, `math.cos`, `math.log`, and `math.exp` will do in C or Java. Functions like `math/sin`, `math/cos`, `math/log`, and `math/exp` will
behave as expected to a C programmer. They all take either 1 or 2 numeric arguments and behave as expected to a C programmer. They all take either 1 or 2 numeric arguments and
return a real number (never an integer!) return a real number (never an integer!)
@ -161,7 +161,9 @@ created as needed.
Functions can be defined with the `defn` macro, like so: Functions can be defined with the `defn` macro, like so:
```lisp ```lisp
(defn triangle-area [base height] (defn triangle-area
"Calculates the area of a triangle."
[base height]
(print "calculating area of a triangle...") (print "calculating area of a triangle...")
(* base height 0.5)) (* base height 0.5))
``` ```
@ -197,12 +199,12 @@ literals without binding them to a symbol.
# Evaluates to 40 # Evaluates to 40
((fn [x y] (+ x x y)) 10 20) ((fn [x y] (+ x x y)) 10 20)
# Also evaluates to 40 # Also evaluates to 40
((fn @[x y] (+ x x y)) 10 20) ((fn [x y &] (+ x x y)) 10 20)
# Will throw an error about the wrong arity # Will throw an error about the wrong arity
((fn [x] x) 1 2) ((fn [x] x) 1 2)
# Will not throw an error about the wrong arity # Will not throw an error about the wrong arity
((fn @[x] x) 1 2) ((fn [x &] x) 1 2)
``` ```
The first expression creates an anonymous function that adds twice The first expression creates an anonymous function that adds twice
@ -213,7 +215,7 @@ There is a common macro `defn` that can be used for creating functions and immed
them to a name. `defn` works as expected at both the top level and inside another form. There is also them to a name. `defn` works as expected at both the top level and inside another form. There is also
the corresponding the corresponding
Note that putting an ampersand in front of the argument list inhibits strict arity checking. Note that putting an ampersand at the end of the argument list inhibits strict arity checking.
This means that such a function will accept fewer or more arguments than specified. This means that such a function will accept fewer or more arguments than specified.
```lisp ```lisp
@ -448,16 +450,16 @@ of the loop.
(-- i)) (-- i))
# Print ... until a random number in range [0, 1) is >= 0.9 # Print ... until a random number in range [0, 1) is >= 0.9
# (math.random evaluates to a value between 0 and 1) # (math/random evaluates to a value between 0 and 1)
(while (> 0.9 (math.random)) (while (> 0.9 (math/random))
(print "...")) (print "..."))
``` ```
Besides these special forms, Janet has many macros for both conditional testing and looping Besides these special forms, Janet has many macros for both conditional testing and looping
that are much better for the majority of cases. For conditional testing, the `cond`, `switch`, and that are much better for the majority of cases. For conditional testing, the `cond`, `switch`, and
`when` macros can be used to great effect. `cond` can be used for making an if-else chain, where using `when` macros can be used to great effect. `cond` can be used for making an if-else chain, where using
just raw if forms would result in many parentheses. `switch` For looping, the `loop` and `for` macro implement just raw if forms would result in many parentheses. `case` For looping, the `loop`, `seq`, and `generate`
list comprehension, as in Python, Clojure. implement janet's form of list comprehension, as in Python or Clojure.
# Combinators # Combinators
@ -469,7 +471,7 @@ list comprehension, as in Python, Clojure.
# The Core Library # The Core Library
Janet has a built in core library of over 200 functions and macros at the time of writing. Janet has a built in core library of over 300 functions and macros at the time of writing.
While some of these functions may be refactored into separate modules, it is useful to get to know While some of these functions may be refactored into separate modules, it is useful to get to know
the core to avoid rewriting provided functions. the core to avoid rewriting provided functions.
@ -481,7 +483,7 @@ For any given function, use the `doc` macro to view the documentation for it in
To see a list of all global functions in the repl, type the command To see a list of all global functions in the repl, type the command
```lisp ```lisp
(table.getproto *env*) (table/getproto *env*)
# Or # Or
(all-symbols) (all-symbols)
``` ```
@ -505,23 +507,19 @@ contents without duplicating memory.
```lisp ```lisp
# One of many Object Oriented schemes that can # One of many Object Oriented schemes that can
# be implented in janet. # be implented in janet.
(def proto1 @{:type :my.custom1 (def proto1 @{:type :custom1
:behave (fn [self x] (print "behaving " x))}) :behave (fn [self x] (print "behaving " x))})
(def proto2 @{:type :my.custom2 (def proto2 @{:type :custom2
:behave (fn [self x] (print "behaving 2 " x))}) :behave (fn [self x] (print "behaving 2 " x))})
(def thing1 (table.setproto @{} proto1)) (def thing1 (table/setproto @{} proto1))
(def thing2 (table.setproto @{} proto2)) (def thing2 (table/setproto @{} proto2))
(print (get thing1 :type)) # prints :my.custom1 (print thing1:type) # prints :custom1
(print (get thing2 :type)) # prints :my.custom2 (print thing2:type) # prints :custom2
(defn behave [x y] (thing1:behave thing1 :a) # prints "behaving :a"
(let [{:behave f} x] (thing2:behave thing2 :b) # prints "behaving 2 :b"
(f x y)))
(behave thing1 :a) # prints "behaving :a"
(behave thing2 :b) # prints "behaving 2 :b"
``` ```
Looking up in a table with a prototype can be summed up with the following algorithm. Looking up in a table with a prototype can be summed up with the following algorithm.
@ -558,7 +556,7 @@ is used to differentiate different kinds of returns. When a fiber yields or thro
control is returned to the calling fiber. The parent fiber must then check what kind of state the control is returned to the calling fiber. The parent fiber must then check what kind of state the
fiber is in to differentiate errors from return values from user defined signals. fiber is in to differentiate errors from return values from user defined signals.
To create a fiber, user the `fiber.new` function. The fiber constructor take one or two arguments. To create a fiber, user the `fiber/new` function. The fiber constructor take one or two arguments.
the first, necessary argument is the function that the fiber will execute. This function must accept the first, necessary argument is the function that the fiber will execute. This function must accept
an arity of one. The next optional argument is a collection of flags checking what kinds of an arity of one. The next optional argument is a collection of flags checking what kinds of
signals to trap and return via `resume`. This is useful so signals to trap and return via `resume`. This is useful so
@ -566,7 +564,7 @@ the programmer does not need to handle all different kinds of signals from a fib
are simply propagated to the next fiber. are simply propagated to the next fiber.
```lisp ```lisp
(def f (fiber.new (fn @[] (def f (fiber/new (fn @[]
(yield 1) (yield 1)
(yield 2) (yield 2)
(yield 3) (yield 3)
@ -574,15 +572,15 @@ are simply propagated to the next fiber.
5))) 5)))
# Get the status of the fiber (:alive, :dead, :debug, :new, :pending, or :user0-:user9) # Get the status of the fiber (:alive, :dead, :debug, :new, :pending, or :user0-:user9)
(print (fiber.status f)) # -> :new (print (fiber/status f)) # -> :new
(print (resume f)) # -> prints 1 (print (resume f)) # -> prints 1
(print (resume f)) # -> prints 2 (print (resume f)) # -> prints 2
(print (resume f)) # -> prints 3 (print (resume f)) # -> prints 3
(print (resume f)) # -> prints 4 (print (resume f)) # -> prints 4
(print (fiber.status f)) # -> print :pending (print (fiber/status f)) # -> print :pending
(print (resume f)) # -> prints 5 (print (resume f)) # -> prints 5
(print (fiber.status f)) # -> print :dead (print (fiber/status f)) # -> print :dead
(print (resume f)) # -> throws an error because the fiber is dead (print (resume f)) # -> throws an error because the fiber is dead
``` ```
@ -599,7 +597,7 @@ Besides being used as coroutines, fibers can be used to implement error handling
# Use the :e flag to only trap errors. # Use the :e flag to only trap errors.
(def f (fiber.new my-function-that-errors :e)) (def f (fiber.new my-function-that-errors :e))
(def result (resume f)) (def result (resume f))
(if (= (fiber.status f) :error) (if (= (fiber/status f) :error)
(print "result contains the error") (print "result contains the error")
(print "result contains the good result")) (print "result contains the good result"))
``` ```