Open aleclarson opened 6 years ago
I did think of map and set being keywords, but I don't want [|arrays|]
, maps, and sets to feel like second class citizens, or like they are somehow significantly different from records or lists.
A lot of the things that are possible in records are also possible in maps and sets, and they share a lot of syntax. So I want them to feel conceptually similar
I agree, they should feel first-class.
You wouldn't really need the Map
keyword since 1 => 2,
indicates a map to the compiler, and you wouldn't be able to mix that with a: 1
syntax.
let record = { a: 1, b: 2 }
let map = { 'a' => 1, 'b' => 2 }
For lists, arrays, and sets:
let list = [ 1, 2, 3 ]
let array = +[ 1, 2, 3 ]
let set = -[ 1, 2, 3 ]
It might be interesting for lists to use parentheses.
let list = ( 1, 2, 3 )
let array = [ 1, 2, 3 ]
let set = [[ 1, 2, 3 ]]
This won't work because a list of a single list is a valid thing people may want to do and relying on their being a whitespace is hard to notice.
let set = [[ 1, 2, 3 ]]
let list = ( 1, 2, 3 )
There's already a lot of use of parenthesis in expressions. I don't want there to be many places where you have parenthesis next to each other:
let a = fn((a && (fn())))
Also, you have to deal with a lot of syntax ambiguities when using the (grouping && syntax)
. It just generally gets confusing.
let record = { a: 1, b: 2 }
let map = { 'a' => 1, 'b' => 2 }
How do you create an empty map? I don't want the answer to be new Map()
I also don't want to have huge lookaheads in the parser to figure out what {
means.
I can see an argument for =>
over =
but I think it's already going to have to be something people get used to, and I liked how {=
and =
matched up. So much so that I've thought about doing this:
let map = {=
'keyA' = 1,
'keyB' = 2,
=}
let record = {:
keyA: 1,
keyB: 2,
:}
let set = {
1,
2,
}
How about getting rid of the regular record syntax and requiring that it be annotated with a type?
let record = Person {
name: "John Doe",
age: 42
}
This would free up {}
for maps, and perhaps {{}}
for sets.
Also, Python uses (a, b, c)
(parens are optional in most cases, that’s how you can do a, b = b, a
) as a tuple, or readonly array.
There could also be a sigil (_
, perhaps) that would infer the type:
let record = Person {
name: _ {
first: "Jane",
last: "Doe"
},
age: 42
}
Would empty map be {==}
or {=}
?
I think {: a: 1 :}
would be unbearable when using records a lot.
How about the following?
let map = { 'a' = 1, 'b' = 2 }
let empty = <Map>{}
let set = { 1, 2 }
let empty = <Set>{}
let record = { a: 1, b: 2 }
let empty = {}
PS: Not a fan of the required type annotation for records that @j-f1 suggests.
This is the other syntax that I'm considering with keywords:
let map = map { 'a' = 1, 'b' = 2 }
let empty = map {}
let set = set { 1, 2 }
let empty = set {}
let record = { a: 1, b: 2 }
let empty = {}
You could also have everything use constructors:
let m = map(a=1, b=2)
let s = set(1, 2, 3)
let r = record(a=1, a=2)
let a = array(1, 2, 3)
# etc
FWIW: I don't love the aesthetic of
{= =}
and{- -}
.Below is my proposal (other proposals are invited to this thread):
The idea is to remove cryptic syntax (
{=
and{-
) and make map keys look less like variable assignments.Along the way, I'm playing with the idea of function calls being able to omit the parentheses when only one argument is passed and it's an object/array literal.