streem
streem copied to clipboard
What is your opinion about removing the curly brackets?
seq(100) | |x|
if x % 15 == 0
"FizzBuzz"
else if x % 3 == 0
"Fizz"
else if x % 5 == 0
"Buzz"
else
x
| STDOUT
Indentation could be used instead.
While I'm not against an indent based syntax, I personally don't like the | |x|
bit. I find it confusing since the block parameter and pipe syntax use the same |
character. If we went with a syntax like this, there should be a different parameter character (or a different pipe character, but I like |
for pipes).
Also, this might be too hard to implement, but that's up to the language designers.
An indent-based syntax would make it impossible to implement one-liners with the equivalent of sed -e
/ ruby -e
for Streem.
Edit: clarified.
@nicolasmccurdy yea, as I was 'converting' the code, the pipe and block part seemed quite meh.
A few ideas:
- create a reserved word
pipe
- make the
|
optional when ablock
is given
@nicolasmccurdy I feel same way, and now seeking different syntax. If you have idea, please tell me.
As @dbohdan pointed out, indentation based block is against one liners, which is bad for a shell influenced language.
Removing curlies is exactly what makes CoffeeScript so beautiful, yet so dangerous, because:
Significant Whitespace + Spaghetti Code == Death!!
Significant whitespace doesn't stop people from writing bad code.
Remove the braces, remove the parens, remove the trailing | STDOUT
, ... just a little further and you'll have re-written Bash. :)
how about
seq(100) => |x|
x % 15 == 0 then "FizzBuzz",
x % 3 == 0 then "Fizz",
x % 5 == 0 then "Buzz",
x
=> STDOUT
@disjukr I personally prefer having the pipe as the flow operator.
Even if the =>
is explicit enough though...
What about existing FBP DSL?
#
# Simple flow with core components
#
'3s' -> INTERVAL Ticker1(core/ticker)
'2s' -> INTERVAL Ticker2(core/ticker)
'1s' -> INTERVAL Clock(core/ticker)
Ticker1 OUT -> IN1 Joiner(core/joiner)
Ticker2 OUT -> IN2 Joiner
Joiner OUT -> IN Switch(core/switch)
Clock OUT -> GATE Switch OUT -> IN Splitter(core/splitter)
Splitter OUT1 -> IN Forwarder(core/passthru) OUT -> IN Log(core/console)
Splitter OUT2 -> IN Log
Debugger(debug/oneshot) OUT -> IN Crasher(debug/crasher) OUT -> IN Log
What about |
as flow operator (familiar for all shell users) and (…)
as block parameter (familiar for all programmers since ALGOL 68 and onwards :-)):
seq(100) | (x)
if x % 15 == 0
"FizzBuzz"
else if x % 3 == 0
"Fizz"
else if x % 5 == 0
"Buzz"
else
x
| STDOUT
Pre-UNIX history about pipes – "The Origin of Unix Pipes", http://doc.cat-v.org/unix/pipes/
Even if we don't use the no-curly braces idea, I do like the idea of doing a more normal syntax for block paramaters.
@dbohdan wrote:
An indent-based syntax would make it impossible to implement one-liners with the equivalent of
sed -e
/ruby -e
for Streem.
Thus, indent-based syntax should not be mandatory. But Streem could still support a normal syntax and also an indent-based syntax. For example, you could implement both of these syntaxes:
if x == 0 { "x is zero" }
if x == 0
"x is zero"
That could cause some confusion. What if you forget one curly brace, but properly indent?
seq(100) | (x) {
if x % 15 == 0
return "FizzBuzz"
else if x % 3 == 0
return "Fizz"
else if x % 5 == 0
return "Buzz"
else
return x
} | STDOUT
I like curly brackets, and oleksandr's example in my way:
{(=> t1 t2 c)
t1 = Ticker1('3s')
t2 = Ticker2('2s')
c = Clock('1s')
} | {(t1 t2 c => j c)
j = Joiner(t1 t2)
} | {(j c => s)
s = Switch(j c)
} | {(sw => sp1 sp2)
(sp1 sp2) = Splitter(sw)
} | {(sp1 sp2 => f sp2)
f = Forwarder(sp1)
} | {(f sp2)
Log = f
Log = sp2
}
Regarding the block parameters...one idea would be to use Ruby 1.9 / CoffeeScript shorthand lambda -> syntax. Or the less pretty ^ (arg1, arg2) { ... }
found in Obj-C.
seq(100) | -> (x) {
if x % 15 == 0 {
"FizzBuzz"
} else if x % 3 == 0 {
"Fizz"
} else if x % 5 == 0 {
"Buzz"
} else {
x
}
} | STDOUT
I like based syntax. The | |x|
may have a problem because expression will have OR operator.
seq(100) | |x|
x = x | 2
| STDOUT
having brackets will be a guard to avoid that the parser become complex.
(: this is true.
seq(100) | (x) if x % 15 == 0 "FizzBuzz" else if x % 3 == 0 "Fizz" else if x % 5 == 0 "Buzz" else x | STDOUT
As I said in above, expression may contains (x)
.
seq(100) | (x)
y = 2 | (x)
| STDOUT
@mattn 'or' operator is ||
currently. https://github.com/matz/streem/blob/a63a29f2156d4fdd45ce65ca9a7f861e1c253675/src/lex.l#L27
and i think (x)
expression may have no problem.
for example, javascript's block scope syntax is {}
although it's already have same syntax to express object literal.
|
and ||
should be different behavior.
Too many pipes... kill pipes. Brackets / Indentation are a very good way to have both fast and expressive way of writing things.
- Brackets are very clear when you've got a lot to write or when you need to do one-liners.
- Indentation is very clear when scripting a bit.
Hmm. Maybe we could do what Ruby does, except with whitespace. One-liners can use braces. But on multiple lines, you have to use whitespace?
In LiveScript, the FizzBuzz would look like this:
[1 to 100] |> map ->
| it % 15 is 0 => \FizzBuzz
| it % 3 is 0 => \Fizz
| it % 5 is 0 => \Buzz
| otherwise => it
|> each console.log
FizzBuzz would look about the same in F# too (the F# syntax itself is further explained in http://stackoverflow.com/a/2422713/809572)
[1..100]
|> Seq.map (function
| x when x % 15 = 0 -> "FizzBuzz"
| x when x % 3 = 0 -> "Fizz"
| x when x % 5 = 0 -> "Buzz"
| x -> string x)
|> Seq.iter (printfn "%s")
Im for F# or LiveScript syntax. LiveScript looks better to me.
While we're thinking about LiveScript, I'd highly desire to allow identifiers with dashes:
my-identifier
I also strongly dislike being forced to use capitalization anywhere.
@christopherdumas I agree.
@naturalethic I agree.