diff --git a/404.html b/404.html index ac8dc4e4..25a00a2f 100644 --- a/404.html +++ b/404.html @@ -4,7 +4,7 @@
NOTE: Only the core of LIPS is written in JavaScript, almost half of it it's written in Scheme. +
Only the core of LIPS is written in JavaScript, almost half of it it's written in Scheme.
So if you want to load the standard library (to have full LIPS), you should use bootstrap
or
data-bootstrap
attribute that will load it for you. You can optionally specify the location of the
-file.
<script type="text/x-scheme" bootstrap="https://cdn.jsdelivr.net/npm/@jcubic/lips@beta/dist/std.xcb">
(let ((what "world")
(greet "hello"))
@@ -38,7 +38,7 @@ R
xcb
file is simple binary format that LIPS uses to speed up parsing the the code. You can also use
.scm
file or .min.scm
file that may be little bit bigger.
NOTE The bootstrap
attribute can also be included on main script tag with the JavaScript file.
The bootstrap
attribute can also be included on main script tag with the JavaScript file.
You can also use src
attribute to link to source file. Like you normally do with JavaScript:
<script type="text/x-scheme" src="example.scm"><script>
@@ -90,8 +90,8 @@ Standalon
and execute the script by providing the name:
./script.scm
-NOTE: by default most systems don't execute files in current directory so you need to provide ./
in front.
-You can change that if you add dot (current working directory) to the $PATH
environment variable:
+infoBy default most systems don't execute files in current directory so you need to provide ./
in front.
+You can change that if you add dot (current working directory) to the $PATH
environment variable:
export $PATH=".:$PATH"
If you prefer to install lips locally instead of globally you can use this shebang:
@@ -99,8 +99,8 @@ Standalon
(let ((what "World"))
(print (string-append "Hello " what)))
NOTE: if you run this code outside of Node.js project npx will install the -package before execution.
+If you run this code outside of Node.js project npx will install the +package before execution.
After you have installed LIPS you can create a new Node.js project and write LIPS Scheme code
instead of JavaScript, using everything Node.js provides. See documentation about Integration with
@@ -118,9 +118,9 @@ NOTE: braces is a popular package to expand bash like
+ braces is a popular package to expand bash like
expressions, it's used as deep dependency for
-TailwindCSS. You can also execute LIPS from JavaScript: Anything you add to the object passed to Interpreter will be added to global scope. The Interpreter have a method Note: that you also need to bootstrap the standard library to have fully working Scheme system. Note that you also need to bootstrap the standard library to have fully working Scheme system. You can use this function in LIPS with version 5 and 7 to get R5RS or R7RS. NOTE: that some of the functions from R5RS may have features of R7RS since
-some of them got additional arguments. RnRS is backward compatible. Note that some of the functions from R5RS may have features of R7RS since
+some of them got additional arguments. RnRS is backward compatible. You can use this function with NOTE: The The There are 3 types of syntax extensions NOTE: The provided output will be exactly the same, when the code will be put into a single file
-and executed. The provided output will be exactly the same, when the code will be put into a single file
+and executed. In syntax extensions NOTE We can use this code to make sure that the function has been executed only once: LIPS define function NOTE the reduce works differently than in JavaScript, the callback function get accumulator in last argument. The reduce works differently than in JavaScript, the callback function get accumulator in last argument. NOTE: here we use Here we use NOTE: In LIPS all integers are BigInts. In LIPS all integers are BigInts. The last typecking function is NOTE the only time when you still need The only time when you still need Here we get a style object
from the DOM node without sorting the
reference to the DOM node. NOTE because dot notation in symbols is not special syntax you can use code like this: Because dot notation in symbols is not special syntax you can use code like this: the values in JavaScript are different because they have different representation in LIPS. The values in JavaScript are different because they have different representation in LIPS. To fix the issue you can
define lambda with single argument: NOTE: because of the construction of syntax extensions and
-quasiquote, you can't splice a list inside object literals: Because of the construction of syntax extensions and
+quasiquote, you can't splice a list inside object literals: NOTE: this example macro works the same This example macro works the same Object literal also have shorthad notation: NOTE Inside Inside NOTE the order of execution is not expected, but it may change in the future. The order of execution is not expected, but it may change in the future. LIPS also define R7RS guard NOTE: be careful when using iterator protocol because any function side Scheme can return a promise. If you would change
-quoted object literal Be careful when using iterator protocol because any function side Scheme can return a promise. If you would change
+quoted object literal You can abstract the use of iteration protocol with a macro, but to have real You can also define generators inside JavaScript using Will create NOTE: directives Directives In LIPS, you can use Note recursive call is inside quote and only argument is unquoted. This is required since
+ Recursive call is inside quote and only argument is unquoted. This is required since
recursive macro call needs to appear in the expansion. If you call macro recursively and don't return
-macro call as output list you will end up in ifninite recursive call. You can see the macro will expand with macroexpand: By default Scheme Note: that not every scheme implementation support this SRFI. Note that not every scheme implementation support this SRFI. Here is example of NOTE: Unfortunately, there are no good books about Scheme hygienic macros. But you can read
-those documents: Unfortunately, there are no good books about Scheme hygienic macros. But you can read
+those documents: Is that in Lisp there are no operators. The above expression is just procedure application (function call). NOTE: We will use procedure and function interchangeably in this tutorial. We will use procedure and function interchangeably in this tutorial. Plus is not an operator, only a symbol that point into an addition procedure that is executed. So in
fact in other programming languages this should be written as: And you can type your scheme code and press enter to execute it (it's often called evaluation of the expression). NOTE: you can run LIPS bookmarklet while reading this tutorial. But note that it
+ You can run LIPS bookmarklet while reading this tutorial. But note that it
doesn't yet support continuations and TCO (Tail Call
-Optimization). Scheme is standardized in form of RnRS documents.
Revisedn Report on the Algorithmic Language Scheme. Where power indicate how many times
diff --git a/img/emacs-scheme-regex.png b/img/emacs-scheme-regex.png
index 0ac9a104..1fb7fc93 100644
Binary files a/img/emacs-scheme-regex.png and b/img/emacs-scheme-regex.png differ
diff --git a/index.html b/index.html
index f63a2f11..273d61cc 100644
--- a/index.html
+++ b/index.html
@@ -4,7 +4,7 @@
Node.js proje
(write (braces "{01..10}" &(:expand #t)))
;; ==> #("01" "02" "03" "04" "05" "06" "07" "08" "09" "10")
-
Executing LIPS prammatically
const { exec } = require('@jcubic/lips');
@@ -161,7 +161,7 @@
Creating REPL<
exec
that work the same as thhe one exported from LIPS.Bootstrapping
-await interpreter.exec(`(let-env lips.env.__parent__
(load "<path or URL>/dist/std.xcb"))`);
S
specification in a form of a function
scheme-report-environment
.
eval
or let-env
:(let ((env (scheme-report-environment 7)))
(let-env env
diff --git a/docs/lips/extension.html b/docs/lips/extension.html
index c4822729..01c65243 100644
--- a/docs/lips/extension.html
+++ b/docs/lips/extension.html
@@ -4,7 +4,7 @@
Syntax ext
(lips.parse "##10")
;; ==> #((list 10 10))
lips.parse
function return array/vector of parsed expressions.lips.parse
function return array/vector of parsed expressions.SPLICE
, LITERAL
, and SYMBOL
. You define them using
constants defined in lips.specials
object.
@@ -220,8 +220,8 @@
;; ==> &(:token "#:num" :col 10 :offset 274 :line 12)
;; ==> (12 13)
Accessing p
Standard input
current-input-port
points into the parser stream. So you can implement
your own parser logic. The best way to implement custom syntax extension (that works similar to
diff --git a/docs/lips/functional-helpers.html b/docs/lips/functional-helpers.html
index d5ac1d6f..8c8357cf 100644
--- a/docs/lips/functional-helpers.html
+++ b/docs/lips/functional-helpers.html
@@ -4,7 +4,7 @@
always and o
(finally
(console.timeEnd ,label))))))
#:result
expression is auto gensym as one of
-builtin syntax extensions.#:result
expression is auto gensym as one of
+builtin syntax extensions.(define (expensive value)
(new Promise (lambda (resolve)
@@ -211,7 +211,7 @@
pipefolding
reduce
that is an alias to standard Scheme procedure fold-right
and fold that is the same
as fold-left
. Both procedures works similarly. The take a procedure and a list and reduce it into a single value.(reduce cons '() '(1 2 3 4 5))
;; ==> (5 4 3 2 1)
folding '("foo" "bar" "baz" "quuz"))
;; ==> (1 "foo" 2 "bar" 3 "baz" 4 "quuz")
cons
to create a list, cons
construct the list in reverse order so reduce
-start from first element and fold
is reversed:cons
to create a list, cons
construct the list in reverse order so reduce
+start from first element and fold
is reversed:(reduce (lambda (item acc)
(print acc)
(cons item acc))
diff --git a/docs/lips/intro.html b/docs/lips/intro.html
index 87a3096d..7a18430c 100644
--- a/docs/lips/intro.html
+++ b/docs/lips/intro.html
@@ -4,7 +4,7 @@
Typechecking (typecheck-number "let" i "bigint"))
;; ==> Expecting bigint got complex in expression `let`
typecheck-args
that check if all arguments are of same type.(let ((number '(1 10 1/2 10+10i)))
(typecheck-args "number" "let" number))
@@ -338,15 +338,15 @@
(document.querySelector "body")
.
function is when you want to get the property of
-object returned by expression..
function is when you want to get the property of
+object returned by expression.(let ((style (. (document.querySelector "body") 'style)))
(set! style.background "red"))
(let ((x #(1 2 3)))
(print x.0)
(print x.1)
@@ -381,7 +381,7 @@
Callbacks
["1", "2", "3"].map(parseInt)
// ==> [1, NaN, NaN]
(--> #("1" "2" "3") (map (lambda (str) (string->number str))))
@@ -457,8 +457,8 @@
Object liter
(write jack)
;; ==> &(:name "Jack" :age 22)
(let ((args (list ':foo "lorem" ':bar "ipsum")))
`&(,@args))
;; ==> pair (unquote-splicing args) is not a symbol!
@@ -484,8 +484,8 @@
Object liter
(create-object :foo "lorem" :bar "ipsum")
;; ==> &(:foo "lorem" :bar "ipsum")
object
is it's not that useful, but you can create
-more complex code where you will be able to generate object literals with splicing.object
is it's not that useful, but you can create
+more complex code where you will be able to generate object literals with splicing.(let ((obj &(:x :y)))
(write obj))
@@ -538,7 +538,7 @@
Promise qu
(print (await promise)))
;; ==> Scheme is Super Fun
then
lambda promises are still automagically resolved.then
lambda promises are still automagically resolved.(--> '>(Promise.resolve "hello")
(then (lambda (value)
(print (string-append value " " (Promise.resolve "LIPS"))))))
@@ -593,7 +593,7 @@
Exceptions;; ==> after error
;; ==> nasty
procedure
that is just a macro that use try..catch behind the scene:(guard (e ((list? e) (print (string-append "Error: " (car e)))))
(raise '("error")))
@@ -627,8 +627,8 @@
(Array.from #(1/2 1/3 1/4 1/5))
;; ==> #(0.5 0.3333333333333333 0.25 0.2)
`&()
with longhand object
you will get an error because object
is async.`&()
with longhand object
you will get an error because object
is async.yield
keyword like
syntax you need call/cc
.self.eval
(JavaScript global eval
):Binary compi
file.xcb
in same directory. For smaller files it make not have a difference when
loading .xcb
or .scm
files.#!fold-case
and #!no-fold-case
work only inside the parser and they are
-treated as comments, so you can't compile the code that have those directives.#!fold-case
and #!no-fold-case
work only inside the parser and they are
+treated as comments, so you can't compile the code that have those directives.loading SRFI
(load)
with path absolute or relative to the directory of the executed LIPS
file. But you can use special syntax that indicate the root directory of the LIPS Scheme.Recursive M
(alist "foo" 10 "bar" 20 "baz" 30)
;; ==> (("foo" . 10) ("bar" . 20) ("baz" . 30))
(macroexpand (alist "foo" 10 "bar" 20 "baz" 30))
;; ==> (cons (cons "foo" 10) (cons (cons "bar" 20) (cons (cons "baz" 30) ())))
@@ -391,8 +391,8 @@
Re
Anaphoric Hygienic Macros
syntax-rules
macros don't allow creating anaphoric macros like lisp macro do.
But with SRFI-139 you can implement such macros.awhen
anaphoric macro that use this SRFI:(define-syntax-parameter it (syntax-rules () ((_) (syntax-error "Use outside aif"))))
diff --git a/docs/scheme-intro/next-step.html b/docs/scheme-intro/next-step.html
index 4a9b4ba3..0a13fb1f 100644
--- a/docs/scheme-intro/next-step.html
+++ b/docs/scheme-intro/next-step.html
@@ -4,7 +4,7 @@
Lisp Macros
Scheme hygienic macros
-
S-Expressions<
1 + 2 + 3
+(1, 2, 3)
@@ -67,9 +67,9 @@
REPL
scheme>
Standards