{"id":13800716,"url":"https://github.com/benzap/eden","last_synced_at":"2025-03-15T13:31:00.225Z","repository":{"id":62432535,"uuid":"139753156","full_name":"benzap/eden","owner":"benzap","description":"Embedded and Extensible Scripting Language in Clojure","archived":false,"fork":false,"pushed_at":"2020-02-28T16:58:27.000Z","size":4683,"stargazers_count":139,"open_issues_count":1,"forks_count":2,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-15T03:42:08.229Z","etag":null,"topics":["clojure","clojurescript","eden","lua","programming-language"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benzap.png","metadata":{"files":{"readme":"readme.org","changelog":"changelog.org","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-04T18:05:54.000Z","updated_at":"2025-03-11T05:34:58.000Z","dependencies_parsed_at":"2022-11-01T21:01:07.055Z","dependency_job_id":null,"html_url":"https://github.com/benzap/eden","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzap%2Feden","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzap%2Feden/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzap%2Feden/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzap%2Feden/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benzap","download_url":"https://codeload.github.com/benzap/eden/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243735804,"owners_count":20339532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojurescript","eden","lua","programming-language"],"created_at":"2024-08-04T00:01:15.484Z","updated_at":"2025-03-15T13:30:59.729Z","avatar_url":"https://github.com/benzap.png","language":"Clojure","readme":"#+TITLE: Eden - lua-based scripting language in clojure\n#+AUTHOR: Benjamin Zaporzan\n#+DATE: 2018-07-01\n#+EMAIL: benzaporzan@gmail.com\n#+LANGUAGE: en\n#+OPTIONS: H:2 num:t toc:t \\n:nil ::t |:t ^:t f:t tex:t\n\n[[https://travis-ci.org/benzap/eden][https://travis-ci.org/benzap/eden.svg?branch=master]]\n\n[[https://clojars.org/eden][https://img.shields.io/clojars/v/eden.svg]]\n\n[[./doc/logo.png]]\n\n*eden* is a language akin to traditional scripting languages like lua,\npython or ruby. It is embeddable, extensible, sandboxed, and\nfamiliarly simple.\n\n*eden* is unique, in that it uses only valid EDN data values for data\nrepresentation. This has the added benefit of ridiculously easy\nclojure interoperability.\n\n/eden is still in beta development, so things are going to be broken,\nundocumented, and error messages are close to non-existent./\n\n#+BEGIN_SRC\n  (require '[eden.core :as eden])\n\n  (eden/eval println(\"Hello World!\"))\n  ;; Hello World!\n  ;;\n\n  (eden/eval\n   local x = 2 + 2\n\n   function add2(x)\n     return x + 2\n   end\n\n   println(\"The value of x plus 2 equals\" add2(x)))\n  ;; The value of x plus 2 equals 6\n  ;;\n\n#+END_SRC\n\n\nAlmost all of clojures core libraries work out-of-the-box within eden\n\n\n#+BEGIN_SRC\n\n  (eden/eval println(rest([1 2 3 4]))) ;; (2 3 4)\n\n  (eden/eval println(conj([1 2 3] 4))) ;; [1 2 3 4]\n\n  (eden/eval\n   local x = list(1 2 3 4)\n   for i in x do\n     println(i)\n   end)\n   ;; 1\n   ;; 2\n   ;; 3\n   ;; 4\n\n#+END_SRC\n\n\nEven higher-level clojure functions work in eden\n\n\n#+BEGIN_SRC\n\n  (eden/eval\n   local result = map(inc vector(1 2 3 4))\n   println(result))\n  ;; (2 3 4 5)\n\n  (eden/eval\n   local sum = reduce(function(a b) return a + b end list(1 2 3 4))\n   println(sum))\n  ;; 10\n\n#+END_SRC\n\nFunctions written in *eden* can be used within clojure\n\n#+BEGIN_SRC\n\n  (eden/eval\n   function addfirst2(xs)\n     return first(xs) + second(xs)\n   end)\n\n  (def addfirst2 (eden/get-var 'addfirst2))\n  (println (addfirst2 [1 2 3 4]))\n  ;; 3\n\n#+END_SRC\n\nFunctions written in clojure can be used within *eden*\n \n#+BEGIN_SRC\n\n  (defn hello [name]\n    (str \"Hello \" name \"!\"))\n\n  (eden/set-var! 'hello hello)\n  (eden/eval hello(\"Ben\")) ;; \"Hello Ben!\"\n\n#+END_SRC\n\n*eden* uses dot notation for retrieving and assigning to EDN\ncollections, like vectors and hash maps.\n\n#+BEGIN_SRC\n\n  (eden/eval\n   local person = {}\n   person.first-name = \"John\"\n   person.last-name = \"Doe\"\n   person.age = 12\n   println(person))\n  ;; {:first-name John, :last-name Doe, :age 12}\n\n  ;;\n  ;; similarly, vectors can be accessed using square bracket notation\n  ;;\n\n  (eden/eval\n   local list-of-letters = [\"a\" \"b\" \"c\"]\n   println(list-of-letters[1])) ;; b\n\n#+END_SRC\n\n\nThe getter syntax makes it much easier to manipulate more complex\ncollections.\n\n#+BEGIN_SRC\n\n  (eden/eval\n   local default-person = {}\n   default-person.first-name = \"John\"\n   default-person.last-name = \"Doe\"\n\n   local display = function(p)\n     println(p.first-name \"-\" p.last-name)\n   end\n\n   local person-list = [\n     default-person\n     default-person\n   ]\n\n   person-list[0].first-name = \"Ben\"\n   person-list[0].last-name = \"Z\"\n   person-list[1].first-name = \"Jane\"\n   person-list[1].last-name \"M\"\n\n   println(person-list)\n   display(person-list[0]))\n   ;; [{:first-name Ben, :last-name Z} {:first-name Jane, :last-name Doe}]\n   ;; Ben - Z\n\n#+END_SRC\n\n* Rationale\n\n  *eden* was developed to be a embedded language within a natively\n  compiled clojure application (GraalVM'a native-image). It can be\n  used to expose the application API so that a userbase can create\n  plugins in a sandboxed environment. The applications of *eden*\n  within clojure are very similar to the applications of lua within\n  c/c++.\n\n  *eden* can also be used as a standalone scripting language. A\n  natively compiled commandline tool has been developed, and can be\n  used to manipulate EDN files similar to how you would implement JSON\n  files in javascript. Everything is still in its early stages, so I\n  would not recommend using it in a production setting.\n\n  I also plan on compiling *eden* to clojurescript, although the\n  applications of eden within clojurescript are not of interest to me\n  at the moment.\n\n* Requirements\n  \n  *eden* requires clojure 1.9+\n\n* Installation\n** Native Executable\n   Native Executables can be found on the [[https://github.com/benzap/eden/releases][releases page]]\n   \n   There are currently native executables generated for debian-based\n   linux systems, and for rpm-based systems.\n\n   If you would like to generate your own native executable, please\n   follow the configuration instructions included in the Makefile.\n\n   An example use:\n\n   #+BEGIN_SRC sh\n   $ eden -e \"println(\\\"Hello World!\\\")\"\n   Hello World!\n   $\n   #+END_SRC\n\n   #+BEGIN_SRC\n   ;; hello.eden\n\n   function hello(name)\n     return str(\"Hello \" name \"!\")\n   end\n\n   local name = system.args[0] or \"there\"\n   println(hello(name))\n   #+END_SRC\n\n   #+BEGIN_SRC sh\n   $ eden hello.eden ben\n   Hello ben!\n   #+END_SRC\n\n** Uberjar\n   Alternatively, the uberjar can be found on the [[https://github.com/benzap/eden/releases][releases page]], which\n   can be run as follows with ~java~\n\n   #+BEGIN_SRC sh\n   java -jar eden-\u003cversion\u003e-standalone.jar \u003cfilename\u003e\n   #+END_SRC\n\n** Clojure Installation\n\n   For the latest version, please visit [[https://clojars.org/eden][clojars.org]]\n\n   *Leiningen/Boot*\n  \n  #+BEGIN_SRC clojure\n\n  [eden \"0.9.0\"]\n\n  #+END_SRC\n\n   *Clojure CLI/deps.edn*\n\n  #+BEGIN_SRC clojure\n\n  eden {:mvn/version \"0.9.0\"}\n\n  #+END_SRC\n\n   *Gradle*\n\n  #+BEGIN_SRC groovy\n\n  compile 'eden:eden:0.9.0'\n\n  #+END_SRC\n\n   *Maven*\n\n  #+BEGIN_SRC xml\n\n  \u003cdependency\u003e\n    \u003cgroupId\u003eeden\u003c/groupId\u003e\n    \u003cartifactId\u003eeden\u003c/artifactId\u003e\n    \u003cversion\u003e0.9.0\u003c/version\u003e\n  \u003c/dependency\u003e\n\n  #+END_SRC\n\n** Docker Image Execution\n   If you wish to just try out *eden*, and you have docker installed,\n   give this a shot:\n\n   #+BEGIN_SRC\n   $ docker run --rm -ti benzap/eden:0.8.0-1 -e '\"Hello Eden!\"'\n   #+END_SRC\n\n   Using *eden* with docker has its issues, as you have to mount\n   volumes in order to execute scripts. Here is a small example, which\n   mounts my current working directory under the volume */mount*, so\n   that it can execute an eden script that also resides in my current\n   working directory.\n\n   #+BEGIN_SRC\n   $ docker run --rm -v `pwd`:/mount -ti benzap/eden:0.8.0-1 /mount/my_script.eden\n   #+END_SRC\n* Introduction\n\n  *eden* is an imperative language, so it embraces the idea of mutable\n  values being passed around. However, *eden* re-uses the persistent\n  data collections that make up clojure, which makes eden\n  copy-on-write when performing operations on collections.\n\n  #+BEGIN_SRC\n\n  function people-eq?(p1 p2)\n    if p1 == p2 then\n      println(\"Are Equal!\")\n    else\n      println(\"Not Equal!\")\n    end\n  end\n\n  local person1 = {:first-name 12 :age 12}\n  local person2 = person1\n\n  people-eq?(person1 person2) ;; Are Equal!\n\n  person2.age = 13\n\n  people-eq?(person1 person2) ;; Not Equal!\n\n  #+END_SRC\n\n  In a more traditional language like lua, ~person2~ would hold a\n  reference to the same data structure as ~person1~. However, *eden*\n  uses copy-on-write semantics. They never share a reference. If you\n  want to share a reference between variables, use a clojure atom.\n\n  #+BEGIN_SRC\n\n  local person1 = atom({:first-name \"Ben\" :age 12})\n  local person2 = person1\n                \n  swap!(person2 function(p) p.age = 13 return p end)\n  println(deref(person1)) ;; {:first-name Ben, :age 13}\n\n  #+END_SRC\n\n* Installing the Eden Console for Administrative Tooling\n\n  *eden* can be run from the commandline, which can make it suitable\n  for commandline scripting. It can evaluate expressions\n  with the -e commandline flag, or can evaluate files, which are\n  usually designated with the suffix *.eden.\n\n  The easiest way to try out *eden* is to clone the project and run it\n  within the project directory.\n\n  #+BEGIN_SRC sh\n  $ git clone https://github.com/benzap/eden.git\n  $ cd eden\n  $ lein run ./examples/eden/get_project_version.eden\n  0.8.0\n  #+END_SRC\n\n** Debian Installation\n   Tested in Ubuntu 17.10, 18.10.\n   \n   /May require stdc++ lib dependencies for other distributions./\n   \n   #+BEGIN_SRC\n   wget https://github.com/benzap/eden/releases/download/0.8.0/eden-0.8.0-amd64.deb\n   sudo dpkg -i eden-0.8.0-amd64.deb\n   #+END_SRC\n\n** Redhat Installaion\n   Tested on Fedora 28\n   \n   #+BEGIN_SRC\n   wget https://github.com/benzap/eden/releases/download/0.8.0/eden-0.8.0-1.x86_64.rpm\n   sudo rpm -i eden-0.8.0-1.x86_64.rpm\n   #+END_SRC\n\n** Running the standalone uberjar\n   Grab a pre-generated uberjar from the [[https://github.com/benzap/eden/releases][releases page]], and run it directly:\n\n  #+BEGIN_SRC\n\n  $ java -jar eden-0.8.0-standalone.jar ./examples/eden/basic_http_server.eden\n\n  #+END_SRC\n\n  The best use of *eden* as a standalone tool is to either build your\n  own native executable, or grab one of the pre-compiled ones provided\n  on the [[https://github.com/benzap/eden/releases][releases page]]\n\n** Installing on Windows\n   *experimental*\n\n   Download the *.exe from the [[https://github.com/benzap/eden/releases][releases page]]\n\n   /Note: Has issues with the current working directory, *.jar recommended/\n\n* Programming in Eden\n  This is a short manual explaining the Eden programming language.\n** Values and Types\n   Eden is a /dynamically typed/ language based on data types provided\n   in the [[https://github.com/edn-format/edn][EDN data format]]. The types include:\n\n   * Integers / BigIntegers :: ~0~, ~13~, ~-13~, ~14N~\n   * Floats / Doubles :: ~3.14~, ~10e+3~\n   * Strings :: ~\"Hello\"~\n   * Keywords :: ~:foo~, ~:bar~\n   * Booleans :: ~true~, ~false~\n   * Symbols (vars) :: ~x~, ~y~\n   * Lists :: ~list(1 2 3)~, ~list(4 5 6)~\n   * Vectors :: ~[1 2 3]~, ~vector(1 2 3)~\n   * Maps :: ~{:a 123 :b 456}~\n   * Set :: ~#{:a :b :c}~, ~set(:a :b :c)~\n   * Nil :: ~nil~\n\n   I encourage you to review the EDN data format for additional types\n   you might experience when using Eden.\n\n** Variables\n   Variables in Eden are presented in the form of Symbols. The extent\n   of allowed variable names consists of what is allowed in the EDN\n   format, but also restricts you from using keywords used by the Eden\n   language, and symbols beginning with a dot (ex. ~.name ~.foo),\n   since this is used to access collection properties.\n\n   #+BEGIN_SRC\n   ;; Allowed\n\n   x y foo bar is-value? set-value! $hallo\n\n   ;; Not Allowed\n\n   for in .foo .bar end\n   #+END_SRC\n\n** Statements\n*** Assignment\n    Assignment in Eden is similar to languages like lua, or\n    python. The most basic form of assignment is assigning a value to\n    a global variable:\n\n    #+BEGIN_SRC\n    \u003cidentifier\u003e = \u003cvalue\u003e\n\n    x = 12\n    foo = :bar\n    chk? = false\n    #+END_SRC\n\n    Global variables live for the duration of the program, and can be\n    accessed from anywhere in the program.\n\n    The second form of assignment is assigning to a local variable:\n\n    #+BEGIN_SRC\n    local \u003cidentifier\u003e = \u003cvalue\u003e\n    \n    local x = 12\n    local foo = :bar\n    local chk? = false\n    #+END_SRC\n\n*** Conditional Structure\n    The first and most often used control structure is the ~if~\n    control structure:\n\n    #+BEGIN_SRC\n    ;; if structure\n    if \u003ccondition\u003e then\n      \u003ctruthy body statements...\u003e\n    end\n\n    ;; if-else structure\n    if \u003ccondition\u003e then\n      \u003ctruthy body statements...\u003e\n    else\n      \u003cfalsy body statements...\u003e\n    end\n\n    ;; if-elseif-else structure\n    if \u003ccondition\u003e then\n      \u003cbody...\u003e\n\n    elseif \u003ccondition\u003e then\n      \u003cbody...\u003e\n\n    [elseif \u003ccondition\u003e then\n      \u003cbody...\u003e]...\n\n    else\n      \u003cbody...\u003e\n    end\n    #+END_SRC\n\n    Examples\n\n    #+BEGIN_SRC\n    local age = 12\n    if age \u003c 21 then\n      println(\"You are underage\")\n    end\n\n    chk? = true\n    if chk? then\n      println(\"Value is true\")\n    else\n      println(\"Value is false\")\n    end\n    #+END_SRC\n\n*** While Statement\n    While statements check its condition, and upon determining that\n    it's true, will run the block of statements contained in its\n    body. Each time, it will check the condition and call the statment\n    block forever until the condition becomes false.\n\n    #+BEGIN_SRC\n    while \u003ccondition\u003e do\n      \u003cbody...\u003e\n    end\n    #+END_SRC\n\n    Examples\n\n    #+BEGIN_SRC\n\n    ;; keep looping until `i` is greater than or equal to 10\n    local i = 0\n    while i \u003c 10 do\n      println(\"i: \" i)\n      i = i - 1\n    end    \n\n    ;; this will loop forever\n    while true do\n      println(\"Never gonna give you up\")\n    end\n\n    #+END_SRC\n\n*** Repeat-Until Statement\n    Repeat statements are similar to the while statement, with the\n    differences being that the body is guaranteed to always be called\n    at least once, and the body will be looped over only if the\n    condition is false.\n    #+BEGIN_SRC\n    repeat\n      \u003cbody...\u003e\n    until \u003ccondition\u003e\n    #+END_SRC\n\n    Examples\n\n    #+BEGIN_SRC\n    \n\n    ;; keep looping until 'i' is greater than or equal to 10\n    local i = 1\n    repeat\n      println(\"i: \" i)\n      i = i + 1\n    until i \u003e= 10\n\n    ;; this will loop forever\n    repeat\n      println(\"Never gonna let you down\")\n    until false\n\n    #+END_SRC\n\n*** For Statement\n    The first ~for~ statement representation closely resembles the for\n    statement seen in C-based programming languages:\n\n    #+BEGIN_SRC\n    for \u003citer-var\u003e = \u003cstart\u003e \u003cend\u003e [step] do\n      \u003cbody...\u003e\n    end\n    #+END_SRC\n\n    Examples\n\n    #+BEGIN_SRC\n\n    ;; loop from 0 to 10\n    for i = 0 10 do\n      println(\"i: \" i)\n    end\n\n    ;; loop from first index to the length of the vector\n    local x = [1 2 3]\n    for i = 0 count(x) do\n      println(i \"-\" x[i])\n    end\n\n    ;; provide a step\n    for i = 0 10 2 do\n      println(\"i: \" i)\n    end\n    #+END_SRC\n\n    The second type of ~for~ statement is called the ~for-each~\n    statement. This is the more popular, and more often used loop\n    conditional.\n\n    #+BEGIN_SRC\n    for \u003citer-var\u003e in \u003ccollection\u003e do\n      \u003cbody...\u003e\n    end\n    #+END_SRC\n\n    Examples\n\n    #+BEGIN_SRC\n\n    ;; Print out each element of xs\n    local xs = [1 2 3]\n    for x in xs do\n      println(\"Element: \" x)\n    end\n\n    #+END_SRC\n** Expressions\n*** Arithmetic Operators\n    - Addition :: ~+~\n    - Subtraction :: ~-~\n    - Multiplication :: ~*~\n    - Division :: ~/~\n\n    #+BEGIN_SRC\n\n    println(2 + 2)\n    println(2 + 2 - 2)\n    println(2 * 2 - 5)\n    println((2 + 2) * 4)\n    println((2 / 2) * 5)\n\n    #+END_SRC\n\n*** Coercions \u0026 Conversions\n    Arithmetic performed between integer values will remain as\n    integers. It is only if you include a float within an arithmetic\n    operation that it is automatically converted into a float value.\n\n    Almost all types can be converted into a string using the ~str~\n    function.\n\n    #+BEGIN_SRC\n    println(2 + 2) ;; 4 (integer)\n    println(2 + 2.) ;; 4. (float)\n    #+END_SRC\n\n*** Relational Operators\n    - Equality :: ~==~\n    - Inequality :: ~!=~\n    - Less Than :: ~\u003c~\n    - Greater Than :: ~\u003e~\n    - Less Or Equal Than :: ~\u003c=~\n    - Greater Or Equal Than :: ~\u003e=~\n\n    #+BEGIN_SRC\n    println(2 == 2) ;; true\n    println(2 != 1) ;; true\n    \n    local age = 12\n\n    println(age \u003c 18) ;; true\n    println(age \u003e 18) ;; false\n    #+END_SRC\n\n*** Logical Operators\n    - And Operator :: ~and~\n    - Or Operator :: ~or~\n\n    #+BEGIN_SRC\n    10 or 20 ;; 10\n    nil or \"a\" ;; \"a\"\n    nil and 10 ;; nil\n    nil or 10 ;; 10\n    10 and 20 ;; 20\n    #+END_SRC\n*** Length and Concatenation\n    Unlike Lua, eden does not make use of special operators for length\n    or concatenation. Instead, length can be obtained by using the\n    function ~count~, and concatentation can be performed by using\n    ~concat~.\n\n    #+BEGIN_SRC\n    count([1 2 3]) ;; 3\n    count(\"test\") ;; 4\n\n    concat([1 2 3] [4 5 6]) ;; (1 2 3 4 5 6)\n    #+END_SRC\n*** Precedence\n    Precendence is in this order (similar to lua):\n    + ~or~, ~and~\n    + ~\u003c~, ~\u003e~, ~\u003c=~, ~\u003e=~, ~!=~, ~==~\n    + ~+~, ~-~\n    + ~*~, ~/~\n    + unary operators (~-~, ~not~)\n\n    #+BEGIN_SRC\n    println(2 + 2 * 4) ;; 10\n    #+END_SRC\n*** Collection Construction\n    Constructing each of the main collections is straightforward\n**** Vector\n     - ~[1 2 3]~\n     - ~vector(1 2 3)~\n     - ~apply(vector list(1 2 3))~\n     - to convert a collection to a vector, use ~vec~\n**** Map\n     - ~{:a 123 :b (2 + 2)}~\n     - to convert a collection to a map, use ~into~\n       #+BEGIN_SRC\n       into({} [[:a 123] [:b \"test\"]])\n       #+END_SRC\n**** Set\n     - ~#{:a :b :c}~\n     - to convert a collection to a set, use ~set~\n**** List\n     - ~list(1 2 3)~\n     - ~apply(list [1 2 3])~\n     - to convert a collection to a list, use ~into~\n       #+BEGIN_SRC\n       into(list() vector(1 2 3 4))\n       #+END_SRC\n*** Function Calls\n    Function calls are similar to lua:\n    #+BEGIN_SRC\n    \u003cidentifier\u003e([arguments...])\n    #+END_SRC\n\n    Examples\n    #+BEGIN_SRC\n    x(\"test\") ;; call the function in variable 'x' with the argument \"test\"\n    #+END_SRC\n\n*** Function Definitions\n    Function creation can either be done standalone, or an anonymous\n    function be assigned to a variable:\n\n    #+BEGIN_SRC\n    function add(x y)\n      return x + y\n    end\n\n    add = function(x y)\n      return x + y    \n    end\n    #+END_SRC\n\n    In both cases, they can be assigned to a local variable\n\n    #+BEGIN_SRC\n    local function add(x y)\n      return x + y\n    end\n\n    local add = function(x y)\n      return x + y\n    end\n    #+END_SRC\n** Module System\n\n   *eden* has a simple module system. eden will look for files in\n   order of increasing precedence:\n   \n   - If on linux, in /usr/share/eden/libs\n   - If on linux, it will look in each of the colon separated paths in\n     the Environment Variable ~EDEN_MODULE_PATH~\n   - if on windows, it will look in each of the /semi-colon separated/\n     paths in the Environment Variable ~EDEN_MODULE_PATH~\n   - In your home folder, located at ~/.eden/libs (%HOME%/.eden/libs on windows)\n   - The current working directory\n\n\n   As an example, assuming I have a file named test.eden in the current\n   working directory:\n\n   #+BEGIN_SRC\n   ;; test.eden\n\n   local print-hello = function(name)\n     println(str(\"Hello \" name \"!\"))\n   end\n\n   export {:hello print-hello}\n\n   #+END_SRC\n\n   importing the module is simple:\n\n   #+BEGIN_SRC\n   ;; another_file.eden\n\n   test = require \"test\"\n\n   test.hello(\"Ben\")\n\n   #+END_SRC\n\n   #+BEGIN_SRC sh\n   $ eden another_file.eden\n   Hello Ben!\n   $ \n   #+END_SRC\n\n** Standard Libraries\n   Most of the standard libraries are handpicked community libraries\n   that i've used in my other projects. The core libraries closely\n   resemble the libraries seen in clojure\n*** Core Library\n    Most of the clojure core library has been implemented in Eden as a\n    core library. The complete list of clojure.core can be found\n    [[http://clojuredocs.org/clojure.core][here]]. Any dynamic variables, or macros have not been included from\n    the core library.\n*** ~system~ Library\n    - ~system.env(s)~ :: Get the Environment Variable by the name ~s~\n    - ~system.exit(n)~ :: Return from program with Exit Code ~n~\n    - ~system.get-globals()~ :: Return all of the Eden program's global\n         variables. Note that the keys are represented as symbols.\n    - ~system.set-global(name value)~ :: Set global variable\n         programmatically.\n*** ~string~ Library\n    The Eden string library is a direct mirror of the [[https://funcool.github.io/cuerdas/latest/][cuerdas]] string\n    library. Please refer to the provided page for the list of\n    functions, which can be accessed via the ~string~ variable.\n\n    Examples\n    #+BEGIN_SRC\n    string.caseless=(\"Hello There!\" \"HELLO There!\") ;; true\n    string.human(:great-for-csv-headers) ;; \"great for csv headers\"\n    #+END_SRC\n*** ~filesystem~ Library\n    The Eden filesystem library is a direct mirror of the [[https://github.com/Raynes/fs/][Raynes.fs]]\n    filesystem library. The library api can be found [[https://raynes.github.io/fs/][here]].\n*** ~io~ Library\n    The Eden io library is a copy of the [[http://clojuredocs.org/clojure.java.io][clojure.java.io]] library.\n*** ~$~, Specter Library\n    For data transformations, the popular [[https://github.com/nathanmarz/specter][specter]] library has been\n    included in the variable ~$~\n\n    Examples\n    #+BEGIN_SRC\n    $.setval([:a $.END] [4 5] {:a [1 2 3]}) ;; {:a [1 2 3 4 5]}\n\n    $.transform([$.filterer(odd?) $.LAST] inc range(1 9)) ;; (1 2 3 4 5 6 8 8)\n\n    $.transform($.ALL inc #{1 2 3}) ;; #{2 3 4}\n    #+END_SRC\n*** Parsing Libraries\n**** ~html~ Library\n     - ~html.parse(s)~ :: Parses HTML string using [[https://github.com/davidsantiago/hickory][hickory]] (generates\n                        hiccup style collection)\n     - ~html.stringify(coll)~ :: Creates HTML string from collection\n          using [[https://github.com/weavejester/hiccup][hiccup]]\n\n     Also has css generator provided by [[https://github.com/noprompt/garden][garden]]\n     + ~html.css.gen-css(coll)~ :: provided by garden.core/css\n     + ~html.css.gen-style(coll)~ :: provided by garden.core/style\n     + ~html.css.color~ :: several color functions from garden.color\n     + ~html.css.units~ :: several unit functions from garden.units\n**** ~json~ Library\n     JSON library provided by [[https://github.com/dakrone/cheshire][cheshire]]\n     - ~json.parse(s [opts])~ :: provided by cheshire.core/parse-string\n     - ~json.stringify(coll [opts])~ :: provided by cheshire.core/generate-string\n**** ~edn~ Library\n     EDN library parser provided by [[https://github.com/clojure/tools.reader][tools.reader]]\n     - ~edn.parse(s [opts])~ :: provided by clojure.tools.reader.edn/read-string\n     - ~edn.stringify(coll [opts])~ :: clojure.core/pr-str\n**** ~markdown~ Library\n     Markdown library stringifier provided by [[https://github.com/yogthos/markdown-clj][markdown-clj]]\n     - ~markdown.stringify(s) :: provided by markdown-clj.core/md-to-html-string\n**** ~transit~ Library\n     Transit Reader and Generator provided by [[https://github.com/cognitect/transit-clj][transit-clj]]\n\n     - transit.parse(s)\n     - transit.write(x)\n*** ~http~ Library\n    HTTP Server provided by [[http://www.http-kit.org/][http-kit]]\n    HTTP Client provided by [[https://github.com/martinklepsch/clj-http-lite/][clj-http-lite]]\n    HTTP Router provided by [[https://github.com/juxt/bidi][bidi]]\n        \n\n    - ~http.router.make-handler(coll)~ :: provided by bidi.ring/make-handler\n    - ~http.server.run-server(handler [opts])~ :: provided by org.httpkit.server/run-server\n    - ~http.client.get(url [opts])~ :: provided by clj-http.lite.client/get\n\n    Example found at ./examples/eden/http_server.eden\n    \n*** ~shell~ Library\n    Shell library provided by [[https://github.com/Raynes/conch][conch]], unfortunately it doesn't work due\n    to reflection issues that will be resolved in future native\n    executables\n\n*** ~operator~ Library\n    Includes all of the clojure equivalent operators. Useful for\n    additional performance in certain applications\n    * ~operator.add(x ...)~ :: clojure.core/+\n    * ~operator.sub(x ...)~ :: clojure.core/-\n    * ~operator.mult(x ...)~ :: clojure.core/*\n    * ~operator.div(x ...)~ :: clojure.core//\n    * ~operator.not(x)~ :: clojure.core/not\n    * ~operator.and(x y)~ :: clojure.core/and, 2-arity wrapped macro\n    * ~operator.or(x y)~ :: clojure.core/or, 2-arity wrapped macro\n* Dark-corners of Eden\n\n  Since *eden* uses EDN data values directly, it does mean some funky\n  things can happen unexpectedly.\n\n** Vectors get confused as indexes\n   \n   #+BEGIN_SRC\n\n   map(inc [1 2 3])\n\n   #+END_SRC\n   \n   This says /get the index [1 2 3] of inc/. The equivalent in clojure\n   would be ~(get-in inc [1 2 3])~, which is not what we want. The\n   solution is to use the ~vector~ function.\n   \n   #+BEGIN_SRC\n   \n   map(inc vector(1 2 3))\n\n   #+END_SRC\n\n   Note that indexing is only in effect after identifiers and function\n   calls\n\n   #+BEGIN_SRC\n   x[1] ;; indexing\n   list([1 2 3] x) ;; not indexing\n   list([1 2 3] x [2]) ;; x[2] is an index!\n   #+END_SRC\n\n** The EDN parser gets confused with complex map hashes\n\n   #+BEGIN_SRC\n\n   local x = {\n     :x 2 + 2\n     :y 3 - 2\n   }\n\n   #+END_SRC\n\n   The parser will fail, since the resulting map within eden appears\n   as ~{:x 2, '+ 2, :y 3, '- 2}~. The solution is to group each\n   expression in round brackets:\n\n   #+BEGIN_SRC\n\n   local x = {\n     :x (2 + 2)\n     :y (3 - 2)\n   }\n\n   ;; similarly for functions\n   local y = {\n     :hello (function(name) return str(\"Hello \" name \"!\") end)\n   }\n\n   #+END_SRC\n\n* Differences between Lua and Eden\n** Array Indexing\n   eden uses zero-indexing for array types, whereas lua uses\n   one-indexing for array types.\n   \n   #+BEGIN_SRC lua\n    -- Lua\n    x = {\"A\", \"B\", \"C\"}\n    print(x[1]) -- A\n   #+END_SRC\n\n   #+BEGIN_SRC clojure\n    ;; eden\n    x = [\"A\" \"B\" \"C\"]\n    println(x[1]) ;; B\n   #+END_SRC\n** Equality Symbols\n   Lua uses ~= to represent inequality, whereas Eden uses ~!=~\n\n   #+BEGIN_SRC lua\n   -- Lua\n   print(true ~= false) -- true\n   #+END_SRC\n\n   #+BEGIN_SRC\n   ;; eden\n   println(true != false) ;; true\n   #+END_SRC\n\n** Module Systems\n   *eden* adopts a module system with the special keyword ~export~ for\n   exporting, whereas Lua reuses ~return~ to represent the module\n   export.\n\n   #+BEGIN_SRC lua\n     -- Lua\n     local x = {}\n     x.test = function()\n       print(\"test!\")\n     end\n\n     return x\n   #+END_SRC\n\n   #+BEGIN_SRC clojure\n     ;; eden\n     local x = {}\n     x.test = function()\n       println(\"test!\")\n     end\n\n     export x\n   #+END_SRC\n\n* Development\n** Uberjar\n   To generate a standalone uberjar file, run ~lein uberjar~\n   \n   The generated jar file will be located in ./target/eden-\u003cversion\u003e-standalone.jar\n\n** Native Executable Distribution\n   Please read the Makefile for instructions on how to native compile\n   *eden* using GraalVM.\n*** Debian DPKG (Tested on Ubuntu 17.10)\n    ~make dpkg~\n*** Redhat RPM (Tested on Fedora 28)\n    ~make rpm~\n*** Tar Archive (Tested on Ubuntu 17.10)\n    ~make tar~\n** Testing\n   Tests can be run with ~lein test~\n* Features for Version 1.0.0 Stable Release\n\n  - +Test Coverage for the entire standard language+\n  - +Better parser errors (might require a parser rewrite)+\n  - +support 'elseif clause in if conditionals+ (added in 0.4.0-SNAPSHOT)\n  - +Additional standard libraries.+ (Several libraries have been\n    added since 0.5.0-SNAPSHOT)\n  - +clojure.string (or use funcool.cuerdas, can it native compile?)+\n    (added in 0.3.0-SNAPSHOT)\n  - +json parse and stringify libs (one that native compiles)+ (added in 0.3.0-SNAPSHOT)\n* Future Unreachable(?) Goals\n  - eden repl\n  - clojurescript build with passing tests\n  - metafunctions\n  - lua table implementation\n  - natively compiled database interface (sqlite, psql)\n","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenzap%2Feden","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenzap%2Feden","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenzap%2Feden/lists"}