Skip to content

Instantly share code, notes, and snippets.

@mystor
Created October 3, 2014 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mystor/c7013abf1cad40b526f0 to your computer and use it in GitHub Desktop.
Save mystor/c7013abf1cad40b526f0 to your computer and use it in GitHub Desktop.
Proposed Changes to Myst Object Syntax
-- PROBLEM 1: Large objects as arguments
react.createClass Obj#{
render: fn ->
doSomething!
}
-- Becomes --
<{
react.createClass Obj#{
render: fn ->
<{ doSomething! }>
;} -- A semicolon is inserted because of indentation
}>
-- This can be fixed by a few different mechanisms:
-- - Special case } and similar tokens to prevent ; from
-- being inserted before them
-- - Change the Syntax for objects, such that this doesn't
-- happen.
-- - Example: <{ => {, }> => }
-- object : (Obj|Map) { [property] }
-- For the first case, the syntax would be the same as currently
-- For the second case, you would be able to do this:
react.createClass Obj
render: fn ->
doSomething!
-- The layout engine would consider Obj to be a block-initializer,
-- rather than the empty object, and would insert tokens as follows:
{react.createClass Obj
{render: fn ->
{doSomething!
}}}
-- This also would simplify the problem of where to put the comma
react.createClass Obj
render: fn -> x
getInitialState: fn -> initialState
-- becomes --
{react.createClass Obj
{render: fn -> {x
};getInitialState: fn -> {initialState
}}}
-- One-line objects would look like:
react.DOM.div (Obj id: "myId"; className: "thing")
-- becomes --
{react.DOM.div (Obj {id: "myId"; className: "thing"})
}
-- Presumably, lists/arrays would be similar
map f (Arr a; b; c; d)
-- becomes --
{map f (Arr {a; b; c; d})
}
-- or --
map f Arr
firstElement
secondElement
thirdElement
fourthElement
-- becomes --
{map f Arr
{firstElement
;secondElement
;thirdElement
;fourthElement
}}
-- I'm not sold on the token for the block initializer
-- Also, this means that the #merge operator may not work as well
-- We won't be able to do
Map#map_or_object
-- to get something as a Map, as Map will be a special token...
-- There may be another option of `MapE` for an empty map
-- which can be merged into, but it won't be as elegant
-- We could probably do lhs binding in map decls too!
doSomethingWith Obj
methodA x:
let y = 20
let z = 30
x + y + z
methodB y: if y < 10
then 1
else methodB (y - 1) -- methodB is visible!
-- If we want, we can even use = instead of :
doSomethingWith Obj
methodA x =
let y = 20
let z = 30
x + y + z
methodB y = if y < 10
then 1
else methodB (y - 1) -- methodB is visible!
-- This may produce nice-ish syntax for creating classes
mkThingy x y = Obj
__constructor__: mkThingy
x: x
y: y
-- or --
mkThingy x y = Obj
__proto__: mkThingy.prototype
x: x
y: y
-- Presumably, the optimizer could make this
-- actually quite efficient, by detecting the
-- special __constructor__ and __proto__ properties
-- This brings up the problem of how to handle maps in pattern matches
-- This is how it's currently done
case x of
{a, b, c} -> -- a, b, and c are avaliable here
[d, e, f] -> -- elements 0, 1, 2 are bound to d, e, f
{a:[1,2]} -> -- Checks if the property a matches [1,2]
-- With the new system, for the sake of consistency,
-- it would probably look like
case x of
Map{a; b; c} -> -- a, b, and c are avaliable here
Vec{d; e; f} -> -- elements 0, 1, 2 are bound to d,e,f
Map{a:Vec{1; 2}} -> -- Checks if the property a matches Vec{1; 2}
-- or --
case x of
(Map a; b; c) -> -- a, b, and c are avaliable here
(Vec d; e; f) -> -- elements 0, 1, 2 are bound to d,e,f
(Map a:(Vec 1; 2)) -> -- Checks if the property a matches Vec{1; 2}
-- But this actually would have different semantics, as
-- the original version matched against map-like things
-- (it would also match against objects), while this only
-- matches against Maps/Vecs (you could also match vs. objects)
-- Maybe there would be a more generic version?
case x of
(# a; b; c) -> -- hashmap?
(.. a; b; c) -> -- list?
(# a:(.. 1; 2)) -> -- Looks kinda ugly & weird
-- Also splats?
case x of
(Vec x; ..xs) -> -- Much more verbose than [x, ..xs]
-- Use the old syntax for generic cases?
case x of
(Map a; b) -> -- Map
{a; b} -> -- Map -or- Obj
(Vec a; b) -> -- Vec
[a; b] -> -- Vec or Arr
(Set a; b) -> -- Set
-- , could be made equivalent to ;, to make the syntax similar?
case x of
(Map a, b) -> -- Map
{a, b} -> -- Map -or -Obj
(Vec a, b) -> -- Vec
[a, b] -> -- Vec or Arr
(Set a, b) -> -- Set
-- That could also happen in instantiation
fun (Map a: 'b', c: 'd')
-- or ; could be dropped entirely for , (make , the statement delimiter)
-- Maybe require a # after the name, and allow people to define
-- their own object types (some standard interface for instantiation?)
case x of
(Map#a, b) -> Map# a: b; b: a
{a, b} -> Obj# a: b; b: a
-- Match vs maybes?
(Just# x) -> doSomethingWith x
(Nothing#) -> doSomething!
-- There would have to be a syntax & type stuff
-- Perhaps a class type which represents a constructor?
let Just = Class#
properties: Vec# x
prototype: Obj#
isJust: true
let Nothing = Class#
prototype: Obj#
isJust: false
-- Creating?
let myObject = Just# 10 -- construct from array?
-- or?
let myObject = Just# x:10 -- construct from map?
-- or?
let myObject = Just 10 -- function constructor?
-- It would be pretty cool if you could instantiate JS objs
-- in this way too...
let someObjectRequiringNew = Router# apple, pear
-- Although, destructuring wouldn't make any sense...
-- Another thing which could be nice is arbitrary blocks
-- of code which are isolated with variables
let x = 10
begin -- (maybe do, but I would like that for pseudo-monads)
let x = 20
console:log x -- 20
console:log x -- 10
-- Thanks a ton for reading through this, I really appreciate
-- your input :). Do you have any opinions on these syntaxes?
-- I find that writing them out helps me realize what I like and
-- what I don't like about them.
-- I'm not super happy with anything above, and I would love
-- your input as to how I could improve the syntax going forward
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment