Giter VIP home page Giter VIP logo

sibilant's Introduction

CI Gitter

Sibilant

  • Sibilant is a language that is parsed by javascript and compiles to javascript.
  • Sibilant is inspired by lisp and follows many lisp conventions, although it is still relatively close to the underlying javascript.
  • Macros can be defined in sibilant and included at compile time.
  • Sibilant is entirely written in sibilant.

Language Priorities

  • Prefer verbose names to abbreviations by default.
  • Avoid line noise. Prefer established punctuation semantics from natural languages and common programming languages (eg commas come after things and mean a pause or separation).
  • Prefer readable and idiomatic javascript output, which necessitates sticking fairly closely to javascript semantics. Switching cost from sibilant to directly editing the output javascript should be low.
  • Prefer expressions to statements. This is the most notable exception to the adherance to idiomatic javascript. Self-executing functions are used extensively to this end.
  • Allow as much of the language to be modified in-source as possible. This includes the ability to rename/remove/redefine all keywords and macros.
  • Any language constructs that do not output readable javascript should be opt-in.
  • Add language features slowly, and only when there's a real use case. Don't blindly implement Lisp features without reasoning through the need.
  • Provide tools to simplify avoidance of repetition.

Installation

First, install node.js [ github ] and npm [ github ]. Then, it's as simple as:

$ npm install sibilant -g
$ sibilant --help

Hello world in the REPL

$ sibilant
sibilant> (+ 1 2)
(1 + 2)
result: 3
sibilant> (console.log "hello world")
console.log("hello world")
hello world

Try it before you install

sibilant.org includes an in-browser as-you-type sibilant compiler and tutorial, so you can get a sense of the language without leaving your browser.

Learning the language

The most up to date documentation is at sibilant.org and docs.sibilant.org. Also, check out sibilant itself, which is written 100% in sibilant to get a sense of what's possible.

License

Sibilant is released under the MIT license (wikipedia).

sibilant's People

Contributors

ben-x9 avatar gustavoschmidt avatar humasect avatar jbr avatar jonnay avatar matthewp avatar matthewpblog avatar tadeuzagallo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sibilant's Issues

methods with underscores in the beginning are not preserved (e.g module._compile)

(defun compileSib (module filename)
(module._compile (translate filename) {filename filename bare true}) filename)
(set require.extensions '.sibilant compileSib)

compiles to this:

var compileSib = (function(module, filename) {
// module:required filename:required
module.(compile, translate(filename), {
filename: filename,
bare: true
});
return filename;
});

(require.extensions)[".sibilant"] = compileSib;

BTW, would be nice, if one could use the native node.js require-ing.

bad interaction between multi-setf and auto-return

(thunk (setf b c d e))

becomes

(function() {
  if (arguments.length > 0)
    throw new Error("argument count mismatch: expected no arguments");

  return b = c;
  d = e;;
})

but it should be

(function() {
  if (arguments.length > 0)
    throw new Error("argument count mismatch: expected no arguments");

  b = c;
  return d = e;;
})

semicolons should never be doubled

For example, (thunk (setf x 1)) becomes
(function() {
return x = 1;;
})

There should only be one semicolon on the second line of the output js.

Website Down

It wouldn't work for me in Firefox or Chrome today.

use arc-like macro names

Again a matter of taste, but while I'm spamming your bug tracker: what do you think of the macro names used in Arc, instead of the more traditional lisp ones? Specifically I'm thinking of:

defun => def
lambda => fn
progn => do
setf => = (and then = has to become is)

And for the benefit of JS people, I would also suggest

defvar => var

Cli not working

when I type which sibilant it shows me that it is installed, bu running sibilant gives me a node/npm error

node.js:116
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: Cannot find module 'sibilant/lib/cli'
    at Function._resolveFilename (module.js:290:11)
    at Function._load (module.js:242:25)
    at require (module.js:318:19)
    at Object.<anonymous> (/Users/Adrian/sibilant/sibilant/bin/sibilant:3:1)
    at Module._compile (module.js:374:26)
    at Object..js (module.js:380:10)
    at Module.load (module.js:306:31)
    at Function._load (module.js:272:10)
    at require (module.js:318:19)
    at Object.<anonymous> (/Users/Adrian/.nvm/v0.4.1/bin/[email protected]:11:18)

I'm running node v0.4.1 and installed sibilant via npm install sibilant

add colors to the repl

This is obviously of urgent priority.

$ sibilant
sibilant> (function-that-does-not-exist)
<red>ReferenceError: function-that-does-not-exist is not defined...</red>

Maybe color true and false blue, etc. Because colors are awesome.

cli should ignore any args after --

How's this seem for expected behavior?

; myfile.lisp
(console.log (get process "ARGV"))

And then

$ sibilant -x myfile.lisp -- args after here are passed through
[ "sibilant", "myfile.lisp", "args", "after", "here", "are", "passed", "through" ]

fix (include...) order

$ echo "(console.log 'a)" > a.lisp

$ echo "(console.log 'b)" > b.lisp

$ echo "(console.log 'c) (include 'a.lisp) (include 'b.lisp)" > c.lisp

$ sibilant c.lisp #this should be c-a-b, but is a-b-c

console.log("a");
console.log("b");
console.log("c");

$ sibilant -x c.lisp # this should just be a\nb\nc but it's not.

console.log("a");
console.log("b");
c

These are two different issues, I think, but will probably be fixed at the same time.

User-definable syntax

This requires refactoring the lexer.

It would be cool if users could add to the lexer at compile time. Language users could do something like

(defsyntax /\[([^\]]+)\]/ (array-contents)
  (apply list (map (split ",\s*" array-contents) translate)))

