tag:blogger.com,1999:blog-2447174102813539049.post1844927628139698674..comments2024-03-29T03:43:02.688-07:00Comments on Room 101: A Ban on ImportsGilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.comBlogger29125tag:blogger.com,1999:blog-2447174102813539049.post-20969592673089134062018-06-26T08:57:33.811-07:002018-06-26T08:57:33.811-07:00thank youthank youKante Luishttps://www.blogger.com/profile/13941884064793276353noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-26426210096199950772017-05-14T11:40:08.688-07:002017-05-14T11:40:08.688-07:00Hi Koosha,
Marketing was never my strong suit, so...Hi Koosha,<br /><br />Marketing was never my strong suit, so sure, there are doubtless other ways to make this point. I read your post, and it is certainly an example of the sort of issue that comes up. But for me, it's too wrapped up in specifics. That does make it easier to communicate to people familiar with those specifics - but as the thread that follows shows, it also gets people to focus on any number of other things (implicits, dynamic scoping etc.). <br /><br />Anyway, thanks for reading and commenting on the post!<br /><br /><br />Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-18271149912760047602017-05-14T11:13:48.336-07:002017-05-14T11:13:48.336-07:00I wonder how much more success you'd have in e...I wonder how much more success you'd have in expressing your idea, if you used the word "context" rather than import? Reading the comments I can see many are confused. I know I am!<br /><br />Just when you said global/static namespcae that was an aha! moment (hey, "namespcae" is good too!).<br /><br />I took a shot: https://www.reddit.com/r/ProgrammingLanguages/comments/6970up/how_about_baking_the_context_management_into_the/<br /><br />Sorry for my clumsy boring writing there. Kooshahttps://www.blogger.com/profile/18371931300494461361noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-11451715713999059472011-01-12T03:03:38.263-08:002011-01-12T03:03:38.263-08:00I like your post, though it does not say something...I like your post, though it does not say something completely new. As you suggested by yourself, parametrized modules may be implemented in a programming language that is able to couple code with mutable data (OOP's object) or immutable data (closure). Even in C it is implemented, but a programmer must pass code and data as distinct arguments.<br /><br />The reason everyone uses non-parametrized modules is that they feel no need of it 99%, moreover there is an additional work. If a programmer is obliged to give the library B as the argument to the library A <strong>everywhere</strong>, instead of linking A and B by default, this is a waste of time. 1% that needs to parametrize, can patch the library A, without creating inconvenience for masses.<br /><br />Non-parametrized modules are not "evil". That sounds too perky.beroalhttps://www.blogger.com/profile/13229768366613602827noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-41213466741273489362009-12-26T08:46:17.987-08:002009-12-26T08:46:17.987-08:00@Mooonbiter:
one more thing; the previous comment...@Mooonbiter:<br /><br />one more thing; the previous comment about global namespaces for types being necessary mostly pertains to purely nominal type systems. <br /><br />It may be possible to have a structural system instead - though making it usable is a challenge, I think. Most likely we end up with a mix. Now all real nominal type systems will have a bit of structural typing in them, but here we may need more.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-67147065331462040682009-12-26T08:26:17.575-08:002009-12-26T08:26:17.575-08:00@Moonbiter: Alas, you cannot avoid a global namesp...@Moonbiter: Alas, you cannot avoid a global namespace if you want mandatory static typechecking.<br /><br />However, with optional/pluggable types, a typechecker is just one more tool, and not part of the language. In that scenario, the typechecker would have a namespace including all types it knows about, and it would interpret type annotations (which are just metadata in this case) wrt that namespace.<br /><br />Hence, the language has no global namespace, but tools may do so in appropriate contexts.<br /><br />As for very common names - well, we do assume that a few things are inherited from Object, such as the literal classes like String, Boolean etc., and Object itself. But you can override these. All of which sort off its with your comment on context.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-72536248518837687802009-12-26T08:01:11.917-08:002009-12-26T08:01:11.917-08:00Maybe I misunderstand but...
Are yoy saying that y...Maybe I misunderstand but...<br />Are yoy saying that you don't want a global namespace for types?<br />How about primitive types or type VERY common? They would be treated in a different way?<br />Is it a way to ehnance the importance of the context around the code? In some way it seems to me that improving the modularity has this some effect: everyline depends strictly on the context instead of using global (absolute) informations.Federico Tomassettihttps://www.blogger.com/profile/06802018713038173830noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-58224143001996701282009-10-02T04:37:05.310-07:002009-10-02T04:37:05.310-07:00fsi:
You make an excellent point.
How to typeche...fsi:<br /><br />You make an excellent point.<br /><br />How to typecheck this scheme is an open question. Nominal type systems have a global flavor to them that undermines modularity. Perhaps structural typing is part of the answer - but I know from experience how problematic that can be as well.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-59646398709464130092009-10-02T03:01:22.200-07:002009-10-02T03:01:22.200-07:00Do we need a structural type system to achieve wha...Do we need a structural type system to achieve what you are talking about? E.g.<br /><br />module SoundSystem(MP3Player) { <br /><br />player = MP3Player(self);<br /><br />... <br /><br />}<br /><br />where we parameterize with an MP3player. If MP3Player is an interface with a name defined in some module, we will come to depend on this module and loose modularity of the Soundsystem module?fslhttps://www.blogger.com/profile/02426442336414052477noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-16899576205371704322009-07-16T12:31:01.488-07:002009-07-16T12:31:01.488-07:00Tom,
thanks for your comment, it started to make ...Tom,<br /><br />thanks for your comment, it started to make a lot more sense. I think that the confusion really came from the fact that I see Imports as linking and namespacing issue.<br /><br />But as described you are right. I work in C# a lot and it kills me that you have to explicitly declare something virtual.<br /><br />allow me to explain<br /><br />Java<br /><br />public void someMethod()<br /><br />=<br /><br />C#<br /><br />public virtual void someMethod()<br /><br /><br />and<br /><br />c#<br />public void someMethod()<br /><br />=<br />Java<br />public final void someMethod()<br /><br /><br /><br />so, of course almost everyone always do the easier version.<br />public void someMethod<br /><br />and in C# that means that someone who 'wasn't think about you in the first place' needs to have 'thought about you' for you to change things later.<br /><br /><br />if they did, then you can override the method and add your hack. I believe what you are .... rediscribing ... is that it would be nice to be able to override the construction of the object as well....<br /><br /><br />which I quite agree on.<br /><br />of course, this all means there shouldn't be a ban on import, there should be a ban on 'new'. after all you still want String to implement everything you think it should, and you have to describe that somewhere.Llewellyn Falcohttps://www.blogger.com/profile/11668997629228826023noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-55591151548526103902009-07-13T09:19:01.713-07:002009-07-13T09:19:01.713-07:00"The only real need use for a global namespac..."The only real need use for a global namespace is when configuring modules, and this should be done externally, and via tools."<br /><br />Why is this true?<br /><br />I do agree that it makes sense to isolate configuration as much as possible (and probably make it something done at runtime). What I don't see is why it has to be either external to the implemenation langauge or confined to a tool.Mikehttps://www.blogger.com/profile/03946106205567009667noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-10068242028922986472009-07-12T17:05:57.043-07:002009-07-12T17:05:57.043-07:00milessabin, why do you need the '=>' in...milessabin, why do you need the '=>' in class SoundSystem(p : => Player) extends Dock ?<br /><br />(sorry for the off topic question..)fslhttps://www.blogger.com/profile/02426442336414052477noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-37151804365110977862009-07-12T17:04:20.371-07:002009-07-12T17:04:20.371-07:00Gilad,
I am sure you've come across scala'...Gilad,<br /><br />I am sure you've come across scala's anonymous type declarations and type aliases. These two features allow one to write:<br /><br />def printName(o: { def getName: String }) = Console.println(o.getName)<br /><br />or<br /><br />type HasName = { def getName: String }<br /><br />def printName(o: HasName) = Console.println(o.getName)<br /><br />I think this is a neat way to implement what you've written about. As for eliminating the global namespace, in my opinion it's more impractical than helpful.Unknownhttps://www.blogger.com/profile/02886285137294136095noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-79413965919746363412009-07-12T14:45:51.542-07:002009-07-12T14:45:51.542-07:00Llewellyn,
What Gilad describes is a better solut...Llewellyn,<br /><br />What Gilad describes is a better solution to the interfaces/dependency injection framework solution which Java programmers use to work around the problem that imports are bad.<br /><br />'import' doesn't 'allow easy use of namespacing' -- it allows you to do *one* thing -- refer to a point in a global namespace.<br /><br />Of course you need a way to refer to classes you depend on, but wouldn't it be nice, for instance, if you could (say) take an existing library and make it use your implementation of String (with performance characteristics which better suit your use case, perhaps) without modifying and recompiling the library from source?Tom Davieshttps://www.blogger.com/profile/13542052736852306130noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-60960768968137743232009-07-12T09:31:41.575-07:002009-07-12T09:31:41.575-07:00... This word import. I do not think it means wha...... This word import. I do not think it means what you think it means...<br /><br />I'm in agreement here. To me, as a java programmer, import does 2 things.<br /><br />1. allows a dependent piece of code to be loaded and available at run time.<br /><br /> this is curial to file modularity <br /><br />2. allows for easy use of name spacing. <br /> <br /> this is good in sooo many ways.<br /><br /><br />now, even if you removed #2 made all files in the default namespace there is STILL an implied:<br />import {currentpackage};<br />import java.lang.*;<br /><br />which is needed to have classes is separate files. to avoid that you could completely ban imports if you wrote everything in one file, but then you can't use ANY of the java.** classes... including Object<br />so you can't even create a class.<br /><br /><br />what you are describing seems to have much more to with Dependency Injection and Interfaces than imports.Llewellyn Falcohttps://www.blogger.com/profile/11668997629228826023noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-78340143659508022972009-07-01T21:56:30.855-07:002009-07-01T21:56:30.855-07:00Kris:
Missed your comment earlier. Ihab and I hav...Kris:<br /><br />Missed your comment earlier. Ihab and I have been in touch on occasion, and I sent him some comments.<br /><br />Eliot:<br /><br />Of course it's non-trivial. Why do youthink that part of Newspeak is still missing? But a clever guy should be able to sort it out.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-60009001315670236612009-07-01T18:38:24.763-07:002009-07-01T18:38:24.763-07:00If this notation is unfamiliar, please brush up on...<i>If this notation is unfamiliar, please brush up on your functional programming skills before you become unemployable.</i><br /><br />ROTFL!<br /><br />But Gilad, isn't this letrec non-trivial to implement if actual parameters are used as classes that are subclassed within a module? Are you proposing open-season on mutually-recursive parameterisation or are you proposing to restrict it in some way?Unknownhttps://www.blogger.com/profile/00739877143913055927noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-20284371983287950682009-07-01T18:37:11.720-07:002009-07-01T18:37:11.720-07:00This comment has been removed by the author.Unknownhttps://www.blogger.com/profile/00739877143913055927noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-4463517704344072462009-07-01T17:40:27.812-07:002009-07-01T17:40:27.812-07:00James,
It is true that a global namespace for val...James,<br /><br />It is true that a global namespace for values (be they classes or functions modules or even worse, stateful objects) is a problem. Imports are a problem because they inherently tie modules to such a global namespace.<br /><br />In the Modula family, an import is necessary, not just an typedef/alias sort of thing as in Java. It still brings all the problems I mention, because it hardwires dependencies into modules. So import is more than an enabler - it is a problem in and of itself.<br /><br />In Java, there is a global namespace freely accessible via fully qualified names, and this makes matters worse. But even FQNs were eliminated, import would still be a problem.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-41824041723228277562009-07-01T08:33:57.285-07:002009-07-01T08:33:57.285-07:00Gilad,
It's clear that the real problem you a...Gilad,<br /><br />It's clear that the real problem you are discussing here isn't imports but global resources. Removing the import keyword from Haskell and Java would just make the programs more verbose not more modular. <br /><br />Perhaps you're arguing that import is an "enabler" - it make name spacing practical and name spacing gives a language designer and a language user an illusion of modularity rather than the real deal.James Iryhttps://www.blogger.com/profile/02835376424060382389noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-13897520827967372492009-07-01T06:56:01.419-07:002009-07-01T06:56:01.419-07:00Neil:
"aren't you just embedding the con...Neil:<br /><br />"aren't you just embedding the concepts of DI into your language and VM"<br /><br />FWIW, read:<br /><br />http://gbracha.blogspot.com/2007/12/some-months-ago-i-wrote-couple-of-posts.html<br /><br />Clean modularity constructs that subsume DI are neither trivial (as you say "just") nor are they derived from DI. <br /><br />DI is a very convoluted way of working around basic flaws in the programming language. <br /><br />It may be your only option using a mainstream language. The point is one can do better. <br /><br />As for whether this is normal practice:<br />A. I wasn't referring to DI. DI requires a lot of extra machinery that wasn't implied in the discussion in question.<br /><br />B. DI isn't universal practice for good reason. There are vast amounts of code out there that do not use these mechanisms - partly because they are so complex. Can you imagine teaching DI or OSGi in an first year programming class? <br /><br />The old post about DI, and several others on this blog, attempt to show better ways of dealing with the issue of modularity. I keep at it precisely because it seems so hard for people to grasp.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-59961672920123945822009-07-01T01:53:30.640-07:002009-07-01T01:53:30.640-07:00FWIW recursive modules of this form are expressibl...FWIW recursive modules of this form are expressible in Scala,<br /><br />object Modules {<br /> trait Dock {<br /> def name : String<br /> def player : Player<br /> }<br /><br /> trait Player {<br /> def name : String<br /> def dock : Dock<br /><br /> def play = println("Player "+name+" playing in "+dock.name)<br /> }<br /><br /> class SoundSystem(p : => Player) extends Dock {<br /> override val name = "Basic Dock"<br /> override def player = p<br /> }<br /><br /> class IPod(d : => Dock) extends Player {<br /> override val name = "IPod"<br /> override def dock = d<br /> }<br /><br /> class Zune(d : => Dock) extends Player {<br /> override val name = "Zune"<br /> override def dock = d<br /> }<br /><br /> object Configuration1 {<br /> object dock extends SoundSystem(player)<br /> object player extends IPod(dock)<br /> }<br /><br /> object Configuration2 {<br /> object dock extends SoundSystem(player)<br /> object player extends Zune(dock)<br /> }<br /><br /> def main(args : Array[String]) {<br /> Configuration1.player.play<br /> Configuration2.player.play<br /> }<br />}<br /><br />Yielding,<br /><br />miles@lewis:~$ scalac Modules.scala <br />miles@lewis:~$ scala Modules<br />Player IPod playing in Basic Dock<br />Player Zune playing in Basic DockAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-57229088065471186622009-07-01T00:29:58.101-07:002009-07-01T00:29:58.101-07:00"Suppose your modules are Java packages that ..."Suppose your modules are Java packages that never, ever import classes (or statics etc.) - only interfaces. To configure an application you define a main package and import the various pieces you need, and tie them together. This is what you are suggesting - clearly not normal practice. Nor is it feasible with existing libraries."<br /><br />I disagree, this is very normal practice. It is exactly the approach taken when one is using a dependency injection framework, or OSGi services.<br /><br />You said that DI isn't needed when using real modularity. Aren't you just embedding the concepts of DI into your language and VM?Neil Bartletthttps://www.blogger.com/profile/08588098030811273044noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-62370589364711378602009-06-30T22:16:21.344-07:002009-06-30T22:16:21.344-07:00To a degree, the idea your proposing here is like ...To a degree, the idea your proposing here is like "dependency injection". Ihab Awad from Google Caja and I have designed a system that permits module systems to be instantiated with particular modules using particular names in the module name space or in a "system" free variable name space available in Server Side JavaScript modules, particularly with Tom Robinson's Narwhal. I invite you to drop in for a program some time.<br /><br />http://narwhaljs.orgKris Kowalhttps://www.blogger.com/profile/01443956999129365941noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-65849237829283785032009-06-30T21:24:33.756-07:002009-06-30T21:24:33.756-07:00Sam:
The meaning of import in Java is given by th...Sam:<br /><br />The meaning of import in Java is given by the Java Language Specification, of which I am an author. So I probably do know what it means. <br /><br />Your point, presumably, is that in Java one can always access things via fully qualified names. Ergo, there is a global namespace. My point, in turn, is that import injects a global namespace into modules - even if it is defined "properly", as in Modula dialects. <br /><br />The only real need use for a global namespace is when configuring modules, and this should be done externally, and via tools.<br /><br />Hence no import. And, yes, of course, no global namespace and no fully qualified names.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.com