Giter Site home page Giter Site logo

gkz / livescript Goto Github PK

View Code? Open in Web Editor NEW
2.3K 109.0 156.0 19.89 MB

LiveScript is a language which compiles to JavaScript. It has a straightforward mapping to JavaScript and allows you to write expressive code devoid of repetitive boilerplate. While LiveScript adds many features to assist in functional style programming, it also has many improvements for object oriented and imperative programming.

Home Page: http://livescript.net

License: MIT License

Makefile 0.33% JavaScript 1.81% LiveScript 97.25% HTML 0.61%

livescript's Introduction

LiveScript

is a language which compiles to JavaScript. It has a straightforward mapping to JavaScript and allows you to write expressive code devoid of repetitive boilerplate. While LiveScript adds many features to assist in functional style programming, it also has many improvements for object oriented and imperative programming.

Check out livescript.net for more information, examples, usage, and a language reference.

Build Status

Build Status

Install

Have Node.js installed. sudo npm install -g livescript

After, run lsc -h for more information.

Source

git://github.com/gkz/LiveScript.git

Community

If you'd like to chat, drop by #livescript on Freenode IRC. If you don't have IRC client you can use Freenode webchat.

livescript's People

Contributors

apaleslimghost avatar appedemic avatar blvz avatar brodyberg avatar cehoffman avatar chrislloyd avatar diggsey avatar dk00 avatar drnic avatar gkovacs avatar gkz avatar goatslacker avatar jashkenas avatar josher19 avatar kkirby avatar matehat avatar michaelficarra avatar misterfish avatar olsonjeffery avatar pepkin88 avatar raine avatar rhendric avatar satyr avatar srijs avatar sstephenson avatar stanangeloff avatar summivox avatar tim-smart avatar vendethiel avatar zaach 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  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

livescript's Issues

Live Compiler

You should consider having a Live Compiler like the one on coffeescript.org
so people can test code and see what Javascript is compiled.

Here's a bare bones, minimal LiveScript compiler:
https://gist.github.com/2426844

PS: It looks like SCRIPT tags with type="text/LiveScript" are getting evaluated twice:
once by Javascript and once by LiveScript.

I'm guessing this is because Javascript was originally called Livescript.
You might need to use "text/x-LiveScript" instead.

->> Josh W <<-

Partial application operator

What about adding an operator to partially apply a function to some arguments? I know a curried function can be used instead in most cases, but it does't help with functions defined outside your own code, or with functions that takes splat arguments or have optional arguments. Also, I don't want to have to define functions that I rarely partially apply as curried, because it has a performance hit when I do provide all the arguments.

I also think it could be useful to have two version of it - one that uses a lexical this (fn [SOME-OPERATOR] a, b would be equal to fn.bind(this,a,b)) and one that uses a dynamically bound this. It could be nice if a syntax that uses - and ~ can be found, so it would be similar to function definition with lexical/dynamic this.

Complete build tool?

I have always missed a complete build system from CoffeeScript.

I find their "cake" very limited compared to https://github.com/mde/jake/ where you can have different base tasks and some compound tasks where you basically just tell which base tasks to run first and it will take care of dependencies etc.

Could this be added to LiveScript for making it like make and other flexible build tools?

watch mode

Supervisor doesn't work with LiveScript.

Would it be a good idea to introduce watch mode when running a script, so when something in that folder (recursive check) changes, the script will be restarted.

livescript app.ls -w

mutability of looping index in comprehensions

The looping index is currently mutable. We fixed this in CoffeeScript 5 months ago, and you should probably do the same. Here's a failing test case:

a = for v, k in [0 1 2 3 4 5 6]
  ++k
  ++v
arrayEq [1 to 7], a

which currently compiles into

var k, v, a, __res, __ref, __len;
__res = [];
for (k = 0, __len = (__ref = [0, 1, 2, 3, 4, 5, 6]).length; k < __len; ++k) {
  v = __ref[k];
  ++k;
  __res.push(++v);
}
a = __res;
arrayEq([1, 2, 3, 4, 5, 6, 7], a);

Here's the synonymous CoffeeScript's compilation:

$ coffee -bsp
a = for v, k in [0, 1, 2, 3, 4, 5, 6]
  ++k
  ++v
var a, k, v;

a = (function() {
  var _i, _len, _ref, _results;
  _ref = [0, 1, 2, 3, 4, 5, 6];
  _results = [];
  for (k = _i = 0, _len = _ref.length; _i < _len; k = ++_i) {
    v = _ref[k];
    ++k;
    _results.push(++v);
  }
  return _results;
})();

