1# Features23Some features, which exists in jrsonnet, but not yet in other implementations.45Any of those features may be enabled during build time using feature flags, i.e: `--features=exp-destruct`.67## `exp-destruct`89Destructuring assignment, upstream issue: https://github.com/google/jsonnet/issues/3071011Destructuring object:1213```jsonnet14local {a: b} = obj; ...15// Same as16local b = obj.a; ...17```1819Field name may be omitted:2021> However, field name omission looks off here, as currently jsonnet doesn't allows `local a = 1; {a}` as a sugar for `local a = 1; {a: a}`, this causing asymmetry2223```jsonnet24local {a} = obj; ...25// Same as26local a = obj.a; ...27```2829Rest of fields may be collected into another object:3031```jsonnet32local {a, ...rest} = obj; ...33```3435And it is possible to set field defaults:3637```jsonnet38local {a = 1} = {};3940a == 141```4243Destructuring arrays:4445```jsonnet46local [a, b, c] = array; ...47```4849Rest of fields in any position may be collected into other array:5051```jsonnet52local [...rest, a] = array; ...53local [a, ...rest] = array; ...54local [a, ...rest, b] = array; ...55```5657In case of not needed fields there is `?` (because `_` is not reserved):5859```jsonnet60local [?, b, c] = ["a", "b", "c"]; ...61```6263Recursive destructuring also works:6465```jsonnet66local {a: [{b: {c: d}}]} = {a:[{b:{c:5}}]}; d == 567```6869Also mutually recursive declaration works:7071```jsonnet72local73 {a, b, c} = {a: y, b: c, c: x},74 {x, y, z} = {x: a, y: 2, z: b};75z == 276```7778This feature also works in function arguments:79> It is impossible to reference those parameters using named argument syntax8081```jsonnet82local myFun({a, b, c}) = a + b + c;8384myFun({a: 1, b: 2, c: 3})85```8687## `exp-preserve-order`8889Object field order preservation during manifestification, upstream issue: https://github.com/google/jsonnet/issues/9039091This feature adds a new CLI argument: `--preserve-order`, as well as additional `std.manifest*/std.objectFields*` standard library functions argument `preserve_order`.9293Using this argument, it is possible to have same field order in manifestification, as in declaration:9495```jsonnet96std.objectFields({c: 1, b: 2, a: 3}, preserve_order = false) == ['a', 'b', 'c'] # Fields were sorted97std.manifestJson({c: 1, b: 2, a: 3}, preserve_order = true) == ['c', 'b', 'a'] # Fields were serialized in declaration order98```99100## `exp-object-iteration`101102Iteration over object fields in comprehensions, upstream issue: https://github.com/google/jsonnet/issues/543103104This feature is not implemented as proposed in upstream, it only yields `[key, value]` arrays per element:105106```jsonnet107{108 [i[0] + '!']: i[1] + '!'109 for i in {110 a: 1,111 b: 2,112 c: 3,113 }114} == {115 'a!': '1!',116 'b!': '2!',117 'c!': '3!',118}119```120121However, it may be combined with `exp-destruct`, to implement syntax close to proposed:122123```jsonnet124{125 [k + '!']: v + '!'126 for [k, v] in {127 a: 1,128 b: 2,129 c: 3,130 }131} == {132 'a!': '1!',133 'b!': '2!',134 'c!': '3!',135}136```137138Unfortunately, there is no integration with the `exp-preserve-order` feature, fields will be still iterated in sorted order, and using old syntax is required:139140```jsonnet141local obj = {142 c: 3,143 b: 2,144 a: 1,145};146147{148 [key + '!']: obj[key] + '!'149 for key in std.objectFields(obj, preserve_order: true)150} == {151 'c!': '3!',152 'b!': '2!',153 'a!': '1!',154}155```156