Open ozra opened 8 years ago
You mention "camelCase" and "humpNotation". Are they different?
I'm in favour of nil-handling sugar; but I'm not sure how well it'll interact with the ?
method suffix. Maybe require ??
if the method ends with ?
. fn?.fn
is preferable to fn?fn
, in my opinion.
I'm in favour of dashed identifiers, and optional commas in arrays. I suggest both regex syntaxes.
Implicit string literals in hashes is an interesting idea.
@stugol
I notice %s{ ... }
is non-interpolating. Is %{ ... }
interpolating?
Yes that's right:
%(...)
etc., is for using other delimiters for the string, as in Crystal.
%s(...)
etc., is flagged "straight string" - no interpolation.
Good. Asterite refused to implement non-interpolated strings. Sigh.
As of today: Char-syntax changed from %"X"
to _"X"
.
...why?
Looking through code, it simply looked veeery noisy with the percentages. I must admit, it wasn't very thought through.
I think, I'll follow the motto used up till now of expanding choices first, and then reducing options to what becomes preferred, only after some time of side by side usage. So I'll re-introduce the old syntax again, for evaluation, and to continue the de facto devlopment methodology of Onyx.
As of now: Char-syntax %"X"
re-introduced. Both are now available in order to evaluate and compare.
Hmm, I still want to allow 0 - n prime symbols at the end of identifiers (have wanted that since the beginning, but put it of again and again because of fear of confusion, but I think it's very moot!): Hmm, better put this in it's own issue first.
For previous comment: #95. Link here in regard to Lexical and Literal aspects of lang.
Note this issue only goes into the surface of constructs: the lexical aspects, for type-definition, etc. there are separate "Doc / RFC"-issues.
There are some
[RFC]
markers in this text, those are for lexical elements that are very much up to debate. You can question any of them. But those are ones in need.Identifiers
Variable and Function Identifiers
Internally the separators are all represented the same way and therefore comparable.
?
and!
.identifier?method-to-call-if-not-nil()
andidentifier!method-to-call-if-not-nil-otherwise-throw()
will be implemented (if no better idea turns up?). The favoured idea in my head atm is that the nil-handling notation favours callables ending with?
, and if not defined, looks for one without it.Quick (Biased) Comments
dash-notation
being better for comprehension,snake_notation
second andhumpNotation
a far down third.Types
Type names are always initial capital
Pros
Cons
T
or similar ad hoc scheme (we can't practically consider capitals in every possible script, and there's not the notion of captials distinction in all).pseudo-english
should be the lingua-franca of programming, and thus the scheme holds water.Prior Art, Preference and Motivation
This idea has followed my language design ideas for about a year now. When I stumbled upon Crystal, I saw it used the scheme also. Click. As Crystal now is in the family from AST-level down to LLVM - this is set in stone.
This, along with constants, also form the notion "capital initial letter = compile time fixed symbol".
Constants
const
constantly [hehe], keepig source cleaner and more focused on logic terms than formalia word noise.Constants aren't "dangerous", they're the "safest part" in code, so why should they have a "shout out look"? Well, they have a more "formal" importance. If you see code
compare x to thingie
. What is thingie now? But ifx is compared to Thingie
, you now thatThingie
is a formalized important concept. So it does hold higher system wide importance. I believe this justifies capitalization apart from it's status as compile time constant, which in that regard is a less important factor. In addition it helps speeding up compilation time.If you're hell bent on having some constant lower case, you could wrap it in a function - compiled in release mode this will be the exact same machine code and exact same speed:
Global Variables
Namespacing Paths
You simply use dots:
SomeModule.SomeType.a-func()
Literal Values
Numbers
[RFC] The literal typings will be removed. Currently a literal int is typed
StdInt
by default, and then if assigned to a var that is typed as, sayUInt8
, it fails because of type mismatch - which is ridiculous from a human being's perspective. The type inference will be improved for this - just have to figure out the "right way" to implement it conceptually.The data type is
StdInt
* for integer literals by default. The data type isReal
for real literals by default.(*) Note StdInt will be changed to be called simply Int, provided coordination with Crystal team holds.
The data type used for the literals can be changed, either explicitly as above, or through parse-pragma:
'int-literal=BigInt
- this would cause any literal integers to produce BigInts instead.'real-literal=FixedPoint[4]
- you get the picture.The variables in the above examples are inferred to the type of the literal - they're not dynamic.
Tags (aka Symbols)
Tag
(think "hash-tags"...) are unique program-wide, they get a unique Int32 number internally, and so are very efficient. Preferably you should use enums, but in some cases, just having ad hoc tags is very convenient. As easy as using strings as identifying tokens; but with the performance of an Int32.Strings
The data type is
Str
/String
Chars
[RFC] Chars are no way near common enough to warrant wasting a unique symbol on (like single quote for instance, which has several other, more important, functions in Onyx).
Was first
c"X"
, but then changed to%c"X"
, which follows the pattern of the other "special string literal notations", but I decided to at least give chars some special treatment, going `%"X", but after some use, it looks noisy, so tests underscore variant now.Regular Expressions
The
=~
above is of course a generic operator that can be implemented for other purposes for other types.A consideration could be to change the syntax to prefixed-string, like Char:
However, in much network programming, which is quite common, regexes serve a steady role, do explicit sugar syntax for them seems warranted.
The resulting type is Regex.
List - a dynamically growing (Vector, Array, Seq, Sequence, etc. in other languages)
For details on List vs Array see issue on basic data types: #***XXX.
You can make Listish literals with arbitrary type also, see
Set
for notation.As is obvious by now: the resulting type is List, where T can be a sum type.
Tuple
[RFC] It is desirable to use
(items, here)
notation for tuples, because braces are never used for tuples in mathematical notation. It does however make syntax a lot messier, since both expression grouping and lambda-parameters use parentheses. The current tuple notation would be much better of used for set-notation!Set
Any type can be used as prefix as long as it implements the
[](ix)
method, this is therefor a generic "listish" syntax. [RFC] Set unfortunately doesn't have it's own literal for now (compare tuple above).Map - Hash Map
[RFC] Note, I will change the syntax for:[ed: this is changed now / 2016-03-25]{key_here: value_here}
-it currently parses it the same askey => val
notation. I will change this to follow Javascript JSON variation: key_here considered a literal string. This might facilitate network coding working with JSON's a lot, since you've then essentially got JSON-syntax in Onyx (but strongly typed!).I've probably forgot something, just tell me.