
Ruby’s Hashes and Perl’s Autovivification, in JavaScript - braythwayt
http://raganwald.com/2018/09/12/auto-vivifying-hash.html
======
mickeyben
Great article! I had some fun with Autovivification a couple of years ago and
implemented a small ruby library to do just that
[https://github.com/mickey/black-hole-struct](https://github.com/mickey/black-
hole-struct).

I think the whole point was to help generate a few very long json files
([http://docs.grafana.org/reference/dashboard/#dashboard-
json](http://docs.grafana.org/reference/dashboard/#dashboard-json)) but in the
end I had way more fun with this new concept!

------
tkahnoski
I have a list of Perl ‘wtf’ moments. The discovery of autovification was one
of them.

Perl autovivifies on existence checks. This has led to A LOT of bugs.

Particularly since native Perl objects have all the behaviors of hashes so
instead of getting the equivalent of a null exception Perl happily creates a
hash and the process won’t bomb out until I try to call a method on the hash
which I was expecting as a particular type.

In legacy code, this has led to a lot of safety checks verifying the variable
is actually the expected type.

~~~
braythwayt
Autovivifying variables is wildly out there. I feel your pain!

Autovivifying properties of a dictionary could certaintly lead to some bugs,
but as presented here, checking for existence won’t invoke autovivification.

~~~
tkahnoski
Indeed. I wish with Perl I had a way to be explicit about when I could disable
this behavior but its builtin to the language to such a degree to be
unavoidable. (Using different Perl object frameworks and getter/setter methods
is a possibility to protect against this class of error)

The implementation provided in the article is at least a known property of
that particular object type and not a property of all objects.

~~~
draegtun
You can switch off or amend autovivification behaviour using this pragma
module -
[https://metacpan.org/pod/autovivification](https://metacpan.org/pod/autovivification)

    
    
        no autovivification;            # switches off autoviv except for setting
    
        no autovivification 'exists';   # just for exists checks

~~~
tkahnoski
OMG. All I have to say is thank you.

------
Ultimatt
If anyone's wondering how you get autoviv in Python, its surprisingly
gross/elegant/fun depending on how much you use the phrasing "pythonic" in
your interaction with people.

some_autoviv_variable = defaultdict(lambda: defaultdict(dict))

~~~
braythwayt
Cool! Does that create defaultdicts “all the way down?”

~~~
Ultimatt
At least until it hits the turtle bedrock at the end of your system memory. Oh
maybe you need the inner one to be a lambda of defaultdict actually, then it
will.

    
    
         turtles = lambda: defaultdict(turtles)
         some_autoviv_variable = defaultdict(turtles)
    

Have to confess I'm a polyglot type person, and even Im starting to twitch at
"unpythonic" feels of having something as nuts as a recursive expression in a
lambda with some assignment.

~~~
klibertp
I could agree with "unpythonic", as Python is a bit weak in this department,
but "recursive lambda" being "nuts" is a bit much - especially here, given the
site's name ;)

~~~
Ultimatt
Oh yeah only nuts given we are in Python land. It's kind of like if some super
advanced alien artefact landed on Earth. It would appear as magic incongruent
with reality. Thats Python and almost _anything_ thats expressive. God forbid
your brain can imagine something beyond simple statements.

------
gvx
> Our third use case involves checking whether the defaultValue is an ordinary
> value or a function. We could check every time it’s accessed, but instead
> we’ll assign different function bodies to the proxy’s get key. That way,
> it’s only checked at (open air quotes) compile time (close air quotes):

The code below that paragraph actually does check on every access, though.

~~~
fenomas
> The code below that paragraph actually does check on every access, though.

I could be wrong, but I think a sufficiently clever JS engine (like v8) would
remove that check at runtime, by realizing that half of the ternary operator
is dead code. (If it's hot code and it gets optimized, anyway).

~~~
braythwayt
Ah, the mythical “sufficiently smart compiler” :-)

~~~
fenomas
To clarify I wasn't being hypothetical, I think v8 will optimize out that
check today. I phrased it vaguely because I'm not sure whether other engines
would as well.

~~~
braythwayt
It’s certainly doable. The `defaultValue` parameter is passed by value, so it
will never be rebound. The result of using `typeof` on a value never changes
in JS, even if the value is modified. So... it should be possible to optimize
the check away after the first time.

