Page Not Found | LIPS Scheme
-
+
diff --git a/assets/js/0058b4c6.0f1f0d46.js b/assets/js/0058b4c6.0f1f0d46.js
deleted file mode 100644
index dbb5d149..00000000
--- a/assets/js/0058b4c6.0f1f0d46.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunknew_docs=self.webpackChunknew_docs||[]).push([[849],{6164:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting Started","href":"/docs/intro","docId":"intro","unlisted":false},{"type":"category","label":"Introduction to Scheme","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"What is Lisp and Scheme?","href":"/docs/scheme-intro/what-is-lisp","docId":"scheme-intro/what-is-lisp","unlisted":false},{"type":"link","label":"Data Types","href":"/docs/scheme-intro/data-types","docId":"scheme-intro/data-types","unlisted":false},{"type":"link","label":"Core of Scheme","href":"/docs/scheme-intro/core","docId":"scheme-intro/core","unlisted":false},{"type":"link","label":"Input and Output","href":"/docs/scheme-intro/input-output","docId":"scheme-intro/input-output","unlisted":false},{"type":"link","label":"Macros","href":"/docs/scheme-intro/macros","docId":"scheme-intro/macros","unlisted":false},{"type":"link","label":"Streams","href":"/docs/scheme-intro/streams","docId":"scheme-intro/streams","unlisted":false},{"type":"link","label":"Continuations","href":"/docs/scheme-intro/continuations","docId":"scheme-intro/continuations","unlisted":false},{"type":"link","label":"What Next?","href":"/docs/scheme-intro/next-step","docId":"scheme-intro/next-step","unlisted":false}],"href":"/docs/category/introduction-to-scheme"},{"type":"category","label":"LIPS introduction","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Core features","href":"/docs/lips/intro","docId":"lips/intro","unlisted":false},{"type":"link","label":"Reflection","href":"/docs/lips/reflection","docId":"lips/reflection","unlisted":false},{"type":"link","label":"SXML (e.g. for React)","href":"/docs/lips/sxml","docId":"lips/sxml","unlisted":false},{"type":"link","label":"Environments","href":"/docs/lips/environments","docId":"lips/environments","unlisted":false},{"type":"link","label":"Functional and other utils","href":"/docs/lips/functional-helpers","docId":"lips/functional-helpers","unlisted":false},{"type":"link","label":"Extending LIPS","href":"/docs/lips/extension","docId":"lips/extension","unlisted":false},{"type":"link","label":"REPL","href":"/docs/lips/REPL","docId":"lips/REPL","unlisted":false},{"type":"link","label":"SRFI","href":"/docs/lips/SRFI","docId":"lips/SRFI","unlisted":false},{"type":"link","label":"Embedding LIPS REPL","href":"/docs/lips/embeding-repl","docId":"lips/embeding-repl","unlisted":false}],"href":"/docs/category/lips-introduction"}]},"docs":{"intro":{"id":"intro","title":"Getting Started","description":"Browser","sidebar":"tutorialSidebar"},"lips/embeding-repl":{"id":"lips/embeding-repl","title":"Embedding LIPS REPL","description":"Embedding the LIPS Scheme REPL","sidebar":"tutorialSidebar"},"lips/environments":{"id":"lips/environments","title":"Environments","description":"Environments in LIPS are first class objects","sidebar":"tutorialSidebar"},"lips/extension":{"id":"lips/extension","title":"Extending LIPS","description":"A way to extends LIPS syntax, not only with macros","sidebar":"tutorialSidebar"},"lips/functional-helpers":{"id":"lips/functional-helpers","title":"Functional and other utils","description":"Code that allows to do more with less","sidebar":"tutorialSidebar"},"lips/intro":{"id":"lips/intro","title":"Core features","description":"Core LIPS features added on top of Scheme, related to JavaScript","sidebar":"tutorialSidebar"},"lips/reflection":{"id":"lips/reflection","title":"Reflection","description":"A way to introspect and manipulate LIPS internals","sidebar":"tutorialSidebar"},"lips/REPL":{"id":"lips/REPL","title":"REPL","description":"features of Node.js and Web REPL","sidebar":"tutorialSidebar"},"lips/SRFI":{"id":"lips/SRFI","title":"SRFI","description":"List of supported SRFI","sidebar":"tutorialSidebar"},"lips/sxml":{"id":"lips/sxml","title":"SXML (e.g. for React)","description":"SXML it\'s what JSX is for JavaScript","sidebar":"tutorialSidebar"},"scheme-intro/continuations":{"id":"scheme-intro/continuations","title":"Continuations","description":"Powerful feature of Scheme that allow to add new control flows","sidebar":"tutorialSidebar"},"scheme-intro/core":{"id":"scheme-intro/core","title":"Core of Scheme","description":"Main article that shows most of the features of Scheme","sidebar":"tutorialSidebar"},"scheme-intro/data-types":{"id":"scheme-intro/data-types","title":"Data Types","description":"All different data types you can have in Scheme","sidebar":"tutorialSidebar"},"scheme-intro/input-output":{"id":"scheme-intro/input-output","title":"Input and Output","description":"How to read/write files and how to interact with stdin/stdout","sidebar":"tutorialSidebar"},"scheme-intro/macros":{"id":"scheme-intro/macros","title":"Macros","description":"Macros are the most powerful feature of Lisp and Scheme","sidebar":"tutorialSidebar"},"scheme-intro/next-step":{"id":"scheme-intro/next-step","title":"What Next?","description":"Few resources how to learn more about Scheme","sidebar":"tutorialSidebar"},"scheme-intro/streams":{"id":"scheme-intro/streams","title":"Streams","description":"Feature of scheme that allow to create lazy lists","sidebar":"tutorialSidebar"},"scheme-intro/what-is-lisp":{"id":"scheme-intro/what-is-lisp","title":"What is Lisp and Scheme?","description":"What is Lisp and what is Scheme and a bit of history","sidebar":"tutorialSidebar"}}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/0058b4c6.e79d03cd.js b/assets/js/0058b4c6.e79d03cd.js
new file mode 100644
index 00000000..8c695c50
--- /dev/null
+++ b/assets/js/0058b4c6.e79d03cd.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunknew_docs=self.webpackChunknew_docs||[]).push([[849],{6164:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting Started","href":"/docs/intro","docId":"intro","unlisted":false},{"type":"category","label":"Introduction to Scheme","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"What is Lisp and Scheme?","href":"/docs/scheme-intro/what-is-lisp","docId":"scheme-intro/what-is-lisp","unlisted":false},{"type":"link","label":"Data Types","href":"/docs/scheme-intro/data-types","docId":"scheme-intro/data-types","unlisted":false},{"type":"link","label":"Core of Scheme","href":"/docs/scheme-intro/core","docId":"scheme-intro/core","unlisted":false},{"type":"link","label":"Input and Output","href":"/docs/scheme-intro/input-output","docId":"scheme-intro/input-output","unlisted":false},{"type":"link","label":"Macros","href":"/docs/scheme-intro/macros","docId":"scheme-intro/macros","unlisted":false},{"type":"link","label":"Streams","href":"/docs/scheme-intro/streams","docId":"scheme-intro/streams","unlisted":false},{"type":"link","label":"Continuations","href":"/docs/scheme-intro/continuations","docId":"scheme-intro/continuations","unlisted":false},{"type":"link","label":"What Next?","href":"/docs/scheme-intro/next-step","docId":"scheme-intro/next-step","unlisted":false}],"href":"/docs/category/introduction-to-scheme"},{"type":"category","label":"LIPS Documentation","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Core features","href":"/docs/lips/intro","docId":"lips/intro","unlisted":false},{"type":"link","label":"Reflection","href":"/docs/lips/reflection","docId":"lips/reflection","unlisted":false},{"type":"link","label":"SXML (e.g. for React)","href":"/docs/lips/sxml","docId":"lips/sxml","unlisted":false},{"type":"link","label":"Environments","href":"/docs/lips/environments","docId":"lips/environments","unlisted":false},{"type":"link","label":"Functional and other utils","href":"/docs/lips/functional-helpers","docId":"lips/functional-helpers","unlisted":false},{"type":"link","label":"Extending LIPS","href":"/docs/lips/extension","docId":"lips/extension","unlisted":false},{"type":"link","label":"REPL","href":"/docs/lips/REPL","docId":"lips/REPL","unlisted":false},{"type":"link","label":"SRFI","href":"/docs/lips/SRFI","docId":"lips/SRFI","unlisted":false},{"type":"link","label":"Embedding LIPS REPL","href":"/docs/lips/embeding-repl","docId":"lips/embeding-repl","unlisted":false}],"href":"/docs/category/lips-introduction"}]},"docs":{"intro":{"id":"intro","title":"Getting Started","description":"Browser","sidebar":"tutorialSidebar"},"lips/embeding-repl":{"id":"lips/embeding-repl","title":"Embedding LIPS REPL","description":"Embedding the LIPS Scheme REPL","sidebar":"tutorialSidebar"},"lips/environments":{"id":"lips/environments","title":"Environments","description":"Environments in LIPS are first class objects","sidebar":"tutorialSidebar"},"lips/extension":{"id":"lips/extension","title":"Extending LIPS","description":"A way to extends LIPS syntax, not only with macros","sidebar":"tutorialSidebar"},"lips/functional-helpers":{"id":"lips/functional-helpers","title":"Functional and other utils","description":"Code that allows to do more with less","sidebar":"tutorialSidebar"},"lips/intro":{"id":"lips/intro","title":"Core features","description":"Core LIPS features added on top of Scheme, related to JavaScript","sidebar":"tutorialSidebar"},"lips/reflection":{"id":"lips/reflection","title":"Reflection","description":"A way to introspect and manipulate LIPS internals","sidebar":"tutorialSidebar"},"lips/REPL":{"id":"lips/REPL","title":"REPL","description":"features of Node.js and Web REPL","sidebar":"tutorialSidebar"},"lips/SRFI":{"id":"lips/SRFI","title":"SRFI","description":"List of supported SRFI","sidebar":"tutorialSidebar"},"lips/sxml":{"id":"lips/sxml","title":"SXML (e.g. for React)","description":"SXML it\'s what JSX is for JavaScript","sidebar":"tutorialSidebar"},"scheme-intro/continuations":{"id":"scheme-intro/continuations","title":"Continuations","description":"Powerful feature of Scheme that allow to add new control flows","sidebar":"tutorialSidebar"},"scheme-intro/core":{"id":"scheme-intro/core","title":"Core of Scheme","description":"Main article that shows most of the features of Scheme","sidebar":"tutorialSidebar"},"scheme-intro/data-types":{"id":"scheme-intro/data-types","title":"Data Types","description":"All different data types you can have in Scheme","sidebar":"tutorialSidebar"},"scheme-intro/input-output":{"id":"scheme-intro/input-output","title":"Input and Output","description":"How to read/write files and how to interact with stdin/stdout","sidebar":"tutorialSidebar"},"scheme-intro/macros":{"id":"scheme-intro/macros","title":"Macros","description":"Macros are the most powerful feature of Lisp and Scheme","sidebar":"tutorialSidebar"},"scheme-intro/next-step":{"id":"scheme-intro/next-step","title":"What Next?","description":"Few resources how to learn more about Scheme","sidebar":"tutorialSidebar"},"scheme-intro/streams":{"id":"scheme-intro/streams","title":"Streams","description":"Feature of scheme that allow to create lazy lists","sidebar":"tutorialSidebar"},"scheme-intro/what-is-lisp":{"id":"scheme-intro/what-is-lisp","title":"What is Lisp and Scheme?","description":"What is Lisp and what is Scheme and a bit of history","sidebar":"tutorialSidebar"}}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/13a1c259.c938df1a.js b/assets/js/13a1c259.c938df1a.js
new file mode 100644
index 00000000..c9e94185
--- /dev/null
+++ b/assets/js/13a1c259.c938df1a.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunknew_docs=self.webpackChunknew_docs||[]).push([[3484],{3202:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"LIPS Documentation","slug":"/category/lips-introduction","permalink":"/docs/category/lips-introduction","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"What Next?","permalink":"/docs/scheme-intro/next-step"},"next":{"title":"Core features","permalink":"/docs/lips/intro"}}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/13a1c259.ce796566.js b/assets/js/13a1c259.ce796566.js
deleted file mode 100644
index 395dc88f..00000000
--- a/assets/js/13a1c259.ce796566.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunknew_docs=self.webpackChunknew_docs||[]).push([[3484],{3202:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"LIPS introduction","slug":"/category/lips-introduction","permalink":"/docs/category/lips-introduction","sidebar":"tutorialSidebar","navigation":{"previous":{"title":"What Next?","permalink":"/docs/scheme-intro/next-step"},"next":{"title":"Core features","permalink":"/docs/lips/intro"}}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/840797c7.442699c4.js b/assets/js/840797c7.442699c4.js
new file mode 100644
index 00000000..82a5b99f
--- /dev/null
+++ b/assets/js/840797c7.442699c4.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunknew_docs=self.webpackChunknew_docs||[]).push([[478],{3055:(e,A,s)=>{s.r(A),s.d(A,{assets:()=>i,contentTitle:()=>o,default:()=>a,frontMatter:()=>c,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"scheme-intro/next-step","title":"What Next?","description":"Few resources how to learn more about Scheme","source":"@site/docs/scheme-intro/next-step.md","sourceDirName":"scheme-intro","slug":"/scheme-intro/next-step","permalink":"/docs/scheme-intro/next-step","draft":false,"unlisted":false,"editUrl":"https://github.com/LIPS-scheme/lips/tree/master/docs/docs/scheme-intro/next-step.md","tags":[],"version":"current","sidebarPosition":8,"frontMatter":{"sidebar_position":8,"description":"Few resources how to learn more about Scheme"},"sidebar":"tutorialSidebar","previous":{"title":"Continuations","permalink":"/docs/scheme-intro/continuations"},"next":{"title":"LIPS Documentation","permalink":"/docs/category/lips-introduction"}}');var n=s(4848),t=s(8453);const c={sidebar_position:8,description:"Few resources how to learn more about Scheme"},o="What Next?",i={},h=[{value:"Scheme",id:"scheme",level:2},{value:"Lisp Macros",id:"lisp-macros",level:2},{value:"Scheme hygienic macros",id:"scheme-hygienic-macros",level:2},{value:"More Resources",id:"more-resources",level:2}];function l(e){const A={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(A.header,{children:(0,n.jsx)(A.h1,{id:"what-next",children:"What Next?"})}),"\n",(0,n.jsx)(A.p,{children:"If you want to learn more about Scheme, here are some recommended resources:"}),"\n",(0,n.jsx)(A.h2,{id:"scheme",children:"Scheme"}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsxs)(A.li,{children:[(0,n.jsx)(A.a,{href:"https://www.t3x.org/sketchy/",children:"Sketchy Scheme"})," by ",(0,n.jsx)(A.a,{href:"https://www.t3x.org/",children:"Nils M Holm"})]}),"\n"]}),"\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.img,{alt:"Sketchy Scheme Book Cover",src:s(8446).A+"",width:"417",height:"621"})}),"\n",(0,n.jsxs)(A.p,{children:["There is a free version in Archive.org called ",(0,n.jsx)(A.a,{href:"https://archive.org/details/sketchy-lisp",children:"Sketchy Lisp"})," but I recommend latest version."]}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsx)(A.li,{children:(0,n.jsx)(A.a,{href:"https://web.mit.edu/6.001/6.037/sicp.pdf",children:"Structure and Interpretation of Computer Programs"})}),"\n"]}),"\n",(0,n.jsx)(A.p,{children:"A classic, one of the authors of the book is the author of Scheme language."}),"\n",(0,n.jsxs)(A.p,{children:[(0,n.jsx)(A.img,{alt:"SICP Cover",src:s(2938).A+"",width:"400",height:"579"}),(0,n.jsx)("br",{}),"\n",(0,n.jsxs)("small",{children:[(0,n.jsx)("a",{href:"https://commons.wikimedia.org/wiki/File:SICP_cover.jpg",children:"Harold Abelson and Gerald Jay Sussman with Julie Sussman\xa0\u2014\xa0MIT Press"}),", ",(0,n.jsx)("a",{href:"https://creativecommons.org/licenses/by-sa/4.0",children:"CC BY-SA 4.0"}),", Wikimedia Commons"]})]}),"\n",(0,n.jsx)(A.p,{children:"I also recommend video lectures. There are two versions. I recommend original by Abelson and Sussman from 1986."}),"\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.a,{href:"https://www.youtube.com/playlist?list=PLB63C06FAF154F047",children:(0,n.jsx)(A.img,{alt:"SICP MIT Lectures",src:s(234).A+"",width:"320",height:"240"})})}),"\n",(0,n.jsxs)(A.p,{children:["Here is the ",(0,n.jsx)(A.a,{href:"https://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/",children:"official website of the lectures"}),"."]}),"\n",(0,n.jsx)(A.p,{children:"They are not very good quality, but they are great, and you should have no problems in seeing the\ncode on the blackboard."}),"\n",(0,n.jsxs)(A.p,{children:["There are also more recent lectures from 2010 at ",(0,n.jsx)(A.a,{href:"https://www.berkeley.edu/",children:"Berkeley"})," by\n",(0,n.jsx)(A.a,{href:"https://people.eecs.berkeley.edu/~bh/",children:"Brian Harvey"}),". Only a little bit better quality."]}),"\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.a,{href:"https://www.youtube.com/playlist?list=PLhMnuBfGeCDNgVzLPxF9o5UNKG1b-LFY9",children:(0,n.jsx)(A.img,{alt:"UC Berkeley CS 61A The Structure and Interpretation of Computer Programs, Spring 2010",src:s(4373).A+"",width:"320",height:"240"})})}),"\n",(0,n.jsx)(A.h2,{id:"lisp-macros",children:"Lisp Macros"}),"\n",(0,n.jsx)(A.p,{children:"If you want to learn more about lisp macros, there are two great books:"}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsxs)(A.li,{children:["\n",(0,n.jsxs)(A.p,{children:[(0,n.jsx)(A.a,{href:"https://www.paulgraham.com/onlisp.html",children:"On Lisp"})," by ",(0,n.jsx)(A.a,{href:"https://www.paulgraham.com",children:"Paul Graham"})]}),"\n",(0,n.jsx)(A.p,{children:"The book is out of print, and you can download it for free. But if you prefer printed books, you\ncan get it printed on Lulu Express."}),"\n",(0,n.jsx)(A.p,{children:"Here is article that explain how to do this:"}),"\n"]}),"\n",(0,n.jsxs)(A.li,{children:["\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.a,{href:"https://www.lurklurk.org/onlisp/onlisp.html",children:'Piecing Together a Printed Copy of "On Lisp"'})}),"\n",(0,n.jsxs)(A.p,{children:["You can also read this ",(0,n.jsx)(A.a,{href:"https://www.reddit.com/r/lisp/comments/l71amc/on_lisp_paperback_replica/",children:"discussion on\nReddit"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(A.li,{children:["\n",(0,n.jsxs)(A.p,{children:["Another great book about advanced lisp macros is ",(0,n.jsx)(A.a,{href:"https://letoverlambda.com/",children:"Let over Lambda"})," by\n",(0,n.jsx)(A.a,{href:"https://hoytech.com/",children:"Doug Hoyte"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(A.h2,{id:"scheme-hygienic-macros",children:"Scheme hygienic macros"}),"\n",(0,n.jsxs)(A.p,{children:[(0,n.jsx)(A.strong,{children:"NOTE"}),": Unfortunately, there are no good books about Scheme hygienic macros. But you can read\nthose documents:"]}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsxs)(A.li,{children:[(0,n.jsx)(A.a,{href:"https://github.com/mnieper/scheme-macros",children:"Writing Powerful Macros in Scheme"})," by ",(0,n.jsx)(A.a,{href:"https://github.com/mnieper",children:"Marc\nNieper-Wi\xdfkirchen"}),"."]}),"\n",(0,n.jsx)(A.li,{children:(0,n.jsx)(A.a,{href:"http://www.phyast.pitt.edu/~micheles/syntax-rules.pdf",children:"JRM\u2019s Syntax-rules Primer for the Merely Eccentric"})}),"\n",(0,n.jsxs)(A.li,{children:[(0,n.jsx)(A.a,{href:"https://www.eighty-twenty.org/~tonyg/Darcs/macromod/doc/reference/petrofsky/petrofsky-advanced-syntax-rules-primer-for-the-mildly-insane.txt",children:"An Advanced Syntax-Rules Primer for the Mildly Insane"})," by Al Petrofsky."]}),"\n",(0,n.jsxs)(A.li,{children:["Oleg Kiselyov part of the website contains ",(0,n.jsx)(A.a,{href:"https://okmij.org/ftp/Scheme/macros.html",children:"advanced usage of Scheme maros"}),"."]}),"\n"]}),"\n",(0,n.jsx)(A.p,{children:"You can also find additional resources in these Reddit posts:"}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsx)(A.li,{children:(0,n.jsx)(A.a,{href:"https://www.reddit.com/r/scheme/comments/3chowf/collection_of_links_about_scheme_macros/",children:"Collection of Links About Scheme Macros"})}),"\n"]}),"\n",(0,n.jsx)(A.h2,{id:"more-resources",children:"More Resources"}),"\n",(0,n.jsxs)(A.p,{children:["You can find common recipes inside ",(0,n.jsx)(A.a,{href:"https://cookbook.scheme.org/",children:"Scheme Cookbook"})," and ",(0,n.jsx)(A.a,{href:"https://books.scheme.org/",children:"more books\nabout Scheme"})," on ",(0,n.jsx)(A.a,{href:"https://www.scheme.org/",children:"official Scheme website"}),"."]})]})}function a(e={}){const{wrapper:A}={...(0,t.R)(),...e.components};return A?(0,n.jsx)(A,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},4373:(e,A,s)=>{s.d(A,{A:()=>r});const r=s.p+"assets/images/SCIP-lectures-berkley-9dcb64a06d3ce6ec281dc003f894e6c5.jpg"},2938:(e,A,s)=>{s.d(A,{A:()=>r});const r=s.p+"assets/images/SICP-cover-5b2540e90b3fe95223bfb2c4aea5c160.jpg"},234:(e,A,s)=>{s.d(A,{A:()=>r});const r=s.p+"assets/images/SICP-lectures-ce39601d03e68eb5ee40bced0737452f.jpg"},8446:(e,A,s)=>{s.d(A,{A:()=>r});const r="data:image/png;base64,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"},8453:(e,A,s)=>{s.d(A,{R:()=>c,x:()=>o});var r=s(6540);const n={},t=r.createContext(n);function c(e){const A=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(A):{...A,...e}}),[A,e])}function o(e){let A;return A=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),r.createElement(t.Provider,{value:A},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/840797c7.c96b5ad6.js b/assets/js/840797c7.c96b5ad6.js
deleted file mode 100644
index 8144ab62..00000000
--- a/assets/js/840797c7.c96b5ad6.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunknew_docs=self.webpackChunknew_docs||[]).push([[478],{3055:(e,A,s)=>{s.r(A),s.d(A,{assets:()=>i,contentTitle:()=>o,default:()=>a,frontMatter:()=>c,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"scheme-intro/next-step","title":"What Next?","description":"Few resources how to learn more about Scheme","source":"@site/docs/scheme-intro/next-step.md","sourceDirName":"scheme-intro","slug":"/scheme-intro/next-step","permalink":"/docs/scheme-intro/next-step","draft":false,"unlisted":false,"editUrl":"https://github.com/LIPS-scheme/lips/tree/master/docs/docs/scheme-intro/next-step.md","tags":[],"version":"current","sidebarPosition":8,"frontMatter":{"sidebar_position":8,"description":"Few resources how to learn more about Scheme"},"sidebar":"tutorialSidebar","previous":{"title":"Continuations","permalink":"/docs/scheme-intro/continuations"},"next":{"title":"LIPS introduction","permalink":"/docs/category/lips-introduction"}}');var n=s(4848),t=s(8453);const c={sidebar_position:8,description:"Few resources how to learn more about Scheme"},o="What Next?",i={},h=[{value:"Scheme",id:"scheme",level:2},{value:"Lisp Macros",id:"lisp-macros",level:2},{value:"Scheme hygienic macros",id:"scheme-hygienic-macros",level:2},{value:"More Resources",id:"more-resources",level:2}];function l(e){const A={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(A.header,{children:(0,n.jsx)(A.h1,{id:"what-next",children:"What Next?"})}),"\n",(0,n.jsx)(A.p,{children:"If you want to learn more about Scheme, here are some recommended resources:"}),"\n",(0,n.jsx)(A.h2,{id:"scheme",children:"Scheme"}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsxs)(A.li,{children:[(0,n.jsx)(A.a,{href:"https://www.t3x.org/sketchy/",children:"Sketchy Scheme"})," by ",(0,n.jsx)(A.a,{href:"https://www.t3x.org/",children:"Nils M Holm"})]}),"\n"]}),"\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.img,{alt:"Sketchy Scheme Book Cover",src:s(8446).A+"",width:"417",height:"621"})}),"\n",(0,n.jsxs)(A.p,{children:["There is a free version in Archive.org called ",(0,n.jsx)(A.a,{href:"https://archive.org/details/sketchy-lisp",children:"Sketchy Lisp"})," but I recommend latest version."]}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsx)(A.li,{children:(0,n.jsx)(A.a,{href:"https://web.mit.edu/6.001/6.037/sicp.pdf",children:"Structure and Interpretation of Computer Programs"})}),"\n"]}),"\n",(0,n.jsx)(A.p,{children:"A classic, one of the authors of the book is the author of Scheme language."}),"\n",(0,n.jsxs)(A.p,{children:[(0,n.jsx)(A.img,{alt:"SICP Cover",src:s(2938).A+"",width:"400",height:"579"}),(0,n.jsx)("br",{}),"\n",(0,n.jsxs)("small",{children:[(0,n.jsx)("a",{href:"https://commons.wikimedia.org/wiki/File:SICP_cover.jpg",children:"Harold Abelson and Gerald Jay Sussman with Julie Sussman\xa0\u2014\xa0MIT Press"}),", ",(0,n.jsx)("a",{href:"https://creativecommons.org/licenses/by-sa/4.0",children:"CC BY-SA 4.0"}),", Wikimedia Commons"]})]}),"\n",(0,n.jsx)(A.p,{children:"I also recommend video lectures. There are two versions. I recommend original by Abelson and Sussman from 1986."}),"\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.a,{href:"https://www.youtube.com/playlist?list=PLB63C06FAF154F047",children:(0,n.jsx)(A.img,{alt:"SICP MIT Lectures",src:s(234).A+"",width:"320",height:"240"})})}),"\n",(0,n.jsxs)(A.p,{children:["Here is the ",(0,n.jsx)(A.a,{href:"https://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/",children:"official website of the lectures"}),"."]}),"\n",(0,n.jsx)(A.p,{children:"They are not very good quality, but they are great, and you should have no problems in seeing the\ncode on the blackboard."}),"\n",(0,n.jsxs)(A.p,{children:["There are also more recent lectures from 2010 at ",(0,n.jsx)(A.a,{href:"https://www.berkeley.edu/",children:"Berkeley"})," by\n",(0,n.jsx)(A.a,{href:"https://people.eecs.berkeley.edu/~bh/",children:"Brian Harvey"}),". Only a little bit better quality."]}),"\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.a,{href:"https://www.youtube.com/playlist?list=PLhMnuBfGeCDNgVzLPxF9o5UNKG1b-LFY9",children:(0,n.jsx)(A.img,{alt:"UC Berkeley CS 61A The Structure and Interpretation of Computer Programs, Spring 2010",src:s(4373).A+"",width:"320",height:"240"})})}),"\n",(0,n.jsx)(A.h2,{id:"lisp-macros",children:"Lisp Macros"}),"\n",(0,n.jsx)(A.p,{children:"If you want to learn more about lisp macros, there are two great books:"}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsxs)(A.li,{children:["\n",(0,n.jsxs)(A.p,{children:[(0,n.jsx)(A.a,{href:"https://www.paulgraham.com/onlisp.html",children:"On Lisp"})," by ",(0,n.jsx)(A.a,{href:"https://www.paulgraham.com",children:"Paul Graham"})]}),"\n",(0,n.jsx)(A.p,{children:"The book is out of print, and you can download it for free. But if you prefer printed books, you\ncan get it printed on Lulu Express."}),"\n",(0,n.jsx)(A.p,{children:"Here is article that explain how to do this:"}),"\n"]}),"\n",(0,n.jsxs)(A.li,{children:["\n",(0,n.jsx)(A.p,{children:(0,n.jsx)(A.a,{href:"https://www.lurklurk.org/onlisp/onlisp.html",children:'Piecing Together a Printed Copy of "On Lisp"'})}),"\n",(0,n.jsxs)(A.p,{children:["You can also read this ",(0,n.jsx)(A.a,{href:"https://www.reddit.com/r/lisp/comments/l71amc/on_lisp_paperback_replica/",children:"discussion on\nReddit"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(A.li,{children:["\n",(0,n.jsxs)(A.p,{children:["Another great book about advanced lisp macros is ",(0,n.jsx)(A.a,{href:"https://letoverlambda.com/",children:"Let over Lambda"})," by\n",(0,n.jsx)(A.a,{href:"https://hoytech.com/",children:"Doug Hoyte"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(A.h2,{id:"scheme-hygienic-macros",children:"Scheme hygienic macros"}),"\n",(0,n.jsxs)(A.p,{children:[(0,n.jsx)(A.strong,{children:"NOTE"}),": Unfortunately, there are no good books about Scheme hygienic macros. But you can read\nthose documents:"]}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsxs)(A.li,{children:[(0,n.jsx)(A.a,{href:"https://github.com/mnieper/scheme-macros",children:"Writing Powerful Macros in Scheme"})," by ",(0,n.jsx)(A.a,{href:"https://github.com/mnieper",children:"Marc\nNieper-Wi\xdfkirchen"}),"."]}),"\n",(0,n.jsx)(A.li,{children:(0,n.jsx)(A.a,{href:"http://www.phyast.pitt.edu/~micheles/syntax-rules.pdf",children:"JRM\u2019s Syntax-rules Primer for the Merely Eccentric"})}),"\n",(0,n.jsxs)(A.li,{children:[(0,n.jsx)(A.a,{href:"https://www.eighty-twenty.org/~tonyg/Darcs/macromod/doc/reference/petrofsky/petrofsky-advanced-syntax-rules-primer-for-the-mildly-insane.txt",children:"An Advanced Syntax-Rules Primer for the Mildly Insane"})," by Al Petrofsky."]}),"\n",(0,n.jsxs)(A.li,{children:["Oleg Kiselyov part of the website contains ",(0,n.jsx)(A.a,{href:"https://okmij.org/ftp/Scheme/macros.html",children:"advanced usage of Scheme maros"}),"."]}),"\n"]}),"\n",(0,n.jsx)(A.p,{children:"You can also find additional resources in these Reddit posts:"}),"\n",(0,n.jsxs)(A.ul,{children:["\n",(0,n.jsx)(A.li,{children:(0,n.jsx)(A.a,{href:"https://www.reddit.com/r/scheme/comments/3chowf/collection_of_links_about_scheme_macros/",children:"Collection of Links About Scheme Macros"})}),"\n"]}),"\n",(0,n.jsx)(A.h2,{id:"more-resources",children:"More Resources"}),"\n",(0,n.jsxs)(A.p,{children:["You can find common recipes inside ",(0,n.jsx)(A.a,{href:"https://cookbook.scheme.org/",children:"Scheme Cookbook"})," and ",(0,n.jsx)(A.a,{href:"https://books.scheme.org/",children:"more books\nabout Scheme"})," on ",(0,n.jsx)(A.a,{href:"https://www.scheme.org/",children:"official Scheme website"}),"."]})]})}function a(e={}){const{wrapper:A}={...(0,t.R)(),...e.components};return A?(0,n.jsx)(A,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},4373:(e,A,s)=>{s.d(A,{A:()=>r});const r=s.p+"assets/images/SCIP-lectures-berkley-9dcb64a06d3ce6ec281dc003f894e6c5.jpg"},2938:(e,A,s)=>{s.d(A,{A:()=>r});const r=s.p+"assets/images/SICP-cover-5b2540e90b3fe95223bfb2c4aea5c160.jpg"},234:(e,A,s)=>{s.d(A,{A:()=>r});const r=s.p+"assets/images/SICP-lectures-ce39601d03e68eb5ee40bced0737452f.jpg"},8446:(e,A,s)=>{s.d(A,{A:()=>r});const r="data:image/png;base64,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"},8453:(e,A,s)=>{s.d(A,{R:()=>c,x:()=>o});var r=s(6540);const n={},t=r.createContext(n);function c(e){const A=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(A):{...A,...e}}),[A,e])}function o(e){let A;return A=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),r.createElement(t.Provider,{value:A},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/e1902777.a8610025.js b/assets/js/e1902777.a8610025.js
deleted file mode 100644
index 70f6a6a6..00000000
--- a/assets/js/e1902777.a8610025.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunknew_docs=self.webpackChunknew_docs||[]).push([[8177],{4877:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"lips/intro","title":"Core features","description":"Core LIPS features added on top of Scheme, related to JavaScript","source":"@site/docs/lips/intro.md","sourceDirName":"lips","slug":"/lips/intro","permalink":"/docs/lips/intro","draft":false,"unlisted":false,"editUrl":"https://github.com/LIPS-scheme/lips/tree/master/docs/docs/lips/intro.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_position":1,"description":"Core LIPS features added on top of Scheme, related to JavaScript"},"sidebar":"tutorialSidebar","previous":{"title":"LIPS introduction","permalink":"/docs/category/lips-introduction"},"next":{"title":"Reflection","permalink":"/docs/lips/reflection"}}');var a=s(4848),i=s(8453);const t={sidebar_position:1,description:"Core LIPS features added on top of Scheme, related to JavaScript"},c="Core features",o={},l=[{value:"Special constants",id:"special-constants",level:2},{value:"Numerical tower",id:"numerical-tower",level:2},{value:"Print procedure",id:"print-procedure",level:2},{value:"Emoji",id:"emoji",level:2},{value:"Macros",id:"macros",level:2},{value:"Gensyms",id:"gensyms",level:3},{value:"Single argument eval",id:"single-argument-eval",level:2},{value:"Procedures",id:"procedures",level:2},{value:"length property",id:"length-property",level:3},{value:"Doc strings",id:"doc-strings",level:2},{value:"Typechecking",id:"typechecking",level:2},{value:"Integration with JavaScript",id:"integration-with-javascript",level:2},{value:"Dot notation",id:"dot-notation",level:3},{value:"Mutating object properties",id:"mutating-object-properties",level:3},{value:"Date and Time",id:"date-and-time",level:3},{value:"Interact with DOM",id:"interact-with-dom",level:3},{value:"Boxing",id:"boxing",level:3},{value:"Procedures",id:"procedures-1",level:3},{value:"Procedure arity",id:"procedure-arity",level:4},{value:"Helper macros and functions",id:"helper-macros-and-functions",level:3},{value:"Legacy macros and functions",id:"legacy-macros-and-functions",level:4},{value:"The dot operator",id:"the-dot-operator",level:5},{value:"The double dot operator",id:"the-double-dot-operator",level:5},{value:"Usage of Legacy .. and . operators",id:"usage-of-legacy--and--operators",level:5},{value:"Scheme functions",id:"scheme-functions",level:3},{value:"JavaScript functions",id:"javascript-functions",level:3},{value:"Callbacks",id:"callbacks",level:3},{value:"Regular Expressions",id:"regular-expressions",level:3},{value:"Vectors",id:"vectors",level:3},{value:"Object literals",id:"object-literals",level:3},{value:"Automagic async/await",id:"automagic-asyncawait",level:3},{value:"Promise quotation",id:"promise-quotation",level:3},{value:"Promises vs delay expression",id:"promises-vs-delay-expression",level:3},{value:"Exceptions",id:"exceptions",level:3},{value:"JavaScript Generars and iterators",id:"javascript-generars-and-iterators",level:3},{value:"Classes",id:"classes",level:3},{value:"Node.js",id:"nodejs",level:3},{value:"ES Modules",id:"es-modules",level:3},{value:"Finding LIPS Scheme directory",id:"finding-lips-scheme-directory",level:3},{value:"Binary compiler",id:"binary-compiler",level:2},{value:"loading SRFI",id:"loading-srfi",level:2},{value:"Limitations",id:"limitations",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"core-features",children:"Core features"})}),"\n",(0,a.jsx)(n.h2,{id:"special-constants",children:"Special constants"}),"\n",(0,a.jsxs)(n.p,{children:["LIPS define ",(0,a.jsx)(n.code,{children:"#null"})," and ",(0,a.jsx)(n.code,{children:"#void"})," as Parser constants so they can be used inside quoted expressions:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(let ((lst '(#null #void)))\n (write (symbol? (car lst)))\n (newline)\n (write (symbol? (cadr lst)))\n (newline))\n;; ==> #f\n;; ==> #f\n"})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"NOTE"})," ",(0,a.jsx)(n.code,{children:"#null"})," is the same as JavaScript ",(0,a.jsx)(n.code,{children:"null"})," value and it's a false value. Similar to\n",(0,a.jsx)(n.a,{href:"https://www.gnu.org/software/kawa/index.html",children:"Kawa Scheme"})," that use ",(0,a.jsx)(n.code,{children:"#!null"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"#void"})," constants is the same as result of ",(0,a.jsx)(n.code,{children:"(value)"})," or ",(0,a.jsx)(n.code,{children:"(if #f #f)"}),". In Scheme it's unspecified value,\nbut in LIPS it's JavaScript undefined. ",(0,a.jsx)(n.code,{children:"#void"})," is not false value."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(eq? (if #f #f) (values))\n;; ==> #t\n"})}),"\n",(0,a.jsx)(n.h2,{id:"numerical-tower",children:"Numerical tower"}),"\n",(0,a.jsx)(n.p,{children:"LIPS support full numerical tower (not yet 100% unit tested):"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"integers - using BitInt"}),"\n",(0,a.jsx)(n.li,{children:"floats - using JavaScript numbers"}),"\n",(0,a.jsx)(n.li,{children:"rationals"}),"\n",(0,a.jsx)(n.li,{children:"complex numbers (that can use integers, floats, or rationals)"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"print-procedure",children:"Print procedure"}),"\n",(0,a.jsxs)(n.p,{children:["LIPS define helper ",(0,a.jsx)(n.code,{children:"print"})," procedure that display all its arguments with newline after each element."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(print 1 2 3)\n;; ==> 1\n;; ==> 2\n;; ==> 3\n"})}),"\n",(0,a.jsx)(n.h2,{id:"emoji",children:"Emoji"}),"\n",(0,a.jsx)(n.p,{children:"LIPS fully supports all Unicode characters, including emoji:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define smiley #\\\ud83d\ude00)\n(define poo #\\\ud83d\udca9)\n(write (string-append (string smiley) " " (string poo)))\n;; ==> "\ud83d\ude00 \ud83d\udca9"\n'})}),"\n",(0,a.jsx)(n.p,{children:"You can also use them as part of symbols (e.g. as variables name):"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define (\u23cf\ufe0f)\n (print "ejecting"))\n(\u23cf\ufe0f)\n;; ==> ejecting\n'})}),"\n",(0,a.jsx)(n.h2,{id:"macros",children:"Macros"}),"\n",(0,a.jsxs)(n.p,{children:["LIPS define both Lisp macros and Scheme hygienic macros (",(0,a.jsx)(n.code,{children:"syntax-rules"}),")."]}),"\n",(0,a.jsx)(n.p,{children:"It also implements:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://srfi.schemers.org/srfi-46/",children:"SRFI-46"})," which allows changing the ellipsis symbol for nested syntax-rules."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://srfi.schemers.org/srfi-139/",children:"SRFI-139"})," which allows defining\n",(0,a.jsx)(n.a,{href:"/docs/scheme-intro/macros#anaphoric-hygienic-macros",children:"anaphoric syntax-rules macros"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://srfi.schemers.org/srfi-147/",children:"SRFI-147"})," which allows defining a new syntax-rules macros to define syntax-rules macros."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"gensyms",children:"Gensyms"}),"\n",(0,a.jsxs)(n.p,{children:["With lisp macros you can use ",(0,a.jsx)(n.a,{href:"/docs/scheme-intro/macros#gensyms",children:"gensyms"}),", they are special Scheme\nsymbols that use JavaScript symbols behind the scene, so they are proven to be unique. Additionally\nyou can use named gensym if you pass string as first argument:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(gensym)\n;; ==> #:g5\n(gensym "sym")\n;; ==> #:sym\n'})}),"\n",(0,a.jsx)(n.h2,{id:"single-argument-eval",children:"Single argument eval"}),"\n",(0,a.jsxs)(n.p,{children:["Eval in LIPS don't require second argument to ",(0,a.jsx)(n.code,{children:"eval"}),". The environment is optional and default\nit's a result of calling ",(0,a.jsx)(n.code,{children:"(interaction-environment)"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(define x 10)\n(eval '(+ x x))\n;; ==> 20\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(define x 10)\n(let ((x 20))\n (eval '(- x)))\n;; ==> -10\n"})}),"\n",(0,a.jsx)(n.p,{children:"But you can also use the second arguments:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(define x 10)\n(let ((x 20))\n (eval '(- x) (current-environment)))\n;; ==> -20\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Read more about ",(0,a.jsx)(n.a,{href:"/docs/lips/environments",children:"LIPS environments"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"procedures",children:"Procedures"}),"\n",(0,a.jsxs)(n.p,{children:["Procedures in LIPS have access additional objects ",(0,a.jsx)(n.code,{children:"arguments"}),", but the have nothing to do with JavaScript.\narguments is an array/vector with calling arguments and it have an object callee which points to the same\nprocedure. So you can create recursive functions with anonymous lambda:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"((lambda (n)\n (if (<= n 0)\n 1\n (* n (arguments.callee (- n 1))))) 10)\n;; ==> 3628800\n"})}),"\n",(0,a.jsx)(n.p,{children:"This is classic factorial function written as lambda without the name."}),"\n",(0,a.jsx)(n.h3,{id:"length-property",children:"length property"}),"\n",(0,a.jsxs)(n.p,{children:["LIPS functions similarly to JavaScript functions also have ",(0,a.jsx)(n.code,{children:"length"})," property that indicate how many\narguments a function accepts. If function get more or less argumenets it's not an error like in Scheme. More arguments are ignored,\nand if less arguments are passed they are ",(0,a.jsx)(n.code,{children:"undefined"})," (",(0,a.jsx)(n.code,{children:"#void"}),")."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(define (sum a b c)\n (+ a b c))\n\n(print sum.length)\n;; ==> 3\n"})}),"\n",(0,a.jsx)(n.p,{children:"It return number of number arguments the rest (dot notation) arguments are ignored."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(define (sum a b . rest)\n (apply + a b rest))\n\n(print sum.length)\n;; ==> 3\n(sum 1 2 3 4 5 6)\n;; ==> 21\n"})}),"\n",(0,a.jsx)(n.h2,{id:"doc-strings",children:"Doc strings"}),"\n",(0,a.jsx)(n.p,{children:"Procedures, macros, and variables can have doc strings."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define (factorial n)\n "(factorial n)\n\n Calculate factorial of a given number"\n (if (<= n 0)\n 1\n (* n (factorial (- n 1)))))\n'})}),"\n",(0,a.jsxs)(n.p,{children:["You can access doc string with ",(0,a.jsx)(n.code,{children:"help"})," procedure or with ",(0,a.jsx)(n.code,{children:"__doc__"})," property."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(write factorial.__doc__)\n"(factorial n)\n\nCalculate factorial of a given number"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["If you define variable or hygienic macro with doc string, the string is hidden (you can access it with ",(0,a.jsx)(n.code,{children:"__doc__"}),"),\nso help is the only way to access it:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define-syntax q\n (syntax-rules ()\n ((_ x) \'x))\n "(q expression)\n\n Macro quote the expression")\n\n(write q.__doc__)\n;; ==> #void\n(help q)\n;; ==> (q expression)\n;; ==>\n;; ==> Macro quote the expression\n'})}),"\n",(0,a.jsx)(n.h2,{id:"typechecking",children:"Typechecking"}),"\n",(0,a.jsx)(n.p,{children:"LIPS do typechecking for all scheme procedures."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(+ "hello" 10)\n;; ==> Expecting number got string\n'})}),"\n",(0,a.jsx)(n.p,{children:"You can incorporate typechecking in your own code:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((x 10))\n (typecheck "let" x "string" 0))\n;; ==> Expecting string got number in expression `let` (argument 0)\n(let ((x "string"))\n (typecheck "let" x "number"))\n;; ==> Expecting number got string in expression `let`\n'})}),"\n",(0,a.jsx)(n.p,{children:"There is also another function to check type of number:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((i 10+10i))\n (typecheck-number "let" i "bigint"))\n;; ==> Expecting bigint got complex in expression `let`\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"NOTE"}),": In LIPS all integers are BigInts."]}),"\n",(0,a.jsxs)(n.p,{children:["The last typecking function is ",(0,a.jsx)(n.code,{children:"typecheck-args"})," that check if all arguments are of same type."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((number \'(1 10 1/2 10+10i)))\n (typecheck-args "number" "let" number))\n;; ==> #void\n(let ((number \'(1 10 1/2 "string")))\n (typecheck-args "number" "let" number))\n;; ==> Expecting number got string in expression `let` (argument 4)\n'})}),"\n",(0,a.jsx)(n.h2,{id:"integration-with-javascript",children:"Integration with JavaScript"}),"\n",(0,a.jsx)(n.h3,{id:"dot-notation",children:"Dot notation"}),"\n",(0,a.jsx)(n.p,{children:"LIPS allow accessing JavaScript objects with dot notation:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"document.querySelector\n;; ==> #\n"})}),"\n",(0,a.jsx)(n.h3,{id:"mutating-object-properties",children:"Mutating object properties"}),"\n",(0,a.jsxs)(n.p,{children:["You can use dot notation with ",(0,a.jsx)(n.code,{children:"set!"})," to change the value:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(set! self.foo 10)\nself.foo\n"})}),"\n",(0,a.jsxs)(n.p,{children:["top level ",(0,a.jsx)(n.code,{children:"self"})," always points to a global object ",(0,a.jsx)(n.code,{children:"window"})," in browser or ",(0,a.jsx)(n.code,{children:"global"})," in Node."]}),"\n",(0,a.jsxs)(n.p,{children:["There is also older API that still work, which is ",(0,a.jsx)(n.code,{children:"set-obj!"})," but with dot notation you don't\nneed it anymore:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(set-obj! self 'foo 10)\n(display self.foo)\n;; ==> 10\n"})}),"\n",(0,a.jsx)(n.p,{children:"In both platforms you can access global JavaScript objects like normal variables:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(set! self.greet "hello, LIPS")\n(write greet)\n;; ==> "hello, LIPS"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"date-and-time",children:"Date and Time"}),"\n",(0,a.jsxs)(n.p,{children:["Since we have full access to JavaScript, we can access the ",(0,a.jsx)(n.code,{children:"Date"})," object to manipulate date and time."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e (new Date "2024-01-01 12:09:2")\n (getFullYear))\n;; ==> 2024\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define (format-part number)\n "(format-part number)\n\n Convert number to string with leading zero. It should be used\n for minutes, hours, and seconds."\n (--\x3e number (toString) (padStart 2 "0")))\n\n(let ((date (new Date "2024-01-01 12:09:02")))\n (format "~a:~a:~a"\n (format-part (date.getHours))\n (format-part (date.getMinutes))\n (format-part (date.getSeconds))))\n;; ==> "12:09:02"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["You can also use Date time libraries like ",(0,a.jsx)(n.a,{href:"https://date-fns.org/",children:"date-fns"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"interact-with-dom",children:"Interact with DOM"}),"\n",(0,a.jsxs)(n.p,{children:["Here is example how to add button to the page and add onclick handler using browser DOM\n(",(0,a.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model",children:"Document Object Model"}),") API."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((button (document.createElement "button")))\n (set! button.innerHTML "click me!")\n (set! button.onclick (lambda () (alert "Hello, LIPS Scheme!")))\n (let ((style button.style))\n (set! style.position "absolute")\n (set! style.zIndex 9999)\n (set! style.top 0)\n (set! style.left 0))\n (document.body.appendChild button))\n'})}),"\n",(0,a.jsx)(n.h3,{id:"boxing",children:"Boxing"}),"\n",(0,a.jsx)(n.p,{children:"LIPS have its own representation for numbers, strings and characters. And when\ninteracting with JavaScript the values may get boxed or unboxed automagically."}),"\n",(0,a.jsxs)(n.p,{children:["You should not confuse boxing with boxes (",(0,a.jsx)(n.a,{href:"https://srfi.schemers.org/srfi-111/",children:"SRFI-111"})," and\n",(0,a.jsx)(n.a,{href:"https://srfi.schemers.org/srfi-195",children:"SRFI-195"}),"). LIPS boxing are part of implementation of Scheme\ndata types. And SRFI boxes are containers written in Scheme. Name boxing came from JavaScript, when\nprimitive values are wrapped in objects when you try to use them in object context (like accessing\na property)."]}),"\n",(0,a.jsx)(n.p,{children:"You need to be careful with some of the JavaScript native methods, since they can unbox the value when you don't\nwhen them to be unboxed."}),"\n",(0,a.jsxs)(n.p,{children:["Example is ",(0,a.jsx)(n.code,{children:"Array::push"})," using with native LIPS types:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(let ((v (vector)))\n (v.push 1/2)\n (print v))\n;; ==> #(0.5)\n"})}),"\n",(0,a.jsx)(n.p,{children:"As you can see the rational number got unboxed and converted into JavaScript float numbers.\nUnboxing always can make you loose some information because LIPS types needs to be converted into native JavaScript\ndata types. And JavaScript doesn't have a notion of rationals, there are only floating point numbers, and big ints."}),"\n",(0,a.jsx)(n.h3,{id:"procedures-1",children:"Procedures"}),"\n",(0,a.jsx)(n.p,{children:"LIPS Scheme procedures are JavaScript functions, so you can call them from JavaScript."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(set! self.greet (lambda () "hello, LIPS"))\n'})}),"\n",(0,a.jsx)(n.p,{children:"You can call this function from JavaScript"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-javascript",children:"console.log(greet());\n// ==> {__string__: 'hello, LIPS'}\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Note that the value was not automagically unboxed because we are no longer in LIPS Scheme code and LIPS can't access native\nJavaScript. So to get the real a string you need to call ",(0,a.jsx)(n.code,{children:"valueoOf()"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-javascript",children:"console.log(greet().valueOf());\n// ==> hello, LIPS\n"})}),"\n",(0,a.jsx)(n.h4,{id:"procedure-arity",children:"Procedure arity"}),"\n",(0,a.jsx)(n.p,{children:"LIPS don't check the number of argumnents when calling a procedure:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(let ((test (lambda (a b c)\n (print a b c))))\n (test 10))\n;; ==> 10\n;; ==> #void\n;; ==> #void\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The same as with JavaScript if you don't pass an argument it will be undefined. But you still have full compatible with Scheme and use ",(0,a.jsx)(n.a,{href:"/docs/scheme-intro/core#variable-number-of-arguments",children:"arguments with variable artity"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(let ((test (lambda (first . rest)\n (apply print first rest))))\n (test 1)\n (test 2 3 4))\n;; ==> 1\n;; ==> 2\n;; ==> 3\n;; ==> 4\n"})}),"\n",(0,a.jsx)(n.h3,{id:"helper-macros-and-functions",children:"Helper macros and functions"}),"\n",(0,a.jsxs)(n.p,{children:["The most useful macro in LIPS (for interacting with JavaScript) is ",(0,a.jsx)(n.code,{children:"--\x3e"})," it acts like a chain of\nmethod calls in JavaScript"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e "this is string" (split " ") (reverse) (join " "))\n;; ==> "string is this"\n'})}),"\n",(0,a.jsx)(n.p,{children:"You can chain methods that return arrays or string and call a method of them. The above expression\nis the same as JavaScript:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-javascript",children:"\"this is string\".split(' ').reverse().join(' ');\n"})}),"\n",(0,a.jsx)(n.p,{children:"With --\x3e you can also gab property of a function:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e #/x/ (test.call #/foo/ "foo"))\n;; ==> #t\n(let ((test-bar (--\x3e #/x/ (test.bind #/bar/i))))\n (test-bar "BAR"))\n;; ==> #t\n'})}),"\n",(0,a.jsx)(n.p,{children:"You can also return a function:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define test (--\x3e #/x/ test))\n(test.call #/foo/ "foo")\n;; ==> #t\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Read more about ",(0,a.jsx)(n.a,{href:"https://tinyurl.com/ykvb836s",children:"function::bind"})," and\n",(0,a.jsx)(n.a,{href:"https://tinyurl.com/yc6j7fdh",children:"function::call"})," on ",(0,a.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/",children:"MDN"}),"."]}),"\n",(0,a.jsx)(n.h4,{id:"legacy-macros-and-functions",children:"Legacy macros and functions"}),"\n",(0,a.jsx)(n.p,{children:"There are two legacy macros that are still part of LIPS, but you don't need\nthem most of the time."}),"\n",(0,a.jsx)(n.h5,{id:"the-dot-operator",children:"The dot operator"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"."})," - dot function was a first way to interact with JavaScript, it allowed to get property from an\nobject:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(. document 'querySelector)\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This returned function querySelector from document object in browser. Note that dot a function can only appear\nas first element of the list (it's handled in special way by the parser). In any other place dot is a pair separator,\nsee documentation about ",(0,a.jsx)(n.a,{href:"/docs/scheme-intro/data-types#pairs",children:"Pairs in Scheme"}),"."]}),"\n",(0,a.jsx)(n.h5,{id:"the-double-dot-operator",children:"The double dot operator"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:".."})," - this is a macro is that simplify usage of ",(0,a.jsx)(n.code,{children:"."})," procedure:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(.. document.querySelector)\n"})}),"\n",(0,a.jsxs)(n.h5,{id:"usage-of-legacy--and--operators",children:["Usage of Legacy ",(0,a.jsx)(n.code,{children:".."})," and ",(0,a.jsx)(n.code,{children:"."})," operators"]}),"\n",(0,a.jsxs)(n.p,{children:["You still sometimes may want to use ",(0,a.jsx)(n.code,{children:"."})," instead of ",(0,a.jsx)(n.code,{children:"--\x3e"})," when you want to get\nproperty from an object returned by expression."]}),"\n",(0,a.jsx)(n.p,{children:"In the old version of LIPS, you have to execute code like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'((. document \'querySelector) "body")\n((.. document.querySelector) "body")\n'})}),"\n",(0,a.jsx)(n.p,{children:"The first expression return a Native JavaScript procedure that is then executed."}),"\n",(0,a.jsx)(n.p,{children:"This is equivalent of:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(document.querySelector "body")\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"NOTE"})," the only time when you still need ",(0,a.jsx)(n.code,{children:"."})," function is when you want to get the property of\nobject returned by expression."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((style (. (document.querySelector "body") \'style)))\n (set! style.background "red"))\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Here we get a ",(0,a.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style",children:"style object"}),"\nfrom ",(0,a.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement",children:"the DOM node"})," without sorting the\nreference to the DOM node."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"NOTE"})," because dot notation in symbols is not special syntax you can use code like this:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(let ((x #(1 2 3)))\n (print x.0)\n (print x.1)\n (print x.2))\n;; ==> 1\n;; ==> 2\n;; ==> 3\n"})}),"\n",(0,a.jsx)(n.h3,{id:"scheme-functions",children:"Scheme functions"}),"\n",(0,a.jsx)(n.p,{children:"Scheme functions (lambda's) are JavaScript functions, so you can call them from JavaScript."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(set! window.foo (lambda () (alert "hello")))\n'})}),"\n",(0,a.jsx)(n.p,{children:"If you define function like this, in browser REPL, you can call it from JavaScript\n(e.g. browser developer console)."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"TODO"})," Screenshot"]}),"\n",(0,a.jsx)(n.h3,{id:"javascript-functions",children:"JavaScript functions"}),"\n",(0,a.jsx)(n.p,{children:"You can call JavaScript functions from Scheme, the same as you call Scheme procedures:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(document.querySelector "body")\n;; ==> #\n'})}),"\n",(0,a.jsxs)(n.p,{children:["In both browser and Node.js you can execute ",(0,a.jsx)(n.code,{children:"console.log"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(console.log "hello, LIPS")\n;; ==> hello, LIPS\n'})}),"\n",(0,a.jsx)(n.h3,{id:"callbacks",children:"Callbacks"}),"\n",(0,a.jsx)(n.p,{children:"You can use Scheme functions as callbacks to JavaScript functions:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e #("1" "2" "3") (map string->number))\n;; ==> #(1 +nan.0 +nan.0)\n'})}),"\n",(0,a.jsx)(n.p,{children:"This is classic issue with functions that accept more than one argument. You have samilar issue\nin JavaScript:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-javascript",children:'["1", "2", "3"].map(parseInt)\n// ==> [1, NaN, NaN]\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"NOTE"}),": the value are different becaseu in Shceme i"]}),"\n",(0,a.jsx)(n.p,{children:"To fix the issue you can\ndefine lambda with single argument:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e #("1" "2" "3") (map (lambda (str) (string->number str))))\n;; ==> #(1 2 3)\n'})}),"\n",(0,a.jsxs)(n.p,{children:["You can also use one of functional helpers insprired by ",(0,a.jsx)(n.a,{href:"https://ramdajs.com/",children:"Ramda"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e #("1" "2" "3") (map (unary string->number)))\n;; ==> #(1 2 3)\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"unary"})," ",(0,a.jsx)(n.a,{href:"/docs/scheme-intro/core#higher-order-functions",children:"higher-order procedure"})," accept a single\nprocedure and return new procedure that accept only one argument."]}),"\n",(0,a.jsxs)(n.p,{children:["To read more check ",(0,a.jsx)(n.a,{href:"/docs/lips/functional-helpers",children:"Functional helpers"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"WARNING"})," be careful when using scheme callback functions inside JavaScript.\nSince some code may be ",(0,a.jsx)(n.code,{children:"async"})," and your code may break."]}),"\n",(0,a.jsx)(n.p,{children:"Example of procedures that are not wise to use are:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"Array::forEach"})," - this function accepts a callaback but because it doesn't return\nanything, LIPS can't automatically await the response, and your code may execute out of order."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"String::replace"})," - this function can accept optional callback and if ",(0,a.jsx)(n.code,{children:"lambda"})," is async\nyou will end up with ",(0,a.jsx)(n.code,{children:"[object Promise]"})," in output string. Any macro or function can return\na promise in LIPS, and if any of the expression inside a function return a Promise, the whole\nfunction return a Promise and become async. Here is example code that demonstrate the problem:"]}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e "foo bar" (replace "foo" (lambda () (Promise.resolve "xxx"))))\n"[object Promise] bar"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Instead of ",(0,a.jsx)(n.code,{children:"Array::replace"})," you should use LIPS Scheme ",(0,a.jsx)(n.code,{children:"replace"})," procedure that works with async ",(0,a.jsx)(n.code,{children:"lambda"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(replace #/[a-z]+/g (lambda ()\n (Promise.resolve "lips"))\n "foo bar")\n;; ==> "lips lips"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"regular-expressions",children:"Regular Expressions"}),"\n",(0,a.jsxs)(n.p,{children:["LIPS define regular expressions it uses native JavaScript regular expressions.\nAt first, the syntax looked like in JavaScript. It was problematic for the parser\nso you were not able to put space after ",(0,a.jsx)(n.code,{children:"/"})," to distinguish from divide procedure.\nLater, the syntax was renamed into form that start with hash ",(0,a.jsx)(n.code,{children:"#/[0-9]/"}),". The same\nsyntax is used by ",(0,a.jsx)(n.a,{href:"https://practical-scheme.net/gauche/man/gauche-refe/Regular-expressions.html",children:"Gauche"})," implementation. But LIPS supports more flags (same as JavaScript)."]}),"\n",(0,a.jsx)(n.h3,{id:"vectors",children:"Vectors"}),"\n",(0,a.jsxs)(n.p,{children:["In LIPS Scheme vectors are JavaScript arrays. So you can execute methods on them with ",(0,a.jsx)(n.code,{children:"--\x3e"})," macro:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(--\x3e #("one" "two" "three") (join ":"))\n;; ==> "one:two:three"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"object-literals",children:"Object literals"}),"\n",(0,a.jsxs)(n.p,{children:["In LIPS you can define object literals with ",(0,a.jsx)(n.code,{children:"&"}),"\n",(0,a.jsx)(n.a,{href:"/docs/lips/extension#syntax-extensions",children:"syntax extension"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define obj &(:name "Jack" :age 22))\n(write obj)\n;; ==> &(:name "Jack" :age 22)\n(console.log obj)\n;; ==> { name: \'Jack\', age: 22 }\n'})}),"\n",(0,a.jsx)(n.p,{children:"You can nest object literals and mix them with different object:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define obj &(:name "Jack" :hobbies #("swimming" "programming")))\n(write obj.hobbies)\n;; ==> #("swimming" "programming")\n(console.log obj)\n;; ==> { name: \'Jack\', hobbies: [ \'swiming\', \'programming\' ] }\n'})}),"\n",(0,a.jsx)(n.p,{children:"Object similar to Scheme vectors, are immutable, and everything inside is quoted automatically:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define obj &(:name Jack))\n(write obj)\n;; ==> &(:name "Jack")\n'})}),"\n",(0,a.jsx)(n.p,{children:"But to make it possible to share objects with JavaScript, native LIPS values are automatically unboxed.\nSo instead of symbol representation you get a JavaScript string."}),"\n",(0,a.jsx)(n.p,{children:"You can also use quasiquote with object literals:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define jack (let ((name "Jack")\n (age 22))\n `&(:name ,name :age ,age)))\n(write jack)\n;; ==> &(:name "Jack" :age 22)\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"NOTE"}),": because of the construction of ",(0,a.jsx)(n.a,{href:"/docs/lips/extension#syntax-extensions",children:"syntax extensions"})," and\n",(0,a.jsx)(n.a,{href:"/docs/scheme-intro/data-types#quasiquote",children:"quasiquote"}),", you can't splice a list inside object literals:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((args (list \':foo "lorem" \':bar "ipsum")))\n `&(,@args))\n;; ==> pair (unquote-splicing args) is not a symbol!\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The reason why this work like this is because, syntax extensions (",(0,a.jsx)(n.code,{children:"&"}),") runs at parse time and LIPS macros are runtime.\nThis may change in the future when ",(0,a.jsx)(n.a,{href:"https://github.com/jcubic/lips/issues/169",children:"expansion time will be implemented"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Objects also have longhand form with ",(0,a.jsx)(n.code,{children:"object"})," macro:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((obj (object :name \'Jack)))\n (write obj))\n;; ==> &(:name "Jack")\n'})}),"\n",(0,a.jsx)(n.p,{children:"But note that object macro is async (return a Promise) so it may be problematic when used it\nwith native JavaScript code."}),"\n",(0,a.jsxs)(n.p,{children:["Using long form ",(0,a.jsx)(n.code,{children:"(object)"})," syntax you can use splicing with help of ",(0,a.jsx)(n.code,{children:"eval"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(let ((args \'(:foo "lorem" :bar "ipsum")))\n (eval `(object ,@args)))\n;; ==> &(:foo "lorem" :bar "ipsum")\n'})}),"\n",(0,a.jsx)(n.p,{children:"The same you can use macros that will return LIPS Scheme code:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:'(define-macro (create-object . args)\n `(object ,@args))\n\n(create-object :foo "lorem" :bar "ipsum")\n;; ==> &(:foo "lorem" :bar "ipsum")\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"NOTE"}),": this example macro works the same ",(0,a.jsx)(n.code,{children:"object"})," is it's not that useful, but you can create\nmore complex code where you will be able to generate object literals with splicing."]}),"\n",(0,a.jsx)(n.p,{children:"Object literal also have shorthad notation:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(let ((obj &(:x :y)))\n (write obj))\n;; ==> &(:x #void :y #void)\n"})}),"\n",(0,a.jsx)(n.p,{children:"It creates two writtable slots, the rest of the props are read only:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-scheme",children:"(let ((obj &(:x :y)))\n (set! obj.x 10)\n (set! obj.y 20)\n (write obj))\n;; ==> &(:x 10 :y 20)\n\n(let ((obj &(:x :y)))\n (set! obj.z 20)\n (write obj))\n;; ==> Cannot add property z, object is not extensible\n\n(let ((obj &(:x :y :z 10)))\n (set! obj.z 20)\n (write obj))\n;; ==> Cannot assign to read only property 'z' of object '#