at the top of their file and after that they'd be able to do [a, b, c] for arrays. Similar could be done for js hash/object literals. Users could define a group of these and import them, like (import 'js-literals)

simulate namaspace

should be possible simulate namespace like clojure. In this mode we can have local macros in name space

buggy interaction between progn and switch

(if true (progn (switch a (b c))) false)

should be

(function() {
  if (true) {
    return (function() {
      switch(a) {
      case b:
        return c;
      }
    })();;
  } else {
    return false;
  };
})()

but is

(function() {
  if (true) {
    return (function() {
      switch(a) {
      case c:

      }
    })();;
  } else {
    return false;
  };
})()

add -e / --eval

if there's an argument, translate and eval it. otherwise, read stdin.

Emacs major mode

As I mentioned in email to Evan, I'd really like to rename some of the fundamental macros like defun, defvar, lambda, etc. These renames are waiting on the stupidest thing, which is that I need to figure out how to make an emacs major mode. The only reason for the current macro names and .lisp extension are that I don't want to lose my precious syntax highlighting.

compile if to ternary

Is there any reason that (if cond expr1 expr2) can't compile to "cond ? expr1 : expr2"? It would save creating the function for each if statement, which can't do good things to performance.

You may also need to change (progn expr1 expr2) to compile to "expr1, expr2" to make this work. Haven't thought about return statements yet.

if-else macro bug

The if-else macro does not properly handle a final "else" clause. It should check for an odd number of arguments and produce an else clause for that case.

(if-else (= 3 3) 3 (= 4 3) 4 5)

should produce

(function() {
  if ((3 === 3)) {
    return 3;
  } else if ((4 === 3)) {
    return 4;
  } else {
    return 5;
  }
})()

instead of

(function() {
  if ((3 === 3)) {
    return 3;
  } else if ((4 === 3)) {
    return 4;
  } else if (5) {
    return undefined;
  }
})()

update documentation

i have see that is supported also syntax quote

