3 ms·
What is the history of the `.` notation? In Javascript obj={key: "val"};obj.key === obj["key"]; => true and the same in many other languages, like Java, C#,
by yjgyhj 11y ago
What is the history of the `.` notation? In Javascript
obj={key: "val"};obj.key === obj["key"]; => true
and the same in many other languages, like Java, C#, Elm, Haskell (I think) et cetera. The only ones in common use I can think of now is Lisp & C (but of course there are thousands).
This pattern of putting the key to get after the object seems popular, but what is the history behind it?
And why is it uncommon to have something like get(obj, key)? Or like in Clojure, `(get {:key :val} :key)`? Seems more consistent, and uses less syntax.
- vinay427 11y agoI would agree with the preference for Clojure-style syntax, though using a getter function makes more sense in a language like Clojure with immutable maps (as opposed to most of the languages you mentioned). At least in OO languages the dot operator feels too much like a class rather than a map/dictionary. An acceptable alternative is the C++ STL map square bracket indexing.
- Pxtl 11y agoIn Vb.NET there's a ! operator for name-like dictionary lookups, so Foo!Bar is equivalent to Foo("Bar") where Foo is a dictionary.
- masklinn 11y ago> Haskell (I think) Not Haskell, record fields are accessed via automatically generated accessor functions e.g. after defining data Car = Car {company :: String, model :: String, year :: Int} you'd have company :: Car -> String model :: Car -> String year :: Car -> Int > And why is it uncommon to have something like get(obj, key)? Or like in Clojure, `(get {:key :val} :key)`? Seems more consistent, and uses less syntax. Isn't get for collections? While historical javascript conflates records and hashmaps, most languages have a rather strict difference between the two, including clojure I believe. And do provide some sort of `get` for maps (as a free function or as a method depending on the language's base paradigm). I know of few languages where accessing record attributes and map values uses the same syntax[0] And in clojure get isn't even necessary as most collections also act as functions e.g. `(get {:key :val} :key)` can be replaced by `({:key :val} :key)`, or (for maps only, IIRC integers are not IFn) `(:key {:key :val})` [0] natively anyway, I have seen e.g. Python libraries where maps were extended to provide attribute-access to their values.
- michaelcampbell 11y agoJust a nit; Java does not use dot notation for map access. (Groovy can, but can also use Java notation.) Not that it matters, but how do you reckon `get(obj, key)` is less syntax than `obj.key`?
- masklinn 11y agoI'm guessing they're talking about the syntactic footprint of the language. Of course that assumes: 1. you have free functions at all (wasn't the case in Java until 1.5 and static imports IIRC, still isn't the case in Smalltalk, and seemingly free functions in Ruby are actually methods of Kernel, an actual free function would be a Proc bound to a global name) 2. you only have free functions, or all your syntax is expressed with free function syntax (which is fairly specific to Lisps, Julia also has generic functions but afaik still uses dotted attribute access)
- yjgyhj 11y agoYeah, the concepts are different, but usage overlaps. That is why I consider them equal.
- vorg 11y agoExcept that `obj.class` gets the class for the object, instead of `get(obj, "class")` or `obj["class"]`. So many little special cases in Groovy's huge grammar, which is still written in Antlr 2.x when both Antlr 3 and 4 shipped long ago.
- tel 11y agoIn Elm you use static types to think of Javascript objects as static, anonymous records instead of dynamic dictionaries. There's a different type for that second use case with no syntax (just `get`). Theoretically this could enable a lot of optimization for Elm, but at the moment I don't think the compiler takes advantage of this. It's the same thing that Google's Closure compiler does.
- wtetzner 11y agoBecause they're not the same thing. One is a record/field lookup, the other is a map lookup. For record lookups, there is no key. What would you pass to the get function as the key? A string? Now the compiler can't reason about it at compile time. It turns into a runtime lookup. In languages like OCaml, there is no reflection, so there is no way to do a runtime lookup of a key. It has to know the name at compile time, and the name is then translated to a byte offset into the record.