Code Monkey home page Code Monkey logo

wonderscript-alpha's Introduction

WonderScript

A simple lisp for web development

Synopsis

user> (+ 3 4)
=> 7
user> (defn square (x) (* x x))
=> #js/function "function(x) { return (x*x); }"
user> (square 5)
=> 25
user> (reduce + (range 10))
=> 45

Language

Special Forms

  • def
  • quote
  • cond
  • fn* (a direct mapping of JS function semantics)
  • set* (a direct mapping of JS assignment semantics)
  • js*
  • loop
  • recur - repeat?
  • throw
  • try, catch, finally (not implemented)
  • do (a block with it's own environment), begin (an immediately executed block with no environment)
    • rescue, ensure, else
  • new
  • .

Operators

(treated specially by the compiler)

Consider making is possible to define within WS, they would function as low-level code generating macros that can also (optionally) be used as functions.

  • mod 1
  • <, >, >=, <= 1
  • not
  • or, and
  • bit-not, bit-or, bit-xor, bit-and, bit-right-shift, bit-left-shift, unsigned-bit-right-shift
  • identical? == (identity, i.e. object equality) 1
  • equiv? (JS type coercive equality)
  • instance? 1
  • typeof 1
  • +, -, *, / 1
  • array-get, array-set!, array-length
  • slot, slot-set!, slot?, length

Equality

  • = value equality
  • == object identity
  • =~ pattern match overloaded by different classes by implementing match(value)

Types of Types

  • Type Aliases deftype
  • Union (->or Number String), (->and Number String)
  • Class defclass
    • Multiple inheritance (Look at PicoLisp, Dylan, CLOS), or no inheritance either way encourage composition via protocols, method / function composition.
  • Protocol defprotocol
  • Record defrecord

Meta Object Protocol

  • Invokable
  • Function
  • Method
  • Class
  • Protocol
  • Record
  • GenericFunction
  • Definition
  • Context
  • Module
  • Object

Functions

(fn (x) (+ 1 x)), #(+ 1 %)

Generic Functions

Methods

Can be dispatched on any type and arbitrary Generic Functions

Modules

The broadest context for state. With the macro forms defconst and defvar module level constants and dynamically scoped variables can be defined. By convention constants are spelled $contstant, and variables are spelled *variable*. Constants and variable can be accessed globally when scoped with the module name i.e. $Module::constant or *Module::variable*. By convention modules names are camel cased. All other definitions with in a module must be explicitly exported and imported to be used. Keywords that are prefixed with a :: like ::keyword are automatically expanded into :Module::keyword. Modules can be nested inner modules can be accessed with the same notation as other definitions i.e. OuterModule::InnerModule. Definitions specified with def and relatives, defn, defmacro, defclass, deftype, defprotocol, defrecord are namespaced by their module and private unless exported. Definitions can be exported with the module form, and imports can be specified with the use form. use with or without imports makes the modules and all shared definitions accessible (scoped by the module name).

(module Dragnet
  (export View TemplateView PageView Button Link))
  
(use Web
  (import html css js))

Exports and shared symbols can also be specified with meta data on the symbol:

(module Web)

(defn ^:export html
   (form) ...)

(module Dragnet)

(defclass View ...)

Definition Meta Data

  • :private (only seen in module defaults to true)
  • :export (definition can be exported)
  • :macro (definition is a macro)
  • :doc (doc string of the definition)
  • :typedef (boolean, definition is a type alias)
  • :tag (Symbol type tag of the def)
  • :sig (the type signature of a function)

Data Structures

Protocols

  • Null
  • Numeric
  • Boolean
  • Meta
  • Reference
  • Associative - Associate one value with another, lookup values in constant time
  • Indexed < Associative - numerically associative
  • Named
  • Sequence
  • Sequencible

Classes

  • Value
  • Object : Reference
  • Nil < Value : Null
  • Unset? < Value : Null (state of an unset key in an Associative data structure)
  • Undefined? < Value : Null (state of an undefined symbol)
  • NaN < Value : Null (state of an undefined numerical operation)
  • True < Value
  • False < Value
  • Symbol < Value : Named, Meta
  • Keyword < Value : Named
  • Pair < Value : Sequence
  • List < Value : Sequence, Meta
  • LazyList < Value : Sequence
  • Range < Value : Sequence
  • Map < Value : Associative
  • Dictionary < Object : Associative
  • Set < Value : Associative
  • MutableSet < Object : Associative
  • String < Value : Indexed
  • Buffer < Object : Indexed
  • Vector < Value : Indexed
  • Array < Object : Indexed
  • Function < Value

Protocols

A collection of properties/shapes and doc strings

  • Meta
    • meta()
    • set-meta(key, value)
    • get-meta(key)
  • Value
    • hash-code()
  • Named?
    • name()
    • namespace()
  • Collection
    • add(col, value)
  • Seq < Collection
    • first()
    • next()
  • Sequenceable < Collection
    • seq()
  • Associative < Sequenceable
    • get(key, alt = nil)
    • remove(key)
  • Indexed < Associative
    • at(index)
  • ImmutableStack
    • pop()
    • peek()
    • push()
  • MutableStack
    • pop()
    • push()
  • Queue
  • Matchable =~
    • match(pattern)
  • Equality =
    • equal(other)
  • Comparable <=>
    • cmp(other)
  • js/ArrayLike
    • length:number

Core Library

  • = (value equality)
  • =~ (matching)
  • fn (lambda macro with arity checks and arity polymorphism)
  • defn
  • defmacro
  • deftype
  • defclass
  • defprotocol
  • defconst
  • defvar
  • set!
  • raise, (builds on throw, requires a class if no class is provided defaults to RuntimeError)
  • if, if-not, when, unless
  • +, -, *, /, mod
  • <, >, >=, <=, <=>
  • inc, dec
  • identity, constantly, always
  • comment
  • even?, odd?
  • zero?, pos?, neg?
  • true?, false?
  • reduce, map, filter, grep, mapcat, concat, reduce-right,
  • first, next, rest, second, cons, drop, take, empty?
  • each, tap
  • dotimes, doeach, for, while, until
  • nth, at
  • range
  • partition
  • pr p, pr-str inspect, print
  • str
  • number?, string?, boolean?, function?
  • set?, map?, iterator?, get
  • array-like?, array?, ->array, array, slice, push!, pop!, shift!, unshift!
  • object?, undefined?, null?, nil?
  • memoize, compose, apply
  • set-meta, meta, get-meta, reset-meta
  • atom, reset!, swap!, deref, compare-and-swap! (TODO)
  • freeze!, frozen?, clone, immutable?, mutable?
  • deftest, is

defclass

(defprotocol Invokable
  "The interface for all invokable objects"
  (invoke (*args)))
  
(defprotocol Type
  (satisfies (object)))

(defclass MethodSig
  (has      Symbol name)
  (has-many Symbol arglist)
  (has?     String doc))
  
(defclass Protocol :does Type
  (has-many? Protocol  ^:key protocols)
  (has-many  MethodSig ^:key signatures)
  (has?      String    ^:key doc))
  
(defclass Method :does Invokable
  (has      Symbol name)
  (has?     String doc)
  (has-many Symbol arglist)
  (has-many Form   body))
  
(defclass Property
  (has Symbol  name)
  (has Boolean required :default true))
  
(defclass Class :does Type
  (has?      String   doc)
  (has-many? Protocol protocols)
  (has-many  Property properties)
  (has-many  Method   methods))

Based on https://opendylan.org/documentation/intro-dylan/objects.html

(defclass Vehicle
  (has serial-owner)
  (has owner))
  
(defclass Vehicle
  (has  Integer serial-number :key :sn)
  (has? String  owner
    :key :owner ;; true would work just as well here
    :default "Northern Motors"))

TODO

  • Add test suite
  • Remove Namespaces (use JS modules instead)
  • Add syntax objects & syntax quoting
  • Improve error reporting and stack traces
  • Add generic functions
  • Add protocols (implement protocols for existing objects/methods)
  • Implement browser-based IDE
  • Add abstractions for browser APIs
  • Add a database interface
    • Datalog based by default
    • Abstract over SQL and KV stores
    • DBI-like interface for SQL stores
  • Implement ST or CL-like images called a "world" (a reified notion of static and dynamic state)
    • Create new compilers based on "world" objects
    • Create encoders for world objects so they can be persisted and transmitted
  • Update JS
    • Make use of let and const
    • Make use of class
    • Refactor into modules
    • TypeScript

Author

Delon Newman [email protected]

Footnotes

  1. Paired with a function equivalent. 2 3 4 5 6

wonderscript-alpha's People

Contributors

delonnewman avatar

Stargazers

 avatar

Watchers

 avatar  avatar

wonderscript-alpha's Issues

"form" reference in else clause fails

(defn html (form)
  (cond (nil? form) ""
        (true? form) "Yes"
        (false? form) "No"
        (string? form) form
        (tag? form)
          (if (has-attr? form)
            (render-attr-tag form)
            (render-tag form))
        (component? form) (render-component form)
        (tag-list? form) (render-tag-list form)
        :else
          (throw (js/Error. (str "Unknown form: " form)))))

js* doesn't work

(defn js-arrays-equal
  (a b)
  (cond
    (not (and (array? a) (array? b))) false
    (not (identical? (alength a) (alength b))) false
    else
      (do
        (dotimes (i (alength a))
          (js* (quote "if (!wonderscriopt.core._EQ_(a[i],b[i])) return false;")))
        (js* (quote "return true;")))))
(defn js-arrays-equal
  (a b)
  (cond
    (not (and (array? a) (array? b))) false
    (not (identical? (alength a) (alength b))) false
    else
      (do
        (dotimes (i (alength a))
          (js* "if (!wonderscriopt.core._EQ_(a[i],b[i])) return false;"))
        (js* "return true;"))))

Both fail

Splat args give false arity

(arity (fn (x y z))) ; => 3
(arity (fn (x))) ; => 1
(arity (fn (&args))) ; => 1 - should be -1 or zero or something more instructive

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.