5 ms·
Newlines are not a fine separator; what if you have a definition that you intend to span multiple lines? In any case, the pipes go all the way back to EBNF, sin
by ek 13y ago
Newlines are not a fine separator; what if you have a definition that you intend to span multiple lines? In any case, the pipes go all the way back to EBNF, since what you are really doing when you specify an ADT is specifying a grammar of types.
I admit to also being a brace weenie; I would very much prefer if all the languages I had to use had them. However, Pyret exists in a tradition of many successful, braceless languages like Python, ML, and Lua.
- clhodapp 13y agoI feel that the argument for the need for multiline definitions here is a bit weak. You are already putting each definition on its own line, so the definitions are actually fairly close to how their actual usage will look. I feel that if you really need them to be all that long, you are already in weird-style territory, so it isn't such a bad idea to just say "deal with wide files". Overall, it improves ergonomics for the vast majority of use cases, with the only cost being a possible aesthetic annoyance for users who are already writing aesthetically-annoying code.
- lysium 13y agoAt the other end are definitions of which several fit on a single line: data Color = Red | Black
- clhodapp 13y agoLines really aren't much of a thing: they are a single keypress, which generates a newline character and some autogenerated indentation from your editor. There's no real difficulty in breaking things up across two lines versus typing any other extra character (this touches on another issue, which is that I am of the opinion that the concept of code brevity estimation by line count comparison is fundamentally flawed, as code with fewer wider lines is often just cumbersome to type as code with more narrower lines). That said, please consider the following: data Color = Red | Black data Color { Red; Black } data Color = Red | Black | Green data Color { Red; Black; Green } I think the brace + semicolon-newline style actually compares pretty favorably on single-line width (it wins out on line width to an increasing degree as the line gets longer, which is important). However, it is visually more complex, which matters a lot for shorter lines. For this reason, I think that allowing both syntaxes would be ideal. The pipe-based syntax could be encouraged for single lines (newline-termination would sidestep block-end inference issues), with the curly brace based syntax being encouraged for multi-line definitions. There is a slight disadvantage in that now a user would have to know both syntaxes, of course. edit: Of course, since Pyret's syntax requires that ADT parameters be specified in parentheses, you can actually omit the pipes in single-line mode, too, and opt to use space-juxtaposition.
- skrishnamurthi 13y agoFrom the very beginning we have debated whether or not to make the initial stick optional. We wanted at least a semester of code to review before we made a decision. I personally lean toward making it optional and just have to persuade the others (-:. With that, you would be able to write data Color: Red | Black | Green; We did also initially discuss using = instead of : in places where we were defining things (functions, data). That's still not completely out of the question. That would get you to data Color = Red | Green | Black; We need a closing delimiter to avoid creating huge ambiguities in the grammar.
- e12e 13y agoPlease don't use equal for assignment, unless you do something along the lines of prolog etc: (a, 2a) = (1, b) > b == 2
- skrishnamurthi 13y agoI can't respond directly to e12e's comment ("Please don't use equal for assignment" -- https://news.ycombinator.com/item?id=6704229 https://news.ycombinator.com/item?id=6704229) so I'll slightly abuse responding by doing so at this level. We don't EVER use = for assignment. For us, = is binding. If you write fun f(x): y = x * x y = x + 2 x - y end Pyret will say I'm confused: y is defined twice and point to the two bindings. The goal here is to make the common case work fine, where you create a bunch of distinct local bindings; but when you try to mutate, you have to do it explicitly: fun f(x): var y = x * x y := x + 2 x - y where: f(10) is -2 # the test passes end The first line inside f says "y is _currently_ this, but it's variable, so look out!", and subsequent mutations use := to change y. Unlike JavaScript (say), mutating a variable that hasn't previously been defined is an error, rather than quietly adding the variable to the set of defined names.
- lysium 13y agoThank you for distinguishing bindings and assignments. Please consider `var y := x * x` for consistency (note the ':=').