oilshell / oil

Oils is our upgrade path from bash to a better language and runtime. It's also for Python and JavaScript users who avoid shell!
http://www.oilshell.org/
Other
2.78k stars 150 forks source link

setvar out = out or mydict idiom doesn't work with empty dict, maybe deepcopy() #1866

Open andychu opened 3 months ago

andychu commented 3 months ago
          Ohh yess, Hmmmm  

Sorry setvar out = out or mydict has a bit of a pitfall -- when out is the empty dict.

The or operator tests if a value is "falsey", and that includes empty containers -- {} [] false null

This is a bit of an unfortunate interaction -- it's something Python also has. I actually tried to change what the or operator meant, but it causes other problems elsewhere in the language.


So really the right thing for dicts is

if (param === null) {
   setvar param = defaults
}

rather than

setvar param = param or defaults

Originally posted by @andychu in https://github.com/oilshell/oil/issues/1842#issuecomment-1979222860

andychu commented 3 months ago

Another possibility is to just evaluate at call time

That's probably easiest

However there is still the possibility of aliasing a global there ...

Like

proc p (d={k: globaldict}, mylist=[globaldict]) {
}
bar-g commented 3 months ago

However there is still the possibility of aliasing a global there ...

I think, the possibility is good, very much needed actually, to keep and update an external state, by default, and be able to call the same proc to process with another mutable for particular runs.

It's only the misleading "=" assignment meaning reference semantics in this case, that makes it implement the python-pitfall.

A well integrated ->-syntax feature, and defining that external default as mylist->[globaldict] should be able to solve this pitfall as well, and allow for mylist=[globaldict] to make a deepcopy. (Can that be done without a full traversal with what you named "pickling"?)

andychu commented 3 months ago

FWIW JavaScript now has syntactic sugar for null only checks (not falsey)


    foo ?? bar is syntactic sugar for ((foo === undefined) or (foo === null)) ? bar : foo.
    foo?.bar is syntactic sugar for ((foo === undefined) or (foo === null)) ? undefined : foo.bar.

https://www.scattered-thoughts.net/writing/unexplanations-sql-is-syntactic-sugar-for-relational-algebra/

Someone asked for ?. and destructuring on Zulip I think too