Open haskellcamargo opened 9 years ago
Livescript has enough arcane syntactic sweets as it is. Also this could easily be achieved with a small function. The syntax would be nearly as concise as the proposed one. Example:
Enum = ->
elems = if typeof! &0 is \Array
&0
else
&
i = 0
r = {}
for e in elems
r[i] = e
r[e] = i++
r
with usage
UserData = Enum <[Active Inactive Removed]>
or
UserData = Enum \Active \Inactive \Removed
Sum types would be more interesting:
union-stmt ::= "union" INDENT <union-case> DEDENT;
union-case ::= <identifier> "(" <identifier-list> ")" | <identifier>
identifier-list ::= <identifier> ("," <identifier>)*
AST = union
Id name
Lambda arg, body
App op arg
{ Id, App, Lambda } = AST
App (Lambda (Id \x), (Id \x)), (Lambda (Id \x), (Id \x))
AST = ->
class UNION;
UNION.Id = class Id extends UNION
(@name) ->
UNION.Lambda = class Lambda extends UNION
(@arg, @body) ->
UNION.App = class App extends UNION
(@op, @arg) ->
UNION
But you can also implement this in userland reasonably well:
items = (o) ->
[[k, v] for k, v of o]
get = (o, n) --> o[n]
union = (cases) ->
class UNION
(items cases).forEach ([name, args]) ->
UNION[name] = class extends UNION
(...ys) ->
a = ^^UNION[name].prototype
for x in args
a[x] = ys.shift!
return a
toString: ->
"#{name}(#{args.map get(this) .join ', '})"
UNION
And use it as:
AST = union do
Id: <[ name ]>
App: <[ op arg ]>
Lambda: <[ arg body ]>
{ Id, App, Lambda } = AST
console.log((Id "foo").to-string!)
console.log <| (App (Lambda (Id \x), (Id \x)), (Lambda (Id \x), (Id \x))).to-string!
I wonder why enum
is a reserved word if the language natively has no support for it.
because it's a JS reserved word
Couldn't it be solved by prefixing all identifiers with _
?
In the language that I'm designing, RawrLang, all the identifiers that are keywords of the target language and are unused by the source language are prefixed by "_" while transcompiling, allowing to use words like class
or interface
as identifier names by hygienized keywords.
This can be simply implemented in the compiler by, while consuming an identifier, verify if it is in a unused keywords table and, if true, prefixing it by an underscore and, to avoid ambiguities, verify the identifiers table and deal with ambiguous values, such as enum => _enum
to _enum => $_enum
and thus continuously.
An enum is a very useful structure for data abstraction and I miss them in LiveScript. In Haskell, although, we can use algebraic data types to abstract our problem. TypeScript already has good support for them.
Proposed syntax
Example
With usage
Transcompiling to
I open the discussion for implementation. If approved, I accept to implement it by myself and make a pull request.