Open gkz opened 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
**
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.
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.
I rarely use import
/importAll
, much preferring <<<
and <<<<
import
and import all
are much more readable and obvious, especially as functions, i.e. map (import a:5)
.
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 +++ ...
Also thinking of removing inexistance !?
as it conflicts with call with no args + existence. Eg. f()?
is different that f!?
+1. It's a mess and not readable at all.
Also:
undefined
as alias to void
x is not y
to mean x isnt y
, have it mean x is !y
insteadMore controversial:
@
::
I quite like @
when in a call blah(@)...
but I see your point. I don't for ::
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.
@DavidSouther we have ::=
as sugar for .prototype import
.
You learn something new every day! @quarterto Thanks!
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?
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.
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)
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).
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)
That's a progn, not prog1.
(we have <| do as a replacement)
but I suppose it is inconvenient
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 toreturn this;
:+1:
Remove with BLOCK
:+1: :+1:
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('&')
I regularly use
@
standalone at the end of a function toreturn 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 theimplements
id
+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.
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
.
I share @PkmX and @lightblade POVs on where
, so I'm :+1: -ing it here.
I regularly use
@
standalone at the end of a function toreturn this;
I am doing this a lot - allows chaining.
Also using it together with jQuery is quite nice: $(@)
this
standalone allows chaining too
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 .
Another +1 for bringing back where
, as mentioned by @PkmX, @lightblade, and @killdream.
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.
remove unjoined strings
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.
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 @attribute
s that are used even without special highlighting.
@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]; @
And things that I wouldn't mind if they were removed:
case
, when
, then
, else
, and default
in switch-case/match
expressions
yes
, no
, on
, and off
CoffeeScript boolean synonyms.
x is not y
-> change to be equivalent to (x) == (!y)
(principle of least surprise)
type(foo) is not str
objA is not objB
x == y
x is not y
to x === !y
.is
operator in LS. It's also one of the main reasons why I always use the ==
/!=
operators for equality.undefined
void
.undefined
.^
or **
.
alias of the <<
composition operator (consistency)* 'str'
, / 'str'
String::join
, String::split
, Prelude.ls's join
function, or its split
function.for ever
alias of loop
loop
.I do enjoy the @
alias for this
. It's very convenient.
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.
@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.
- '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...
@vendethiel +1
@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??'
I only disagree with
.
alias of the<<
composition operator (consistency)
I never used that, what does it do?
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)
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
@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')
@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
@impinball I enjoy match
a 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?
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.
So far (on master), slated for removal (and currently with compiler notices upon use):
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 betterwhere
statement - relatively useless - just use local var assignment or a let statement [currently has notice]undefined
alias forvoid
- added for CoffeeScript compatibility, but with coffee2ls that is not an issue [currently has notice]!?
inexistence op [currently has notice]discussion:
**
or^
for power op?import
andimportAll
?x is not y
to meanx isnt y
, have it meanx is !y
insteadyes/no/on/off
aliases - added for CoffeeScript compatibility, but now with coffee2ls, this is not an issueMore controversial:
@
::