{"action":"created","issue":{"url":"https://api.github.com/repos/ozra/onyx-lang/issues/9","repository_url":"https://api.github.com/repos/ozra/onyx-lang","labels_url":"https://api.github.com/repos/ozra/onyx-lang/issues/9/labels{/name}","comments_url":"https://api.github.com/repos/ozra/onyx-lang/issues/9/comments","events_url":"https://api.github.com/repos/ozra/onyx-lang/issues/9/events","html_url":"https://github.com/ozra/onyx-lang/issues/9","id":135207326,"number":9,"title":"Basic Lexical Elements and Value Literals of Onyx","user":{"login":"ozra","id":563674,"avatar_url":"https://avatars.githubusercontent.com/u/563674?v=3","gravatar_id":"","url":"https://api.github.com/users/ozra","html_url":"https://github.com/ozra","followers_url":"https://api.github.com/users/ozra/followers","following_url":"https://api.github.com/users/ozra/following{/other_user}","gists_url":"https://api.github.com/users/ozra/gists{/gist_id}","starred_url":"https://api.github.com/users/ozra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ozra/subscriptions","organizations_url":"https://api.github.com/users/ozra/orgs","repos_url":"https://api.github.com/users/ozra/repos","events_url":"https://api.github.com/users/ozra/events{/privacy}","received_events_url":"https://api.github.com/users/ozra/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ozra/onyx-lang/labels/RFC","name":"RFC","color":"000000"},{"url":"https://api.github.com/repos/ozra/onyx-lang/labels/this-issue-doubles-as-DOC","name":"this-issue-doubles-as-DOC","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"2016-02-21T13:45:19Z","updated_at":"2016-09-21T22:18:43Z","closed_at":null,"body":"Note this issue only goes into the surface of constructs: the lexical aspects, for type-definition, etc. there are separate \"Doc / RFC\"-issues.\r\n\r\nThere 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.\r\n\r\n# Identifiers #\r\n\r\n## Variable and Function Identifiers ##\r\n\r\n```onyx\r\nmy–identifer = \"47\"  -- here using ENDASH in the identifier\r\n\r\nif my_identifer == my–identifer => say \"Yep - snake case is interchangeable!\"\r\nif my-identifer == my–identifer => say \"Yep - hyphens (lisp case) also!\"\r\nif myIdentifer == my–identifer => say \"Yep - even camelCase works!\"\r\n\r\nmy-fun-with-qmark?(foo) ->\r\n   foo == \"Say what?\"\r\n\r\nbar = my-fun-with-qmark?(\"Say what?\")  -- => true\r\n\r\n```\r\n\r\nInternally the separators are all represented the same way and therefore comparable.\r\n\r\n- I decided to transparently support (–|-|_) (ENDASH (\\u2013), hyphen, underscore) interchangeably as \"word-delimiters\".\r\n  + For the choice of ENDASH - of all available unicode characters - this came about through a long heated debate when I was hacking on the Nim compiler. If you want some motivations you can probably find that discussion with a search\r\n- Since there is a big crowd favouring humpNotation, I've now added experimental support for that too, though not being a fan, but for completeness in this sandbox-try-everything-out-phase of Onyx. \r\n- The rules for camelCase are, a capital latin alpha is translated to '_' + lcase(char) - keep that in mind!\r\n- This behaviour was inspired from Nim. There is a _major difference_ though: Nim throws away the delimiter-information (case insensitive past the initial character), in Onyx a delimitation is a delimitation, it can simply be _expressed differently_.\r\n- To maintain Crystal-compatibility: _Callable_ identifiers may _end_ with `?` and `!`.\r\n- The (?|!) ending characters are definitely up to debate in entirety - especially since nil-handling sugar using `identifier?method-to-call-if-not-nil()` and `identifier!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.\r\n\r\n### Quick (Biased) Comments ###\r\n- There are some studies that taken together point to `dash-notation` being better for comprehension, `snake_notation` second and `humpNotation` a far down third.\r\n  + There are some studies pointing the other way, but examining them, they were rather flawed in their design.\r\n  + Current studies must be seen as rather inconclusive.\r\n  + As with all things programming there is a big gap in the scientific community - any more studies that might apply would be welcome!\r\n- I _personally_ warmly recommend the ENDASH or lisp-case notation. After 28 years of coding, with a \"always looking for the better way\"-mindset and trying all kinds of styles, that's the one I keep favouring more and more. Much more fluent. The ENDASH \"grabs\" the neighbouring chars more, and _might_ look more fluent than hyphens in many (monotype) fonts. This is however entirely up to your project's style specification. Personally, in practice, I end up using hyphen.\r\n\r\n## Types ##\r\n\r\n```onyx\r\ntype MyType\r\n   some–member Int32 = 47\r\nend\r\n\r\nmy-type-instance = MyType()\r\n```\r\n\r\n### Type names are _always_ initial capital ###\r\n\r\n### Pros ###\r\n\r\n- Visual disambiguation - good for human\r\n- Less ambiguities already at parsing stage - good for compiler speed\r\n\r\n### Cons ###\r\n\r\n- For a big team / company with a mother tongue written in non Latin letters this means that _iff_ you'd like to write the code in your own\r\nlanguage, types must begin with, say, latin `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).\r\n    - It could be argued that english is the lingua franca, especially in programming contexts, and as such it should be favoured as basis for symbols in source code. (I'm not native english speaking myself, although do have a latin alhabet superset - which makes me biased)\r\n    - If it would be of great benefit and regarding a major language (Japanese, Chinese, Russian, etc.) this could be reconsidered in the future, if not _too_ intrusive - **also: when to stop adding? Pandoras box...**\r\n    - I hold the position for now that `pseudo-english` should be the lingua-franca of programming, and thus the scheme holds water.\r\n\r\n###  Prior Art, Preference and Motivation ###\r\n\r\nThis 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.\r\n\r\nThis, along with constants, also form the notion \"capital initial letter = compile time fixed symbol\".\r\n\r\n## Constants ##\r\n\r\n```onyx\r\nMyConstant = 47\r\n\r\ntype Foo\r\n   MyFooConstant = 47\r\nend\r\n\r\n```\r\n\r\n- Constants, just like types, are a compile time construct, constant at run time. Therefore they share the lexical notion of capitalization.\r\n- This lets us get rid of having to specify `const` constantly [hehe], keepig source cleaner and more focused on logic terms than formalia word noise.\r\n\r\nConstants aren't \"dangerous\", they're the \"safest part\" in code, so why should they have a \"shout out look\"?\r\nWell, they have a more \"formal\" importance. If you see code `compare x to thingie`. What is thingie now? But if `x is compared to Thingie`, you now that `Thingie` 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.\r\n\r\nIf 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:\r\n```onyx\r\nCRUDE_PI = 3.14\r\ncrude-pi() -> CRUDE_PI\r\n\r\nsay \"Hey, my lowercase 'constant': {crude-pi * 2}\"\r\n```\r\n\r\n## Global Variables ##\r\n\r\n```onyx\r\n-- currently:\r\n$my-global = 47\r\n$my-thread-bound-global = 42 'thread-bound\r\n\r\n```\r\n\r\n- Globals are prefixed with $ - _because_ it looks ugly (and makes them pop out clearly)\r\n\r\n## Namespacing Paths ##\r\n\r\nYou simply use dots: `SomeModule.SomeType.a-func()`\r\n\r\n\r\n# Literal Values #\r\n\r\n## Numbers ##\r\n\r\n```onyx\r\nmy-int-number = 47\r\nmy-real-number = 3.1415\r\nmy-hex-int = 0x2f\r\n\r\nmy-literal-typed-int = 47u64\r\n\r\n-- likely future idiomatic way (no longer typed at literal)\r\n-- my-literal-typed-int U64 = 47\r\n\r\nmy-big-number = 1_000_000_000  -- underscores can be used to clarify\r\n\r\n```\r\n\r\n[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, say `UInt8`, it fails because of type mismatch - which is ridiculous from a human being's perspective.\r\nThe type inference will be improved for this - just have to figure out the \"right way\" to implement it conceptually.\r\n\r\nThe data type is `StdInt`* for integer literals _by default_.\r\nThe data type is `Real` for real literals _by default_.\r\n\r\n(*) Note StdInt will be changed to be called simply Int, provided coordination with Crystal team holds.\r\n\r\nThe data type used for the literals can be changed, either explicitly as above, or through parse-pragma:\r\n`'int-literal=BigInt` - this would cause any literal integers to produce BigInts instead.\r\n`'real-literal=FixedPoint[4]` - you get the picture.\r\n\r\nThe variables in the above examples are inferred to the type of the literal - they're **not** dynamic.\r\n\r\n## Tags (aka Symbols) ##\r\n\r\n```onyx\r\nmy-tag = #some-tag\r\n\r\nmy-fun(foo Tag) ->  -- note, you don't have to specify the type - inferred!\r\n   case foo\r\n   when #some-tag    => say \"It was some tag\"\r\n   when #other-tag   => say \"It was other tag\"\r\n   else              => say \"It was {a} - which I don't recognise\"\r\n\r\nmy-fun #funky-tag  --> \"It was funky_tag - which I don't recognise\"\r\n```\r\n\r\n`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. \r\nAs easy as using strings as identifying tokens; but with the performance of an Int32.\r\n\r\n## Strings ##\r\n\r\n```onyx\r\nmy-string = \"A simple string\"\r\nmy-interpolated-string = \"Interpolation: {my-string} with sugar on top!\"\r\n-- any kind of expressions can go in the interpolation brackets of course!\r\n\r\nthe–str = \"111kjhgkjh\" \\\r\n   \"222dfghdfhgd\"\r\n\r\n--> \"111kjhgkjh222dfghdfhgd\"\r\n\r\nyet-a–str = \"111kjhgkjh\r\n   222dfghdfhgd\r\n   333asdfdf\r\n\"\r\n-- above preserves the white space and newlines\r\n\r\nmy-straight-str = %s<no {interpolation\\t here}\\n\\tOk!>\r\n-- for the %* string notations, you can pick your delimiter chars yourself,\r\n-- which ever makes the particular string clearer: `<...>`, `(...)`, `{...}`\r\n-- or `[...]`:\r\n\r\n```\r\n\r\nThe data type is `Str` / `String`\r\n\r\n## Chars ##\r\n\r\n```\r\nmy-char = _\"X\"\r\n```\r\n\r\n[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).\r\n\r\nWas 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.\r\n\r\n## Regular Expressions ##\r\n\r\n```onyx\r\nmy-regex = /^match-stuff.*$/i\r\nmatch = my-regex =~ \"does this match?\"\r\n```\r\n\r\nThe `=~` above is of course a generic operator that can be implemented for other purposes for other types.\r\n\r\nA consideration could be to change the syntax to prefixed-string, like Char:\r\n```onyx\r\nmy-regex = r\"^match-stuff.*$\"i\r\nmatch = my-regex ~= \"does this match?\"\r\n```\r\n\r\nHowever, in much network programming, which is quite common, regexes serve a steady role, do explicit sugar syntax for them seems warranted.\r\n\r\nThe resulting type is Regex.\r\n\r\n## List - a dynamically growing (Vector, Array, Seq, Sequence, etc. in other languages) ##\r\n\r\n```onyx\r\nmy-list = [items, go, here]\r\nother-list = [\r\n    \"a string\"      -- commas not necessary if newlined\r\n    47,             -- but are allowed\r\n    1.41\r\n    [\"nested list\", \"ok, duh!\"]\r\n]\r\n\r\n-- type of above is List< Str | StdInt | Real | List[Str] >\r\n\r\nan-empty-list = [] of Int   -- empty list has to be typed (since there are no\r\n                            -- values to infer type from)\r\nanother-empty-list = List[Int]()  -- same result as previous line\r\n```\r\n\r\nFor details on List vs Array see issue on basic data types: #***XXX.\r\n\r\nYou can make Listish literals with arbitrary type also, see `Set` for notation.\r\n\r\nAs is obvious by now: the resulting type is List<T>, where T can be a sum type.\r\n\r\n## Tuple ##\r\n\r\n```onyx\r\nmy–tuple = {\"foo\", 1, #bar}\r\n```\r\n\r\n[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!\r\n\r\n## Set ##\r\n\r\n```onyx\r\nmy–set = Set{\"foo\", 1, #bar}\r\n```\r\n\r\nAny type can be used as prefix as long as it implements the `[](ix)` method, this is therefor a generic \"listish\" syntax.\r\n[RFC] Set unfortunately doesn't have it's own literal for now (compare tuple above).\r\n\r\n\r\n## Map - Hash Map ##\r\n\r\n```onyx\r\nstring-keyed–hash = {\"foo\": 47, \"bar\": \"bar value\", \"qwo\": [\"a\", \"list\", \"here\"]}\r\ntag-keyed-hash = {\r\n    #foo: 47    -- commas not necessary when newlined\r\n    #bar: \"bar value\"\r\n    #qwo\": [\r\n        \"a\", \"list\"\r\n        \"here\"\r\n    ]\r\n}\r\n\r\nstring-keyed-hash-js-style = {\r\n  var_name: \"a value\"\r\n}\r\n\r\nsome-var = #a-key\r\nother-var = \"another key\"\r\n\r\nvariable-keys = {\r\n  some_var => \"some value\"\r\n  other_var => \"other value\"\r\n}\r\n\r\n-- type of above would be {Str|Tag => Str}\r\n\r\n```\r\n\r\n~~[RFC] Note, I will change the syntax for:~~ [ed: this is changed now / 2016-03-25]\r\n`{key_here: value_here}` - ~~it currently parses it the same as `key => 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!).~~\r\n\r\n\r\n**I've probably forgot something, just tell me.**\r\n"},"comment":{"url":"https://api.github.com/repos/ozra/onyx-lang/issues/comments/248759554","html_url":"https://github.com/ozra/onyx-lang/issues/9#issuecomment-248759554","issue_url":"https://api.github.com/repos/ozra/onyx-lang/issues/9","id":248759554,"user":{"login":"ozra","id":563674,"avatar_url":"https://avatars.githubusercontent.com/u/563674?v=3","gravatar_id":"","url":"https://api.github.com/users/ozra","html_url":"https://github.com/ozra","followers_url":"https://api.github.com/users/ozra/followers","following_url":"https://api.github.com/users/ozra/following{/other_user}","gists_url":"https://api.github.com/users/ozra/gists{/gist_id}","starred_url":"https://api.github.com/users/ozra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ozra/subscriptions","organizations_url":"https://api.github.com/users/ozra/orgs","repos_url":"https://api.github.com/users/ozra/repos","events_url":"https://api.github.com/users/ozra/events{/privacy}","received_events_url":"https://api.github.com/users/ozra/received_events","type":"User","site_admin":false},"created_at":"2016-09-21T22:18:43Z","updated_at":"2016-09-21T22:18:43Z","body":"For previous comment: #95. Link here in regard to Lexical and Literal aspects of lang."}}
{"actor":{"display_login":"ozra"}}