Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

removing features #219

Open
gkz opened this issue Dec 2, 2012 · 54 comments
Open

removing features #219

gkz opened this issue Dec 2, 2012 · 54 comments

Comments

@gkz
Copy link
Owner

gkz commented Dec 2, 2012

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

  • short function syntax - f(x) = x - [currently has notice]
    why: hacky implementation, duplicating functionaly
    use --> to make curried functions
  • +++ concat op [currently has notice]
    why: added ++ as concat op, which is shorter and better
  • where statement - relatively useless - just use local var assignment or a let statement [currently has notice]
  • undefined alias for void - added for CoffeeScript compatibility, but with coffee2ls that is not an issue [currently has notice]
  • !? inexistence op [currently has notice]

discussion:

  • choose one of ** or ^ for power op?
  • remove import and importAll?
  • remove x is not y to mean x isnt y, have it mean x is !y instead
  • yes/no/on/off aliases - added for CoffeeScript compatibility, but now with coffee2ls, this is not an issue

More controversial:

  • remove standalone use of @
  • remove standalone or hanging use of ::
@vendethiel
Copy link
Contributor

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
Copy link
Contributor

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

@michaelficarra
Copy link
Contributor

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
Copy link

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

@apaleslimghost
Copy link
Contributor

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

@cocodrino
Copy link

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
Copy link
Owner Author

gkz commented Dec 30, 2012

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

@vendethiel
Copy link
Contributor

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

@gkz
Copy link
Owner Author

gkz commented Dec 30, 2012

Also:

  • remove undefined as alias to void
  • remove x is not y to mean x isnt y, have it mean x is !y instead

@gkz
Copy link
Owner Author

gkz commented Dec 30, 2012

More controversial:

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

@vendethiel
Copy link
Contributor

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

@DavidSouther
Copy link

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
[email protected]:

More controversial:

  • remove standalone use of @

  • remove standalone or hanging use of ::


    Reply to this email directly or view it on GitHubhttps://github.com/removing features #219#issuecomment-11768087.

gkz added a commit that referenced this issue Dec 30, 2012
gkz added a commit that referenced this issue Dec 30, 2012
gkz added a commit that referenced this issue Dec 31, 2012
@apaleslimghost
Copy link
Contributor

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

@DavidSouther
Copy link

You learn something new every day! @quarterto Thanks!

@craigyk
Copy link

craigyk commented Jan 7, 2013

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

satyr commented Jan 11, 2013

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
Copy link
Contributor

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
Copy link
Contributor

satyr commented Jan 11, 2013

That's a progn, not prog1.

@neersighted neersighted mentioned this issue Jan 16, 2013
11 tasks
@vendethiel
Copy link
Contributor

That's a progn, not prog1.

(we have <| do as a replacement)

but I suppose it is inconvenient

@texastoland
Copy link

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

👍 from ObjC but I see their redundancy.

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

👍

Remove with BLOCK

👍 👍

@ming-codes
Copy link

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
Copy link

jorgebg commented Jul 9, 2013

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

👍

And please 😄 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

@vendethiel
Copy link
Contributor

this standalone allows chaining too

@DavidSouther
Copy link

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 [email protected] wrote:

this standalone allows chaining too


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

@utkarshkukreti
Copy link

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

@gkz
Copy link
Owner Author

gkz commented Nov 15, 2013

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
Copy link
Contributor

remove unjoined strings

@igl
Copy link
Contributor

igl commented May 15, 2015

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
Copy link
Contributor

kay-is commented May 16, 2015

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
Copy link
Contributor

@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
Copy link
Contributor

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

  • case, when, then, else, and default in switch-case/match expressions
    • IMHO, this is where CoffeeScript starts looking not so pretty.
  • yes, no, on, and off CoffeeScript boolean synonyms.
    • I rarely see these outside of CoffeeScript and YAML.
  • x is not y -> change to be equivalent to (x) == (!y) (principle of least surprise)
    • Python's version is exclusively used for references, usually for objects or types.

      type(foo) is not str
      objA is not objB
      x == y
    • CoffeeScript itself compiles x is not y to x === !y.

    • Needless to say, it has tripped me up a few too many times when I used the is operator in LS. It's also one of the main reasons why I always use the ==/!= operators for equality.

  • undefined
    • Exclusively use void.
    • Clearer that it's not just JavaScript's problematic (in sloppy mode) undefined.
  • One of ^ or **
  • . alias of the << composition operator (consistency)
  • * 'str', / 'str'
    • Use String::join, String::split, Prelude.ls's join function, or its split function.
    • Easier to know at a glance.
  • for ever alias of loop
    • Don't need both.
    • Most languages with this construct use loop.

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

@heavyk
Copy link

heavyk commented May 19, 2015

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
Copy link
Contributor

@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
Copy link
Contributor

  • '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
Copy link
Contributor

@vendethiel +1

@heavyk
Copy link

heavyk commented May 21, 2015

@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
Copy link

homam commented May 21, 2015

I only disagree with

. alias of the << composition operator (consistency)

@heavyk
Copy link

heavyk commented May 21, 2015

I never used that, what does it do?

@raine
Copy link
Contributor

raine commented May 21, 2015

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
Copy link

heavyk commented May 21, 2015

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
Copy link
Contributor

@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
Copy link
Contributor

@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
Copy link
Contributor

igl commented Jun 16, 2015

@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
Copy link
Contributor

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 [email protected] wrote:

@IMPinball https://github.com/impinball I enjoy matcha lot too (#584
#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
#219 (comment).

@focused
Copy link

focused commented May 24, 2016

Match is a must have feature

@ozra
Copy link

ozra commented May 25, 2016

+1 on all except stand alone @ (mostly because I have a lot of old code using it).

@dead-claudia
Copy link
Contributor

@ozra I agree WRT the original list (except I also want to keep C:: == C.prototype).

@focused I agree, and I wish match was documented. It does IMHO have odd behavior with certain cases (it's rather ad-hoc in how it matches things), and could stand to be fixed, but it should still stay around.

@chrisvfritz
Copy link

I'm disappointed the single-item array not evaluating to an array "feature" wasn't removed in 1.5 after all. 😕 It's something that actively causes pain through unexpected behavior, rather than just duplicating behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests