Hm, thinking about it some more... Nulan does technically suffer from the same problems as Ruby, because of mutable variables. I took this example (https://gist.github.com/4110634#file_ref_8.rb) and tried rewriting it in Nulan style:
# library1
(types %inject)
(def (add-all [ %inject f ])
(f "" -> str acc (+ acc str)))
# application
(import library1)
(def (my-+ x y) "@x plus @y")
(def (my-array)
[ %inject -> str f
(do (each {"foo" "bar" "qux"} -> x
(set! str (let! + my-+ (f x str))))
str) ])
In this case, we're using "let!" to dynamically rebind "+" to "my-+". I think this is okay, though, for two reasons:
1) It's not idiomatic to assign to variables. Instead, it's idiomatic to use unique types to create extensible functionality. Mutability is discouraged in general (though allowed).
2) It's also possible to protect against such things, if you really want to. For instance, you could do this:
This is clunky, though, having to manually make everything safe to use. If I really wanted to, I could make a macro that automatically protects against such things:
But I, personally, don't see much reason for that since as point 1 said, it's not idiomatic to assign to variables.
Of course, I guess the same argument could be used for Ruby... if refinements aren't idiomatic, then it's not a big deal, right? Well, except that mutable monkey-patching actually is idiomatic in Ruby, refinements are just a way to scope them.
In any case, I feel that due to Nulan's different idioms and such, the kinds of problems Ruby has generally aren't an issue.
"In any case, I feel that due to Nulan's different idioms and such, the kinds of problems Ruby has generally aren't an issue."
It perplexed me that you didn't take that point of view in the first place. :) From that blog post, Ruby's refinements strike me as a snowball of complexity arising from the existing use of monkey patching in the wild. Nulan has no entrenched user base and no monkey patching mechanism (that I can see offhand), let alone a culture of monkey patching, so you have little to worry about. :-p
---
"It's not idiomatic to assign to variables [in Nulan]."
Well, I wonder what Ruby idioms were like before Rails came along! EDSLs often use every readability-enhancing language feature they can get their paws on, regardless of the intended stability of those features.
I'm a culprit of this. Consider my Arc module system, where namespaces work by assigning macros to the global scope, calling 'eval on a module body, and removing the macros again. When my module system didn't work in Jarc and Rainbow, I considered Jarc and Rainbow to be nonconformant, even after jazzdev and conanite fixed most of the obvious bugs and probably conformed to pg's intended design about as well as pg-Arc did. :)
---
Blog post: "It forces every Ruby programmer to second-guess every block of code they pass into someone else's library or someone else's method call."
You: "I'm fairly sure Nulan avoids [this issue]"
Actually, since Nulan's an fexpr language, its programmers potentially have to second-guess how every single expression will be evaluated. XD Yes you may have idioms to manage this paranoia, but that doesn't make Nulan exempt to the blog post's point, since Ruby could develop idioms for this too.
---
"[...]but I think this kind of "magical action at a distance" is consistent with Ruby's hyper-liberal viewpoint."
Yeah, when the blog post talks about a very dynamic language and warns about how certain features might threaten to break its local static invariants, there's a sense of whiplash there. :-p But it does make sense to care about local static reasoning in this case, since that's (at least informally) what refinements are supposed to bring to monkey patching in the first place.