curimit / SugarCpp

SugarCpp is a language which can compile to C++11.
135 stars 13 forks source link

to vs .. ... ..< #45

Open dobkeratops opened 9 years ago

dobkeratops commented 9 years ago

Would you consider freeing up the 'to' keyword by copying 'Swift'/ 'rusts' style syntax for ranges

... is an operator creating an inclusive range e.g. 0...9 yields [0,1,2,3,4,5,6,7,8,9] ..< is an operator yielding a range until the last value, e.g. 0..<n yields [0,1,2,3,4,... n-1]

(Swift used to use ..n for ..n-1, however I think they changed it to make it clearer.)

These could slot into a loop iterator protocol, or into your extended for loop sugar.

I realise this is highly subjective. There is a very good case for using 'to' as a keyword since it can create readable statements, and of course maybe 'to' itself could be an overloadable operator eg x to y desugar as to(x,y) and then you could actually implement it as a range constructor. to(x,y).begin()=x to(x,y).end()=y etc. I also realise ..< is more fidly to type than "to" because it needs 'shift'

I'm not familiar with the specific sources of inspiration you are drawing from.

curimit commented 9 years ago

I am also trying to replace the keyword to to just an operator, especially the keyword downto. Ps: xtoy can be compiled to to(x,y), if we free up the to keyword.

There are 4 different situations for ranges:

  1. [a..b] (eg. 1,2,3,4...)
  2. [b..a] (eg. 10,9,8..)
  3. [a,b..c] (eg. 1,3,5,7..)
  4. [c,b..a] (eg. 11,9,7,5..) We can see there are two problems here:
  5. How to determine a < b or a > b (one is up-to, the other is down-to).
  6. How to specify the step. Another problem is
  7. Including or excluding endpoints.

There are lots of syntax been invented. For example, CoffeeScript transpiler solve the problem 1 in this way:

(function() {
  _results = [];
  for (var _i = a; a <= b ? _i <= b : _i >= b; a <= b ? _i++ : _i--){ _results.push(_i); }
  return _results;
}).apply(this);

However, this code is not human readable, also increase the time cost. I want to generate human readable code, so I'm trying to find a syntax which let compiler know which kind of situation we want.

  1. F#
    • start..stop: means "start up-to stop"
    • start .. step .. stop: we can use this syntax to implement "down-to" some like [10 .. -1 .. 1]
  2. LiveScript
    • to and til here doesn't provide any information about the direction, so [a to b by c] will still need a dynamic check to determine whether c > 0.
  3. CoffeeScript
    • [a..b] need dynamic check to determine whether a < b
  4. Haskell
  5. Swift/Rust: You mentioned.

Your ..< idea looks good, but how to distinguish to and downto, here is my rough idea:

// to
1 .. 5 == [1,2,3,4,5]
1 ..<= 5 == [1,2,3,4,5]
1 ..< 5 == [1,2,3,4]
1 <.. 5 == [2,3,4,5]
1 <..< 5 == [2,3,4]

// downto
5 .. 1 == []
5 ..>= 1 == [5,4,3,2,1]
5 ..> 1 == [5,4,3,2]
5 >.. 1 == [4,3,2,1]

// step
1 .. 2 ..  7 == [1,3,5,7]
7 .. -2 .. 1 ==  []
7 .. -2 ..>= 1 ==  [7,5,3,1]

If we use to and downto, then we have to type more letters but can decrease the possibility of typing mistakes.

Do you have any ideas about distinguish to and downto?

dobkeratops commented 9 years ago

interesting. I like your ideas of swapping < for > to mean 'down to; ..<= ..>= ..< ..> I'd be happy to use that.

more brainstorming on this subject - Imagine if we had currying for operators. there's a problem, many operators in C++ have different use for prefix.. so this is probably a bad idea. but imagine making a sequence constructor..

seq(init, test, increment) ... creates an iterator starting at 'x=init()', continuing while 'test(x)', stepping on with x=increment(x)

seq(a, <b, ++) eg seq(5, <10, ++) gives 5,6,7,8,9 seq(b,>a,--) eg seq(10, >5 --) gives 10,9,8,7,6

However, I'd guess making something more specific like ..< ..> would slot better into the system you already have, and once you said '<' , you know you want ++, and vica versa > implies --.

ozra commented 9 years ago

I like the [1..<5] - it's much clearer than CS [1...5] for til operation. Also the reversal of comparators for downto is very obvious.

As for downto and stepping, in the literal cases much could be deduced, as per your examples but modified:

5 .. 1 == [5,4,3,2,1]
5 .. -1 .. 1 == [5,4,3,2,1]
5 ..>= 1 == [5,4,3,2,1]
5 ..> 1 == [5,4,3,2]
7 .. -2 .. 1 ==  [7,5,3,1]
7 .. -2 ..>= 1 ==  [7,5,3,1]
7 .. -2 ..> 1 ==  [7,5,3]