(defmacro sum (a b)
(defvar x 100)
`(+ ~a ~b ~x)

)

(sum 1 2)

make sibilant-mode an independent repo and put it on melpa

Hello,

This would allow for submodules based packaging in emacs without having to pull the whole sibilant source, while not really causing any changes on the "root" project.

Also do you have any plan or ongoing work on porting sibilant to the latest node (and also continue to work on this project)? I am not able to compile or install it on v0.6.7 atm, maybe some indication in the README about the required versions of nodes would help new comers.

Macros and Lists

Why is first element of a list the word "list" when passing a list as an argument to a macro? See example below.

(defmacro macro-test (list-arg)
    (map list-arg (lambda (arg) arg)))

(macro-test [1 2])

Outputs:

list,1,2

problems installing sibilant with npm

node version: 0.6.12
npm version: 1.1.10


$ npm install sibilant -g
npm http GET https://registry.npmjs.org/sibilant
npm http 304 https://registry.npmjs.org/sibilant
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
/usr/local/bin/sibilant -> /usr/local/lib/node_modules/sibilant/bin/sibilant
[email protected] /usr/local/lib/node_modules/sibilant


$ sibilant

/usr/local/lib/node_modules/sibilant/lib/sibilant.js:3
import = require("sibilant/lib/import"),
^^^^^^

node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
SyntaxError:
at Module._compile (module.js:429:25)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at Object. (/usr/local/lib/node_modules/sibilant/lib/cli.js:1:78)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)

List or array?

There is some inconsistencies here. sibilantjs.info calls them lists, but then we have macros like (array?). I propose that we refer to them as lists as it is more lispy that way. We can redefine array? to be list? and use array? as a macro for list? Sound good?

Also, we need a macro for (list-like?) for things like NodeList and arguments. I believe the way they do this in ClojureScript is check for the existence of a .length property and exclude strings.

hash macro is not working in repl (???)

sibilant> (hash a 'b)
result: 'b'

sibilant> (hash a 'b b 'b)
SyntaxError: Unexpected token :
at /usr/local/lib/node_modules/sibilant/lib/repl.js:50:27
at Interface. (/usr/local/lib/node_modules/sibilant/lib/repl.js:71:4)
at Interface.emit (events.js:64:17)
at Interface._onLine (readline.js:153:10)
at Interface._line (readline.js:408:8)
at Interface._ttyWrite (readline.js:585:14)
at ReadStream. (readline.js:73:12)
at ReadStream.emit (events.js:81:20)
at ReadStream._emitKey (tty_posix.js:307:10)
at ReadStream.onData (tty_posix.js:70:12)

Environment:
OSX 10.6.6
npm -v
1.0.18

node -v
v0.4.8

sibilant -v
sibilant version 0.1.1
(at /usr/local/lib/node_modules/sibilant)

request for feedback: require!

Proposed macro:

(defmacro require! (&rest args)
  (apply macros.defvar
     (inject [] args
         (lambda (collector item)
           (collector.concat [item ['require ['quote item]]])))))

With this usage:

(require! sys fs redis)

Outputs this:

var sys = require("sys"),
    fs = require("fs"),
    redis = require("redis");

I'm looking for feedback.

No mention of license

I can't seem to find any mention of what license Sibilant is released under. Briefly going through your other code, it seems that you've been using the MIT license; any chance we can get a LICENSE file dropped in here as well? :-)

argument for improved capitalization options

actual code I've used:

-j-s-o-n.stringify functions

process.-a-r-g-v

(new (node-static.-server "./public" (hash cache false)))

obviously, I'm trying to get to process.ARGV, JSON.stringify, and nodeStatic.Server here.

Node 0.9.x error

/usr/local/lib/node_modules/sibilant/lib/sibilant.js:3
import = require("sibilant/lib/import"),
^^^^^^
SyntaxError: Unexpected reserved word
at Module._compile (module.js:437:25)
at Object.Module._extensions..js (module.js:472:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
at require (module.js:378:17)
at Object. (/usr/local/lib/node_modules/sibilant/lib/cli.js:1:78)
at Module._compile (module.js:454:26)
at Object.Module._extensions..js (module.js:472:10)
at Module.load (module.js:356:32)

defvar within function generates two semicolons

From your REPL demo:

(defun alert-hello (planet-name)
(defvar message (concat "hello " planet-name))
(alert message)
message)

generates:
var alertHello = (function(planetName) {
// planetName:required
var message = ("hello " + planetName);;
alert(message);
return message;
});

Errors in REPL silently ignored

Errors in Sibilant's REPL seem to be silently ignored:

sibilant> (foobar)
sibilant> 

The same thing in Node's REPL:

> foobar()
ReferenceError: foobar is not defined
    at [object Context]:1:1
    at Interface.<anonymous> (repl.js:112:21)
    at Interface.emit (events.js:31:17)
    at Interface._ttyWrite (readline.js:307:12)
    at Interface.write (readline.js:145:30)
    at Stream.<anonymous> (repl.js:83:9)
    at Stream.emit (events.js:31:17)
    at Stream._onReadable (net.js:613:14)
    at IOWatcher.onReadable [as callback] (net.js:156:10)
> 

I tried this against both Node's master branch (v0.3) and the v0.2 branch with the same results.

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.