diff --git a/docs/syntax.md b/docs/syntax.md index bf09e66..95983b7 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -59,11 +59,12 @@ allowed but not required. ["Eggplant", "Pepper", "Zuccini"], ] -## Records +## Dictionaries -Records are surrounded by `{}`. Records can be written in json form, where the -left-hand side is an expression. Then the key and value are separated by `:` and -the element separator is `,`. A trailing comma is optional. +Dictionaries, _dicts_ for short, are surrounded by `{}`. Dicts can be written +in json form, where the left-hand side is an expression. Then the key and value +are separated by `:` and the element separator is `,`. A trailing comma is +optional. { "name": "apple", @@ -79,7 +80,7 @@ strings precludes serialization to json. 5 + 5: "X", } -Alternatively, records can be written in record form, where the left-hand side +Alternatively, dicts can be written in record form, where the left-hand side is an identifier. Then the key and value are separated by `=` and the element separator is `;`. A trailing semicolon is optional. The following value is identical to the first one above. @@ -89,20 +90,25 @@ identical to the first one above. flavor = "sweet"; } -Note, the empty collection `{}` is a set, not a record. -TODO: It _has_ to be a record, because in json it is a record. Need to fix! +Note, the empty collection `{}` is a dict, not a set. ## Sets -Sets are surrounded by `{}` and work otherwise the same as lists. The empty -collection `{}` is a set, not a record. The following list contains two -identical sets: +Sets are surrounded by `{}` and work otherwise the same as lists. The following +list contains two identical sets: [ {"Apple", "Pear"}, {"Apple", "Pear", "Apple"}, ] +Note, the empty collection `{}` is a dict, not a set. There is currently no +literal for the empty set. It is possible to work around this using +comprehensions: + + // An empty set. + {for x in []: x} + ## Let bindings Values can be bound to names with a let-binding. diff --git a/golden/error/runtime_collection_kv_scalar.test b/golden/error/runtime_collection_kv_scalar.test index 39f2fe1..7007e8d 100644 --- a/golden/error/runtime_collection_kv_scalar.test +++ b/golden/error/runtime_collection_kv_scalar.test @@ -14,4 +14,4 @@ Error: Expected key-value, not a scalar element. | 2 | "key": "value", | ^ -Note: The collection is a record and not a set, because of this key-value. +Note: The collection is a dict and not a set, because of this key-value. diff --git a/golden/error/runtime_collection_list_kv.test b/golden/error/runtime_collection_list_kv.test index 51b4514..be188ba 100644 --- a/golden/error/runtime_collection_list_kv.test +++ b/golden/error/runtime_collection_list_kv.test @@ -7,4 +7,4 @@ | ^ Error: Expected scalar element, not key-value. -Help: Key-value pairs are allowed in records, which are enclosed in '{}', not '[]'. +Help: Key-value pairs are allowed in dicts, which are enclosed in '{}', not '[]'. diff --git a/golden/error/runtime_collection_scalar_kv.test b/golden/error/runtime_collection_scalar_kv.test index 3db9204..ef860aa 100644 --- a/golden/error/runtime_collection_scalar_kv.test +++ b/golden/error/runtime_collection_scalar_kv.test @@ -14,4 +14,4 @@ Error: Expected scalar element, not key-value. | 2 | "single", | ^~~~~~~~ -Note: The collection is a set and not a record, because of this scalar value. +Note: The collection is a set and not a dict, because of this scalar value. diff --git a/golden/error/runtime_iter_arity_record.test b/golden/error/runtime_iter_arity_record.test index 334fcf0..98c07db 100644 --- a/golden/error/runtime_iter_arity_record.test +++ b/golden/error/runtime_iter_arity_record.test @@ -5,10 +5,10 @@ | 1 | [for kv in {"key": "value"}: kv] | ^~ -Error: Expected two variables in record iteration. +Error: Expected two variables in dict iteration. --> stdin:1:11 | 1 | [for kv in {"key": "value"}: kv] | ^~~~~~~~~~~~~~~~ -Note: This is a record, it yields a key and value per iteration. +Note: This is a dict, it yields a key and value per iteration. diff --git a/golden/json/empty_dict.test b/golden/json/empty_dict.test new file mode 100644 index 0000000..2b47c7d --- /dev/null +++ b/golden/json/empty_dict.test @@ -0,0 +1,5 @@ +// This is an empty dict, not an empty set. +{} + +# output: +{} diff --git a/golden/json/empty_set.test b/golden/json/empty_set.test deleted file mode 100644 index 7a24df9..0000000 --- a/golden/json/empty_set.test +++ /dev/null @@ -1,5 +0,0 @@ -// This is an empty set, not an empty record. -{} - -# output: -[] diff --git a/ideas/roadmap.md b/ideas/roadmap.md index 11c9f6c..a16f0af 100644 --- a/ideas/roadmap.md +++ b/ideas/roadmap.md @@ -3,14 +3,13 @@ ## Near term * [WIP] Colored output for json. - * Ensure `{}` is a dict, not a set, for json compatibility. +* [WIP] Update terminology; I am calling them dicts, not records. * The ability to turn coloring on or off, respect . * Add assertions. * Absorb the `highlight` command into `fmt` and make it use the same coloring? * Different output modes, RCL in addition to json (so we can preserve sets); possibly yaml output. * Preserve insertion order in dicts and sets. - * Update terminology; I am calling them dicts, not records. ## Method vs. field access diff --git a/src/eval.rs b/src/eval.rs index 4d59720..d42102f 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -7,7 +7,7 @@ //! Evaluation turns ASTs into values. -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeMap; use std::rc::Rc; use crate::ast::{BinOp, Expr, FormatFragment, Seq, UnOp}; @@ -23,8 +23,9 @@ pub fn eval(env: &mut Env, expr: &Expr) -> Result> { eval_seq(env, seq, &mut out)?; } match out { - // If we have no keys, it’s a set. - SeqOut::SetOrDict => Ok(Rc::new(Value::Set(BTreeSet::new()))), + // If we have no keys, it’s a dict, because json has no sets, + // and `{}` is a json value that should evaluate to itself. + SeqOut::SetOrDict => Ok(Rc::new(Value::Map(BTreeMap::new()))), SeqOut::Set(_, values) => { let result = values.into_iter().collect(); Ok(Rc::new(Value::Set(result)))