Related CoffeeScript issues: jashkenas/coffeescript#1959, jashkenas/coffeescript#1910

prototype ::=

lala = (mmm) ->
  console.log mmm

lala ::= {
  lala: 1
}

produces:

var lala, prototype;
lala = function(mmm){
  return console.log(mmm);
};
lala(prototype = {
  lala: 1
});

workaround: without the space, it produces the correct code :)
(used the livescript gh-page to make the demo, it's useful :))

monads

roy language has nice syntax for monads.

In the site of roy there sare example of ajax and deferred monads:

let deferred = {
  return: \x -> $.when x
  bind: \x f ->
    let dfd = $.Deferred ()
    x.done (\val ->
      (f val).done dfd.resolve
    )
    dfd.promise ()
}

let v = do deferred
  val <- $.ajax 'examples/helloworld.roy'
  val2 <- $.ajax 'examples/alias.roy'
  return val ++ val2

v.done (\x ->
  console.log x
)

use prelude.ls functions if it is included

I haven't messed around with the LiveScript build system, in fact I don't know if it has one, but I assume it does given the existence of cake and coke (lake?).

But I think it would be useful to have a "target" compilation option that specifies commonjs, browser, etc. And then an option to include prelude.ls which would determine how to include it based on the target (defaulting to simply inlining it, which would hopefully be optimized out when the files are merged and optimized, which should be done for all browser scripts).

I noticed that some auto-generated functions like __curry are duplicated in prelude.ls, so knowing that prelude.ls is included would allow the compile to avoid duplicating them.

?= not working in REPL

The ?= operator only works on the first line when running in interactive mode.
After that, gives a ReferenceError.

% bin/livescript -i
livescript> x ?= 1
1
livescript> y ?= 1
ReferenceError: y is not defined

Probably related to LiveScript.savedScope

`_` placeholder

What do you think about using it as a placeholder var in languages like Scala? Not sure it's very usable in current way. Or maybe i'm looking the wrong place.

[1 2 3].map(_ * 2).filter(_ > 5).reduce(_ + _)
[1, 2, 3]
  .map(function($0) {return $0 * 2;})
  .filter(function($0) {return $0 > 5;})
  .reduce(function($0, $1) {return $0 + $1;})

Make pipe code more readable

[1 2 3 4 5]
  |> map (* 2)
  |> filter (> 5)
  |> map (+ 1)
  |> filter (> 2)

is compiled to

filter(__lt(2))(map(__add(1))(filter(__lt(5))(map(__multiply(2))([1, 2, 3, 4, 5]))));

Pretty hard to read. Any idea how this can be improved?

My idea is to fold pipeline with compose:

fold1(compose, [
  map(__multiply(2)),
  filter(__lt(5)),
  map(__add(1)),
  filter(__lt(2))
])([1, 2, 3, 4, 5])

Benchmark shows it has almost the same performance.

Make intro to LiveScript for CoffeeScript and JavaScript programmers

Consider making a brief "Introduction to LiveScript for CoffeeScript programmers" and a
"Introduction to LiveScript for Javascript and NodeJS programmers" which highlights differences with code samples, and what > they would need to do to port their code to LiveScript, and some of the "gotchas": code which compiles but not in the way expected.

Examples:

[x..y]
(x) => y
 x === y vs. x == y

etc.

perhaps =~ or ~~~ instead of === for fuzzy equality to avoid
'False Friends'

Original by @josher19 in #5

Pattern Matching

Theoretical syntax:

sort-even-odd = ([x, xs]) ->                                                                                                                                              
  | xs.length is 0 => [x] 
  | otherwise => if odd(x) then sort-even-odd(xs) ++ [x] else x & sort-even-odd(xs)

Inspired by Haskell.

This little algorithm will sort even and odd numbers in a list. The [x, xs] in the parameters splits up the list where x is head(list) and xs is tail(list)

The Guards are already mad cool, it would be great if the language could be extended to deconstruct parameters according to a pattern.

Implicit objects and arrays as first function argument

Why isn't it allowed to do:

someone
  name: "foo"
  age: 20
, callback

someone
  "foo"
  20
, callback

One of the selling point with LiveScript is that it removes the need for a closing character.

The only exception is:

someone {
  name: "foo"
  age: 20
}, callback

someone [
  "foo"
  20
], callback

This makes the code more verbose than the CoffeeScript version (the array syntax stays the same).

Can't we just remove the "pyramid effect" in all eternity just like Jade, Haml and Stylus have done but for HTML and CSS.

Piping returns the first expression result

This line here returns 12

[1, 2, 3, 4, 5] |> filter even |> map (* 2) |> fold (+), 0

However this one

x = [1, 2, 3, 4, 5] |> filter even |> map (* 2) |> fold (+), 0
x

returns [1, 2, 3, 4, 5].

How do I capture 12 instead of the first expression?

Livescript Discussion Board

There are certain types of discussions that Livescript needs that aren't fit for its issue board. This is one of them, but it needs to be posted somewhere.

Livescript needs some place where users can discuss best practices, get help, or share cool hacks with livescript. I can set up a subreddit if anyone is interested.

I feel like this would also help get the word out about livescript.

""" in the doc

I think you forgot to mention """ heredoc in the documentation.

Is the documentation a git repo so we could help out?

Operator precedence

I think our operator precedence hierarchy has gotten a bit complicated. Currently it is:

operators =
  # Listed from lower precedence.
  <[ left     PIPE POST_IF FOR WHILE ]>
  <[ right    BACKPIPE     ]>
  <[ right    , ASSIGN HURL EXTENDS INDENT SWITCH CASE TO BY LABEL ]>
  <[ right    CONCAT       ]>
  <[ right    LOGIC        ]>
  <[ left     BITWISE      ]>
  <[ right    COMPARE      ]>
  <[ left     RELATION     ]>
  <[ left     SHIFT IMPORT ]>
  <[ left     +-           ]>
  <[ left     MATH         ]>
  <[ right    UNARY        ]>
  <[ right    POWER ^      ]>
  <[ right    COMPOSE      ]>
  <[ nonassoc CREMENT      ]>
  <[ left     BACKTICK     ]>

any ideas about simplifying it?

Also taking ideas on changing the order. @michaelficarra I know you were thinking about this in coffee-of-my-dreams - I looked at the discussion there - LiveScript actually currently has something like Haskell's $ operator - the backpipe, taken from F#. eg. print <| 5 + 5 - the op could perhaps be changed? & could become available if we changed cons to something else.

Immutability of vars by default

OMG THIS IS AWESOME
๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘
i've looked for shit like this for a long time, thank you @gkz! No strict functional purity & functional orientation FTW.

BTW, any plans of making vars, maybe, immutable by default, so they can't be redefined a-la Scala? This can be a static check, not runtime.

a = 1

# will fail compilation
a = 2

There could also be an alternative syntax for mutable vars.

Also, what js engines LiveScript targets? I mean, is mammoth's shit like IE6 included?

about Semiautovivification and f# cloning record implementation

Hi!!...first I wanna comment about the weird syntax for "Semiautovivification" (it's the first time than I heard that word :D)

x.@@'hello world'[email protected] 

I'm not sure cause the example wasn't totally clear for me...but is the same syntax for th coffeescript code

zip = lottery.drawWinner?().address?.zipcode  ??

I feel it a bit complicate and weird compares with the coffeescript...the livescript syntax here offer any benefit?

the second point is abot cloning record..would be nice has cloning record in livescript

personA = {name : "matias" , age : 20  , job : "a cool job", ..........}
{personA with name='jhon'}   //syntax example...copy personA changing the name

UpperCaseName => (person) ->
    {person with name=person.name.toUpperCase()}

I don't know..but for me...this looks cool :D.....
maybe you know other cool way..please share your opinion.....

Backslash string syntax

Why the backslash is used? : is used in Ruby, Clojure and many langs (also it's symbol there). Compare:

<- $ \h1 .on \click
alert \boom!
console.log key: \value
save sync: yes, login: \paulmillr, type: \organization, admin: no
<- $ :h1 .on :click
alert :boom!
console.log key: :value
save sync: yes, login: :paulmillr, type: :organization, admin: no

Idea: add support for dashes in variable names, mangle them

Why dashes?

  1. More readable than underscores.
  2. JS has its own variable naming style (camelCase), which obviously sucks in readability.
  3. Vars with dashes are invalid in js, so if we'll compile it with mangling, it won't violate js naming style.

Cons:

  1. It would add more complexity
  2. - will be prohibited from using as OP without indenation like a - b (which is good IMO).

Examples

add-user = (name, age) -> ...
remove-users-with-age = (age) ->
  remove-user user for user in users when user.age is age
add-users = (users) ->
  add-user user for user in users
class Thread-post
addUser ...
removeUsersWithAge ...
addUsers ...
ThreadPost ...

Examples

Clojure. Pretty readable.

reposted from jashkenas/coffeescript#2345

Feature: object comprehensions

We should have {k:v for ...} to complement [v for ...]. Would be sugar for let out = {} then [out <<< k:v for ...]; return out. Would the proposed syntax cause too much ambiguity with object literals?

Ace support

Could Ace support be added (by someone who knows how to)?

That would give syntax highlighting for every editor that is using Ace including Cloud9ide and Github.

Would boost up popularity.

Idea: Type Inference

Have you thought about adding some sort of optional type system along with type inference?

Roy has types.

This can also be something similar to contracts.coffee, except the type checking happens at compile time instead of runtime so you don't get the performance hit.

Bitwise operator syntax

bitwise operators are too long to be able to tell what kind of shift you're doing or whether or not you have the right number of symbols. I propose Haskell's syntax:

1 .&. 3 # => 1 & 3
0xff8800 .>>. 8 # => 0xff8800 >> 8

I feel like this is a more reasonable syntax.

!?

What does !? do?

I don't think you have explained what it does in the doc.

order of operation 'is'

if req.url.indexOf '/lala.lala/' is 0
  console.log "lala"

produces:

if (req.url.indexOf('/lala.lala/' === 0)) {
  console.log("lala");
}

workaround: explicitly add ( )

Bundle prelude by default

How about bundling prelude by default with livescript? There would be no need in type

global <<< require 'prelude-ls'

I think would be a bug with pattern matching feature

Hi...I like a lot this project but I was testing it and I feel the pattern matching has a weird behavior...

my code

take([x, ...xs]:list) =
  | empty list => []
  | otherwise  => x & take xs

take [1 2 3 4 5]   #good it return 1,2,3,4,5, has expected

now

take([x, ...xs]:list) =
  | empty list => []
  | otherwise  => [x] & take xs

this return 1,2,3,4,5 again
I could expect [1],[2],....

running

take([x,y, ...xs]:list) =
  | empty list => []
  | otherwise  => [x,y] & take xs

take [1 2 3 4 5 6] 

i would expect [[1,2],[3,4],[5,6]] = [1,2]&[3,4]&[5 6]&[] but it return 1,2,3,4,5,6

I'm not sure if I'm doing a mistake, but I think it could be a problem in the implementation...give a look and please let me know what do u think

* weird behavior

This code works as expected

someone do
  * name: "foo"
    20
  callback

It gives you

someone([
  {
    name: "foo"
  }, 20
], callback);

This code gives two

However, this code

someone do
  * name: "foo"
  * name: "bar"
  callback

gives you:

someone({
  name: "foo"
}, {
  name: "bar"
}, callback);

Shouldn't it compile into an array with 2 objects?

Improve CLI

The CLI

livescript> answer = 42
42
livescript> answer
ReferenceError: answer is not defined

Must do:

livescript> @answer = 42

but this is not required in a .ls file or the browser version.
Also difficult to cut & paste code into the CLI because of need for ^J at the end of the line.

If you start a line with '[' in the CLI, coffee throws a long error message.
livescript and coco throw a nicer error message: SyntaxError: missing ] on line 1.
node indents and prompts you for more array input.

I prefer node's solution. It would be great if that would also work for function definitions as well, so:

f(a,b) = 
  a + b
#
g = (a,b) ->
  a + b

would work without needing ^J (or \ in CoffeeScript).

Of course, this could make the CLI client slightly more complex, but I'd much prefer
to have the CLI automatically indent my next line for me and wait for more input
when I enter

livescript> g = (a,b) ->

instead of the no-op function:

[Function]
function (a, b){}

which is what I'd expect from g = (a,b) -> followed by two newlines.

Original by @josher19 in #5

Bound functions in class declarations bind to constructor?

Hi,

In a Livescript class definition, a function with a wavy arrow binds differently than in Coffeescript:

class Class
  -> \my-constructor
  x : 100
  method : -> console.log this, @x
  static : ~> console.log this, @x

c = new Class
c.method!                  #=> Class, 100 (desired result)
setTimeout c.method, 1000  #=> Window, undefined (correct failure)
setTimeout c.static, 2000  #=> function Class () { "my-constructor"; }, undefined (incorrect failure)

In CS, binding a function in the class declaration binds it's context to the class prototype, where it could find @x, which is how I've been using it. But in LS, it binds the context to the constructor function, whose prototype is Function and can't find @x.

This is incorrect, right? Seems like a weird thing to change deliberately, unless this is something inherited from Coco that I'm not familiar with. Please close if I'm just ignorant.

Thanks

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.