Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] Import keyword #327

Closed
TomasM opened this issue Apr 21, 2010 · 7 comments
Closed

[Feature request] Import keyword #327

TomasM opened this issue Apr 21, 2010 · 7 comments

Comments

@TomasM
Copy link

TomasM commented Apr 21, 2010

Hi,

I'm working on an experimental framework with coffeescript. All my classes/mixins are namespaced like this:

MyFrameworkNamespace.Mixin.Observable: {}
MyApp.Class.Controller.Index: {}

...and so on. In my code I do:

 ( ->

  # Import classes/packages into this closure
  Index: MyApp.Class.Controller.Index
  Mixin: MyFrameworkNamespace.Mixin

  c: new Index()
  $.extend(true, c, Mixin.Observable)

 )()

Now idealy i would like a smart Import keyword that would do the imports for me:

( ->

  # Loops through MyFrameworkNamespace.Mixin and imports all mixins
  import MyFrameworkNamespace.Mixin.*
  # import into variable Ind
  import MyApp.Class.Controller.Index as Ind

  c: new Ind()
  $.extend(true, c, Observable)
  
)()

The implementation for this would be very simple. What do you think about this?

EDIT:

Perhaps this would be allowed as well:

from MyNameSpace.Mixin import Observable, Enumerable as Enum, Countable
@weepy
Copy link

weepy commented Apr 21, 2010

It's been discussed before. General consensus is that it's a great feature for code compacting and DSL's etc. However, there was some disagreement about whether * would work nicely.

Essentially it would require the use of eval and it was dropped because performance concerns. Personally I think that these concerns are in the most part unfounded, since in real practical use, the eval would be called very few times and so would have a minimal impact to the running time.

@TomasM
Copy link
Author

TomasM commented Apr 21, 2010

I found the issue where this was discussed. At this point I don't understand why we need to use eval when using "*" in the import statement.

this:

import Obj.*

could translate to:

for prop of Obj
  prop: Obj[prop]

no?

@weepy
Copy link

weepy commented Apr 21, 2010

you can't do prop: ... it would just set a variable called prop

@TomasM
Copy link
Author

TomasM commented Apr 21, 2010

Dope.... :)

@StanAngeloff
Copy link
Contributor

As a proof-of-concept, I have a macros branch which defines an import macro:

from obj use method1, method2
method1()  # is actually obj.method1()

This did not make it to the core. It is also several commits behind master so it doesn't have the new fixes applied lately. I no longer support it, but feel free to adopt it for your own needs.

eval is another alternative, as long as you don't do it per request or too often as it is considerably slower.

You can also use destructuring assignments to introduce local variables:

{ method1: method1, property1: property1 }: obj

And last you could also mix in properties into the current scope (whether this is bad or not I won't discuss):

(this[prop]: prop) for prop of obj
method1()  # is obj.method1()

Jeremy: how about doing something similar to the macro version in core? The question seems to pop all too often and it should be an easy one to address.

@jashkenas
Copy link
Owner

TomasM: Quick note -- you don't need to wrap your CoffeeScript in a closure wrapper, one is already provided for you.

This feature has been discussed before, but there are a couple of reasons why we're not able to add it.

The fundamental issue is that you can't dynamically set local variables in JavaScript without resorting to with or eval, neither of which are acceptable. So, you have to follow Stan's tactics and name each property you'd like to import. But once you've done this, you've lost any gain in readability from just simply assigning the local variable yourself. So, using your example...

MyFrameworkNamespace.Mixin.Observable: {}
MyApp.Class.Controller.Index: {}

Observable: MyFrameworkNamespace.Mixin.Observable
Index: MyApp.Class.Controller.Index

As mentioned before, pattern matching can be used to extract multiple properties from an object as local variables at a stroke:

{Class: {Controller: {Index: Index, Route: Route}}}: MyApp

Really, as long as you have to name the properties, I think that local variables are the way to go. Closing as a wontfix.

@TomasM
Copy link
Author

TomasM commented Apr 21, 2010

Thank you everybody for your replies.

For me, pattern matching seems too verbose. So I will be using weepy's extension (probably will extend it to allow aliasing).

It is awsome how easy it is to extend coffeescript!

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants