mirror of
https://github.com/janet-lang/janet
synced 2024-12-27 17:00:27 +00:00
Update Intro.
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
|
||||
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
|
||||
return a real number (never an integer!)
|
||||
|
||||
@ -161,7 +161,9 @@ created as needed.
|
||||
Functions can be defined with the `defn` macro, like so:
|
||||
|
||||
```lisp
|
||||
(defn triangle-area [base height]
|
||||
(defn triangle-area
|
||||
"Calculates the area of a triangle."
|
||||
[base height]
|
||||
(print "calculating area of a triangle...")
|
||||
(* base height 0.5))
|
||||
```
|
||||
@ -197,12 +199,12 @@ literals without binding them to a symbol.
|
||||
# Evaluates to 40
|
||||
((fn [x y] (+ x x y)) 10 20)
|
||||
# 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
|
||||
((fn [x] x) 1 2)
|
||||
# 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
|
||||
@ -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
|
||||
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.
|
||||
|
||||
```lisp
|
||||
@ -448,16 +450,16 @@ of the loop.
|
||||
(-- i))
|
||||
|
||||
# Print ... until a random number in range [0, 1) is >= 0.9
|
||||
# (math.random evaluates to a value between 0 and 1)
|
||||
(while (> 0.9 (math.random))
|
||||
# (math/random evaluates to a value between 0 and 1)
|
||||
(while (> 0.9 (math/random))
|
||||
(print "..."))
|
||||
```
|
||||
|
||||
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
|
||||
`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
|
||||
list comprehension, as in Python, Clojure.
|
||||
just raw if forms would result in many parentheses. `case` For looping, the `loop`, `seq`, and `generate`
|
||||
implement janet's form of list comprehension, as in Python or Clojure.
|
||||
|
||||
# Combinators
|
||||
|
||||
@ -469,7 +471,7 @@ list comprehension, as in Python, Clojure.
|
||||
|
||||
# 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
|
||||
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
|
||||
|
||||
```lisp
|
||||
(table.getproto *env*)
|
||||
(table/getproto *env*)
|
||||
# Or
|
||||
(all-symbols)
|
||||
```
|
||||
@ -505,23 +507,19 @@ contents without duplicating memory.
|
||||
```lisp
|
||||
# One of many Object Oriented schemes that can
|
||||
# be implented in janet.
|
||||
(def proto1 @{:type :my.custom1
|
||||
(def proto1 @{:type :custom1
|
||||
:behave (fn [self x] (print "behaving " x))})
|
||||
(def proto2 @{:type :my.custom2
|
||||
(def proto2 @{:type :custom2
|
||||
:behave (fn [self x] (print "behaving 2 " x))})
|
||||
|
||||
(def thing1 (table.setproto @{} proto1))
|
||||
(def thing2 (table.setproto @{} proto2))
|
||||
(def thing1 (table/setproto @{} proto1))
|
||||
(def thing2 (table/setproto @{} proto2))
|
||||
|
||||
(print (get thing1 :type)) # prints :my.custom1
|
||||
(print (get thing2 :type)) # prints :my.custom2
|
||||
(print thing1:type) # prints :custom1
|
||||
(print thing2:type) # prints :custom2
|
||||
|
||||
(defn behave [x y]
|
||||
(let [{:behave f} x]
|
||||
(f x y)))
|
||||
|
||||
(behave thing1 :a) # prints "behaving :a"
|
||||
(behave thing2 :b) # prints "behaving 2 :b"
|
||||
(thing1:behave thing1 :a) # prints "behaving :a"
|
||||
(thing2:behave thing2 :b) # prints "behaving 2 :b"
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -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.
|
||||
|
||||
```lisp
|
||||
(def f (fiber.new (fn @[]
|
||||
(def f (fiber/new (fn @[]
|
||||
(yield 1)
|
||||
(yield 2)
|
||||
(yield 3)
|
||||
@ -574,15 +572,15 @@ are simply propagated to the next fiber.
|
||||
5)))
|
||||
|
||||
# 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 2
|
||||
(print (resume f)) # -> prints 3
|
||||
(print (resume f)) # -> prints 4
|
||||
(print (fiber.status f)) # -> print :pending
|
||||
(print (fiber/status f)) # -> print :pending
|
||||
(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
|
||||
```
|
||||
|
||||
@ -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.
|
||||
(def f (fiber.new my-function-that-errors :e))
|
||||
(def result (resume f))
|
||||
(if (= (fiber.status f) :error)
|
||||
(if (= (fiber/status f) :error)
|
||||
(print "result contains the error")
|
||||
(print "result contains the good result"))
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user