I don't think you guys have the definition of "lexical scope" quite straight.
I've made darn sure that Sass is lexically scoped, as fully as is possible given that mixins can only be defined at top-level. Local variables shadow global variables, and a variable's scope is taken from its lexically enclosing environment, not its (dynamic) calling environment. I've worked up a couple of examples <http://gist.github.com/148913> that should demonstrate this. What you're actually asking for is a way to define local variables that shadow global variables. As Chris points out, this is a question of declaration vs. assignment, something that Sass doesn't distinguish between syntactically. This is behavior inherited from Ruby, which in retrospect might not be the best suited for the sort of language that Sass is. Again as Chris mentioned, we'll be examining this in the future. However, given that Sass does have lexical scope, even local variable assignment won't give you what you want, Carl. Mixins won't be able to access the scope of their callers; that's *dynamic* scope, not lexical. Nor will we allow functions to access the environment object because, as Chris said, that will impede future optimizations. Hope this is helpful! Good luck with your framework! - Nathan On Thu, Jul 16, 2009 at 5:07 PM, Chris Eppstein <[email protected]> wrote: > Regard the current environment, it should be possible, but doing so might > make certain optimizations we'd like to perform harder. (FYI: functions do > have access to the sass engine options via the evaluation context > model) Also, I'd really like to know what you're trying to do with the > environment and why you want to make functions that would need to > inspect/manipulate the lexical stack. I think it could result in some > "magical" behavior that could separate users from the mental model of how > things ought to work. > With respect to lexical scoping, I could certainly make an argument for > lexical scoping at the mixin level. For example: > > !foo = 1px > > =a-mixin(!baz) > !foo = !baz + 2px > :foo= !foo > > .before > :foo= !foo > > .during > +a-mixin(10px) > > .after > :foo= !foo > > Generates: > > .before { > foo: 1px; } > > .during { > foo: 12px; } > > .after { > foo: 12px; } > > I think it could be argued that !foo should have been 1px in the .after > class because mixins ought not need to know about the variables in use on > the page where they are mixed. > > Lexical scoping within the selector hierarchy would be very unnatural and > confusing, in my opinion, especially, if you can use mixins to create a > lexical scope, which I would be in favor of since default arguments have > access to the calling scope. If we did add lexical scoping, we'd need a > better syntax to separate a declaration from a simple assignment -- a > concept I've already been discussing with nathan. > > Now, with respect to your general approach of making your percents inherit > up the selector hierarchy, I would like to discourage you against this. > Here's the reason: The selector hierarchy is not the DOM hierarchy and sass > stylesheets do not know the DOM or how styles are cascading on the > page. Maybe the two match up, maybe they don't. Also, percents are always > relative to the dom parent, and the browser is responsible for that > calculation, so why would you need to know both to set the width as a > percentage? > > > Maybe if you gave a concrete example of what sass you'd like to write and how > it would work, I might understand better. > > Thanks for your email, and for leaping into the bowels of sass... it's > clear you did a lot of research before writing. > > chris > > On Thu, Jul 16, 2009 at 4:03 PM, Carl Meyer <[email protected]>wrote: > >> >> Hey all, >> >> There are some tricks I'd like to do with Sass mixins that require >> lexically scoped redefinition of variables. The machinery for this is >> pretty much already in place with the stacked environments that >> lexically scope variable definitions. The problem is that try_set_var >> always tries parent.try_set_var, meaning that any definition of an >> already-defined variable always directly affects the scope in which >> the variable was originally defined, whereas I'd like it to "mask" the >> outer definition with a temporary scoped definition. >> >> Doing this would require adding some syntax to mark when you want a >> scoped redefinition as opposed to a global redefinition (personally >> I'd prefer = to mean scoped redefinition and something like != for >> global redefinition, but that's backwards incompatible). Is there >> something I'm missing here, or a reason why this hasn't already been >> done? Would a patch for this be interesting to anyone else? >> >> (My use case is for a percentage-based elastic grid system, where >> nested columns need to know the width in columns of their parent >> element in order to generate the correct percentage width. Currently >> the context width has to be manually passed in as a mixin arg, but >> with scoped redefinition of variables it could be neatly handled >> automatically by the mixins themselves.) >> >> Oh, and while I'm making a pony wishlist anyway: is there a reason why >> functions in Sass::Script::Functions don't have access (afaict) to the >> current environment object? Or do they, and I'm just not seeing how? >> >> Sass is super-awesome - many thanks to the devs. >> >> Carl >> >> >> > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Haml" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/haml?hl=en -~----------~----~----~----~------~----~------~--~---
