gkz / LiveScript

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.
http://livescript.net
MIT License
2.32k stars 156 forks source link

removing features #219

Open gkz opened 11 years ago

gkz commented 11 years ago

So far (on master), slated for removal (and currently with compiler notices upon use):


discussion:

More controversial:

vendethiel commented 11 years ago

I like \ more for power op. Maybe remove either . or << ? Not sure about import/importAll, but with implements, it became less useful

Discussion : simplify switch

michaelficarra commented 11 years ago

** has been accepted as the exponentiation operator in CoffeeScript (see jashkenas/coffee-script#2026), definitely go with that. Already implemented in CoffeeScriptRedux at michaelficarra/CoffeeScriptRedux@6bc355d027326d5d1e42650d9178dae8eb5554cf.

michaelficarra commented 11 years ago

Also, regarding yes/no/on/off, I actually use yes and no all over the place in my CoffeeScript code. It's probably a 9:1 ratio of yes/no to true/false. They just make more grammatical sense when they're used as the answer to a question.

DavidSouther commented 11 years ago

I rarely use import/importAll, much preferring <<< and <<<<

apaleslimghost commented 11 years ago

import and import all are much more readable and obvious, especially as functions, i.e. map (import a:5).

cocodrino commented 11 years ago

yes quarterto..I think the same..import is much more obvious, the livescript syntax is great but it has too much symbols (a good haskell son :D) I'm much more ocaml syntax fan and I think the symbols only are goods when they're used so much or use a keyword could be so long...

I really like ++ for concat over +++ ...

gkz commented 11 years ago

Also thinking of removing inexistance !? as it conflicts with call with no args + existence. Eg. f()? is different that f!?

vendethiel commented 11 years ago

+1. It's a mess and not readable at all.

gkz commented 11 years ago

Also:

gkz commented 11 years ago

More controversial:

vendethiel commented 11 years ago

I quite like @ when in a call blah(@)... but I see your point. I don't for ::

DavidSouther commented 11 years ago

Standalone use of @:

I regularly use @ standalone at the end of a function to return this;

Hanging :::

I regularly use Type:: <<< to quickly assign several properties to a prototype.


David Souther http://davidsouther.com

On Sun, Dec 30, 2012 at 2:52 PM, George Zahariev notifications@github.comwrote:

More controversial:

  • remove standalone use of @
  • remove standalone or hanging use of ::

    — Reply to this email directly or view it on GitHubhttps://github.com/gkz/LiveScript/issues/219#issuecomment-11768087.

apaleslimghost commented 11 years ago

@DavidSouther we have ::= as sugar for .prototype import.

DavidSouther commented 11 years ago

You learn something new every day! @quarterto Thanks!

craigyk commented 11 years ago

my 2¢: remove it as automatic assignment to single argument function calls.

Is it just me? When I first saw LiveScript I thought, 'cool, look at all these features', but my second thought was: 'they can't hope to keep more than half of these in the long run'. The problem is I don't know which half. Was that the idea?, to throw everything and see what shakes out?

vendethiel commented 11 years ago

A lot is coming from @satyr/coco, and it's been since around two years I think (maybe more ?). These are features thought before by satyr. LiveScript came, added back some coffee compatibility, and of course functional sugar.

vendethiel commented 11 years ago

Remove with BLOCK, I can't see where you can't do that with do/cascade. The cloneport could maybe be changed to use another keyword ... We have with/when/where, maybe we could avoid having 3 different keywords (when they don't have a so different meaning)

satyr commented 11 years ago

I can't see where you can't do that with do/cascade.

Cascade sometimes is inconvenient as a prog1 due to the requirement of at least one ref in its body (as of satyr/coco#179).

vendethiel commented 11 years ago

why just not use do then ?

a do
  do
    some instructions
    d

Also, LS removed withstatement as argument as per #53 (we have <| do as a replacement)

satyr commented 11 years ago

That's a progn, not prog1.

vendethiel commented 11 years ago

That's a progn, not prog1.

(we have <| do as a replacement)

but I suppose it is inconvenient

texastoland commented 11 years ago

remove import and import all?

import/import all is very nice for static mixins (maybe there's a better way?) cf.:

class A extends B implements C
  import all B, C
class A extends B implements C
  @ <<<< B
  @ <<<< C

9:1 ratio of yes/no to true/false

:+1: from ObjC but I see their redundancy.

@ standalone at the end of a function to return this;

:+1:

Remove with BLOCK

:+1: :+1:

ming-codes commented 11 years ago

I think the where statement can make better styling when used appropriately.

promise.then resolve, resolve where resolve = (fate) ->

# vs.

resolve = (fate) ->
promise.then resolve, resolve
result.join('&')
  where result = for key, value of data
    switch
    | typeof value in <[ number boolean string ]> => "#{key}=#{value}"
    | value.length => (for item in value => "#{key}=#{item}").join('&')
    | otherwise => ''

# vs.

result = for key, value of data
  switch
  | typeof value in <[ number boolean string ]> => "#{key}=#{value}"
  | value.length => (for item in value => "#{key}=#{item}").join('&')
  | otherwise => ''
result.join('&')
jorgebg commented 11 years ago

I regularly use @ standalone at the end of a function to return this; import and import all are much more readable and obvious, especially as functions, i.e. map (import a:5). 9:1 ratio of yes/no to true/false

:+1:

And please :smile: let me remind #297:

[...] allowing the use of implements outside class definitions in order to be able to declare functions and variables with the implements id

PkmX commented 11 years ago

+1 @lightblade. I also would like to keep where in Livescript, it really helps readability when skimming over code because it moves the important parts of body to the top of function definition. This is like reading an article: the first line should give you a rough idea what a function does and the implementation is followed in case you need to get into the detail.

PkmX commented 11 years ago

Also favoring the removal of on and off for gkz/prelude-ls#55. Personally I haven't found them to be very useful in increasing readability, YMMV. Maybe we can move them to prelude-ls as const on = true and const off = false.

robotlolita commented 11 years ago

I share @PkmX and @lightblade POVs on where, so I'm :+1: -ing it here.

karamfil commented 11 years ago

I regularly use @ standalone at the end of a function to return this;

I am doing this a lot - allows chaining.

Also using it together with jQuery is quite nice: $(@)

vendethiel commented 11 years ago

this standalone allows chaining too

DavidSouther commented 11 years ago

Well, sure, but it's the aesthetic of the bare @ that draws me to it. Three less characters, and it looks like a little hook hanging there at the end of the method, just begging the next coder to hook in to it.


David Souther http://davidsouther.com

On Thu, Jul 25, 2013 at 1:30 PM, Nami-Doc notifications@github.com wrote:

this standalone allows chaining too

— Reply to this email directly or view it on GitHubhttps://github.com/gkz/LiveScript/issues/219#issuecomment-21570515 .

utkarshkukreti commented 11 years ago

Another +1 for bringing back where, as mentioned by @PkmX, @lightblade, and @killdream.

gkz commented 10 years ago

I'm thinking of removing both case and default in the next version. Also removing else to mean default, and when to mean case (leaving it for comprehensions only), this would greatly simplify our switch statement syntax.

vendethiel commented 9 years ago

remove unjoined strings

igl commented 9 years ago

I never use @ and if decorators ever become a thing in JS we have a clash. I did not have the pleasure of coding LS in a team but in coffeescribble and I found not just one bug caused by heavy usage of ?. That disqualifies the whole thing as a safe-guard to me.

I generally prefer not using symbols if i don't have to... Not all symbols in LS have such quirky and placement specific behavior but i still prefer not to be clever just for saving a few characters.

kay-is commented 9 years ago

I use @ a lot. You're right with the readability and decorators aspect (even if I don't think LS has to mirror every feature of JS). But it's a very simple substitute and for me it feels fast to skim over code and see all the @attributes that are used even without special highlighting.

dead-claudia commented 9 years ago

@igl There's no need for decorators in LiveScript outside of changing property descriptors. You can use plain functions for nearly every use case. (I've used this in my own pet projects before)

inc = (f) -> ->
  @index += 1
  f.apply @, &

class Foo
  -> @index = 2
  foo: inc -> console.log "#{@index}"

wrap = (f) -> -> new List f.apply @, &

class List
  (@value) ->
  map: wrap (f) -> [f i for i in @value]
  filter: wrap (f) -> [i for i in @value | f i]
  each: (f) -> [f i for i in @value]; @
dead-claudia commented 9 years ago

And things that I wouldn't mind if they were removed:

I do enjoy the @ alias for this. It's very convenient.

heavyk commented 9 years ago

great list ...

I've never tried is not and always used isnt however, now that I think about it, I could see why that would be logical. without thinking about it, I'd write if x is !y

I will admit I've used * 'str' a lot, so it'd be the only one I miss, but not that much.

so yeah, I'm totally +1 for all that.

dead-claudia commented 9 years ago

@heavyk I've used that quite a bit, too, but it tends to throw me a little at first glance, which isn't nice when you're reading code. That's why I put it on there.

vendethiel commented 9 years ago
  • 'str', / 'str'

Use String::join, String::split, Prelude.ls's join function, or its split function. Easier to know at a glance.

Literal overloading in general. It'd make sense to have such feature with a type system (and overloadable operators...), but for us right now...

dead-claudia commented 9 years ago

@vendethiel +1

heavyk commented 9 years ago

@impinball yea I agree. I had a phase where I wrote a bunch of console apps, and I used that operator all the time. I look at that code now, it's like 'wat??'

homam commented 9 years ago

I only disagree with

. alias of the << composition operator (consistency)

heavyk commented 9 years ago

I never used that, what does it do?

raine commented 9 years ago

Function composition from right to left.

ls> (+ 1) . (* 2) <| 1
3

By the way I find this discussion valuable. LS has a bit too many features.

p.s. let's get rid of match first (or document it)

heavyk commented 9 years ago

oh, I didn't know you could do that!

I just looked at your profile, then at the ramda-cli you're working on, and it gave me a good idea. why do we pass options objects around at all? why not pass around option thunks?

every part of anything we write could be composed. I'll give an example...

resizeImage({ width: 1024, height: 768, rotate: 0, normalize: ... etc. // these are options }

so I pass in my options object with values, but if I were to instead pass thunks, I could get two objects that can always change, but depend on each oher. one obj would have the thunks to call of the other object, and vice versa.. objects would turn out the properties of other objects. it looks in my head like water. I need a better way to express this. I will work on this more...

totally had no idea about those function compositions. whole new world just opened... omg

dead-claudia commented 9 years ago

@homam To be fair, I have used it before. I have run into a gotcha with it, though: partially applying it. I have found a few times where I had to use (<<) because ( . ) always represents property access. You can still do (foo .) though.

@heavyk

Here's a use case for function composition: making a lazy chain:

a = -> [.. for &]
chain-sync = a >> reduce (>>)

read-rc = chain-sync do
  ('.'+)
  (fs.read-file-sync _, 'utf8')
  JSON.parse

I've also used a similar trick in a Gulpfile:

require! { /* ... */ }
a = -> [.. for &]
pipe = a >> reduce (a, b) -> a.pipe b

gulp.task \build ->
  pipe do
    * gulp.src 'src/**/*.ls'
    * sourcemaps.init!
    * livescript!
    * soucemaps.write!
    * gulp.dest 'dest'

Doing the same with promises is easy

a = -> [.. for &]
pipe = a >> reduce (a, b) -> a.then b

my-package-setting = pipe do
  * fs.get-file-async 'package.json', 'utf8'
  * JSON.parse
  * (.'my-custom-setting')
dead-claudia commented 9 years ago

@raine I use match quite a bit. I ended up making an equivalent targeting ES7 virtual methods (expect it to be slow), just to simplify the rest of my program significantly (mostly written in ES6/7):

export const method = f => function (...args) {
  return f(this, ...args);
};

const each = (xs, f) => {
  for (let i = 0; i < xs.length; i++) {
    f(xs[i], i);
  }
};

export const then = method((x, f) => f(x));

export const match = method((value, pairs) =>
        each(pairs, (p, i) => assertCallable(p[0], `test[${i}]`))::then(() => {
    let def = Array.isArray(pairs[pairs.length - 1]) ? pairs.pop() : undef;
    assertCallable(def, 'def');

    for (let [g, run] of pairs) {
        if (typeof g === 'function' ? g(value) : value === g) return run(value);
    }

    return def(value);
});

value::match([
  // I found the common case to be a function call with `value`, so I designed
  // it with that in mind
  [test, value => doSomething(value)],
  [otherTest, doSomethingElse],
  value => def(value), // optional
]);

The last part in LS would be this:

match value
  | test => doSomething value
  | otherTest => doSomethingElse value
  | otherwise => def value

I enjoy match

igl commented 9 years ago

@impinball I enjoy matcha lot too (#584 is the only issue i have with it)

I am very curious about how these changes are going to land. Will there be a 1.5 with breakage? Will features like es6 class and module support be pushed off further to LS2? Can there be a LS2 pre-release with a lot of breakage so big changes can happen before locking the keywords? Is forking CoffeeScriptRedux still on the roadmap?

dead-claudia commented 9 years ago

That LS2 branch/roadmap is years outdated. LiveScript uses its own lexer and parser now.

As for an actual roadmap, I don't think there's much to add right now. But FWIW I do feel that removing all these features should constitute a new major version (I know this project doesn't follow Semver). Even gradually, this would cause a lot of code breakage, including in the compiler itself.

On Tue, Jun 16, 2015, 06:45 Richard notifications@github.com wrote:

@impinball https://github.com/impinball I enjoy matcha lot too (#584 https://github.com/gkz/LiveScript/issues/584 is the only issue i have with it)

I am very curious about how these changes are going to land. Will there be a 1.5 with breakage? Will features like es6 class and module support be pushed off further to LS2? Can there be a LS2 pre-release with a lot of breakage so big changes can happen before locking the keywords? Is forking CoffeeScriptRedux still on the roadmap?

— Reply to this email directly or view it on GitHub https://github.com/gkz/LiveScript/issues/219#issuecomment-112383210.