another thought on how to implement namespaces

45 views
Skip to first unread message

rogerdpack

unread,
Jun 17, 2010, 4:12:45 PM6/17/10
to ruby optimization
Here's my latest:

convert this:

using namespace "xyz"
class String
def go
end
end
end


using namespace "xyz"
'abc'.go
end


to this:


class String
def go_namespace_xyz
end
end
end

'abc'.go_namespace_xyz

How? By remembering 'in namespace xyz, I have previously defined a go
method' and assuming that that's the one they really want.

People would get used to it after awhile.
Thoughts?
-rp

Charles Oliver Nutter

unread,
Jun 17, 2010, 7:37:24 PM6/17/10
to ruby-opt...@googlegroups.com
I actually implemented a hack similar to this in JRuby, whereby you
could specify that all calls within a given scope or file should have
an additional dispatch step that checks for installed namespaces. It
was largely just decorating the call nodes in the AST with additional
logic that only fired when a namespace was active. Not hard to add,
really.

The biggest questions I've had with regards to namespacing are:

* How do you define the scope? Keep in mind that Ruby scopes are only
partially determined at compile time, and constant lookups (for
example) are not resolved until runtime
* How do you know what code should see the namespacing? Should it be
all code downthread from a namespacing call, or should it be only code
local to some Ruby structure (file, module, block)

Groovy is the only language I know of that has attempted to implement
this sort of namespacing, using a "downthread" approach, and I know
it's caused them a lot of problems over time.

Roger Pack

unread,
Jun 18, 2010, 11:13:47 AM6/18/10
to ruby-opt...@googlegroups.com
> * How do you define the scope? Keep in mind that Ruby scopes are only
> partially determined at compile time, and constant lookups (for
> example) are not resolved until runtime

Hmm. One possibility might be something like Thread.current.scope or what not.

Another possibility that might work cross VM might be to specify known
scopes, like

all_scopes_are :scope1, :scope2, :scope3

Then in each (all) currently existing calsses, alias *all* methods to
their scope equivalents, like

String#each_line => String#each_line_scope1
String#downcase => String#downcase_scope1

Then when you run into a block like

using scope1 do
''.downcase
end

You translate it (pre processor?) to

''.downcase_scope1

Might have potential.
-rp

Caleb Clausen

unread,
Jun 18, 2010, 11:16:28 AM6/18/10
to ruby-opt...@googlegroups.com
rogerdpack wrote:
> How? By remembering 'in namespace xyz, I have previously defined a go
> method' and assuming that that's the one they really want.

Ok, I get it. This is a completely static implementation of namespaces.
There would be no dynamic aspect to it at all; not like method or
constant lookup in the least. It's just a scheme for rewriting method
names. I think this could work pretty well, and should have no
performance problems. Tho adding yet another scheme for name lookup
disturbs me... the method and constant lookup rules are hard enough to
keep track of already.

> Groovy is the only language I know of that has attempted to implement
> this sort of namespacing, using a "downthread" approach, and I know
> it's caused them a lot of problems over time.

Yeah, no, that's a real bad idea, I can see. You don't want arbitrary
code that you call to be affected by the namespace of the caller.

All the attempts to add namespaces to ruby so far ahve had performance
problems. And tho I think a sufficiently sophisticated implementation
could implement namespaces with no performance drawbacks, it just hasn't
happened yet.

Caleb Clausen

unread,
Jun 18, 2010, 11:20:16 AM6/18/10
to ruby-opt...@googlegroups.com
rogerdpack wrote:
> Here's my latest:
> How? By remembering 'in namespace xyz, I have previously defined a go
> method' and assuming that that's the one they really want.

Let me expand on what (I see) Roger's idea is:

namespace Foo
class Bar
def baz
end
end
end

namespace Foo
Bar.new.baz #gets rewritten to Bar.new.bar_namespace_Foo
Bar.new.quux #does not get rewritten; no method quux in namespace Foo
end

Roger Pack

unread,
Jun 18, 2010, 12:46:40 PM6/18/10
to ruby-opt...@googlegroups.com
> namespace Foo
>  Bar.new.baz #gets rewritten to Bar.new.bar_namespace_Foo
>  Bar.new.quux #does not get rewritten; no method quux previously defined in namespace Foo
> end

Yeah that's right, for that style. except it would be
baz_namespace_Foo I suppose.

Charles Oliver Nutter

unread,
Jun 30, 2010, 6:10:29 PM6/30/10
to ruby-opt...@googlegroups.com

The important thing to remember here is that Ruby has very little
static syntax right now, so this would be somewhat unique.

Class definitions in Ruby are not really static class definitions;
they're just opening (and possibly instantiating) a Class object and
running code against it. Same goes for Modules and constants defined
anywhere; they can't be sorted out statically ahead-of-time (the best
you can do is guess based on standard patterns).

In JRuby we've had to deal with this to support compiling Ruby into
Java classes. Specifically, we have started to support translating the
"apparent" static structure of a Ruby class into the equivalent Java
class structure, without actually running the code. It's tweaky,
though, and it's easy to walk off the edge of what we can support
statically.

The namespacing stuff you're talking about would definitely be nice to
have statically supported, but statically propagating it across files
leads right back into the same problems...since Ruby files know
nothing of each other until runtime.

It's a hard problem, and part of the reason I haven't said more about
it or tried to implement more prototypes is because I haven't found a
solution that doesn't have a lot of ugly warts. I suspect Matz is in
the same boat...

- Charlie

Reply all
Reply to author
Forward
0 new messages