Today a Redline developer pointed out that the following code didn't function as he expected:
At first glance I thought that is was odd for the Greeting class to not be found when the 'greet' message was sent. Then I looked closer and realized that this may not be an error but a question of scope. You see 'import:' is expanded in the preprocessor to 'self import:' which means it is being sent to the self at the scope of the call, in the above case the metaclass that represents the GreetingCaller source file and not the GreetingCaller class itself. What I have not tried is this:
Which should/would import Greeting into the proper scope. Before I go down the track of and changes I wanted to ask your opinion. Do you want the top level 'import:' to be visible to the rest of the file? (Note that behind the scenes this may equate to a message to the enclosing file metaclass to get its imports. ie: its not a special 'hack'.) What do you think? |
I'm a little torn on this one.
The notion of needing to import a Smalltalk class seems very unlike Smalltalk to me. I think of the import should only be necessary for the Java interop, basically just like java_import in JRuby. Maybe we should do the Java imports like that?
In the case where I did an import at the top level, like the code you mention first, I would expect that import statement to be scoped available to everything else within that file.
On Oct 16, 2012, at 12:56 AM, jamesl <[hidden email]>
wrote:
Today a Redline developer pointed out that the following code didn't function as he expected: |
Thanks for the response.
Imports appear foreign in Smalltalk because typically you file-in everything into a global space. This has its advantages and disadvantage. Regardless of the Java interop there would still be an 'import:' in Redline because is facilitates sharing of packages and the handling of name collisions 'import:as:'. I'll go with what I think is the principle of least amazement and ensure that 'import:' at the top means those imports are available to the rest of the file. :) On Wed, Oct 17, 2012 at 3:31 PM, Robert Roland <[hidden email]> wrote:
|
In reply to this post by James Ladd
Later today I will post the implementation for this. Then the code below will work as expected. For those wanting technical details - the eigen class that sends the messages contained within a .st source file also contains the imports that are done at the outer scope. Now, the eigen class is kept and during subclass creation the subclass looks up its eigen class to grab its imports. On Tuesday, October 16, 2012 6:56:26 PM UTC+11, jamesl wrote: Today a Redline developer pointed out that the following code didn't function as he expected: |
Pushed to master.
import: 'package'. not works as you would expect and the bug shown by another Redline developer is no longer and issue. On Sunday, 28 October 2012 09:00:32 UTC+11, jamesl wrote:
|
Of course I meant NOW works rather than not!
On Sun, Oct 28, 2012 at 2:11 PM, jamesl <[hidden email]> wrote: Pushed to master. |
Aussies do everything backwards. This bug and this thread are proof of that.
I suspect that means, where I call you my friend. You call me your enemy.
On Sat, Oct 27, 2012 at 11:18 PM, James Ladd <[hidden email]> wrote: Of course I meant NOW works rather than not! |
Always my friend Sent from Hyperspace.
|
In reply to this post by James Ladd
I realize I am late to this thread as I joined the ML after it was posted, but I have some thoughts on this.
I spent a good chunk of some evenings over the last month or so reading some amazing resources on Smalltalk, its philosophy and origins, and the path of its construction: Design Principles Behind Smalltalk: http://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html Squeak mailing list thread discussing Smalltalk vs Sun's early HotSpot VM, with Alan Kay himself chiming in: http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/016743.html Alan Kay's (often referenced) response to this thread: http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html And this precious gem of Alan Kay's summary of Smalltalk's origins: http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html After reading these materials, I believe Redline's independent/floating 'import: 'binary message feels very much out of place in a Smalltalk environment, even, dare I say, violating Smalltalk principles entirely (and this is coming from a Java programmer who has never programmed in Smalltalk professionally) I saw the usage/syntax months ago when learning about Redline, and as a Java programmer, thought nothing of it. But now it feels very weird: As Allan Kay carefully clarified in the ML response, Smalltalk at its heart is about messaging between self-contained building blocks (components). Messages from one object are sent to another, i.e. there is always clearly a sender and a receiver, and much of the Smalltalk's beauty is that this fundamental principle holds even at the meta programming level: Classes are themselves first-class objects that also support messaging and can be both manipulated and introspected. To this end, having an 'import:' binary message at the top of a Redline smalltalk file obscures this fundamental concept: who is the receiver of the 'import:' message? Is it the Class (that hasn't even been defined yet)? Is it a system table somewhere? An object message receiver is always clearly known in traditional Smalltalk environments, as this concept is a fundamental building block of the language. Instead, I think your second example is much more in-line with Smalltalk's principles, especially that of extending behavior and growing the system for particular needs (but while retaining these primitive-and-immutable building block philosophies):
So while 'import:' at the top of the file is more aligned with Java programmer expectations, I feel it is a detriment: it alleviates the programmer from truly thinking in the 'Smalltalk Way', which can only hurt them. It also might hurt Redline over time: where is it ok to (apparently) violate these principles? Should some other paradigms be invented or fundamental concessions made to make things easier for Java programmers? I personally believe making special concessions (at the language level only) is a very dangerous road and should be avoided at all costs. Of course, because Redline runs on the JVM and is not the entire Smalltalk runtime world, runtime/infrastructural concessions and adjustments will need to be made. But I don't think this should propagate at the _language_ level at all. Something like the following might work as well: Object subclass: #MySubclassName instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'com.foo.whatever' imports: 'com.foo.Bar, java.io.InputStream, ...' Having an 'import:' as a binary message on the class itself makes quite a bit of sense too: Classes are themselves first-class mutable objects in Smalltalk, and so adding an 'import:' after Class construction could be allowed (assuming this makes sense for the Redline compiler, depending on how Java interop works). This is in the spirit of Smalltalk's extensibility principles (keep the primitives immutable, and allow customization beyond that to your heart's content). Please forgive the long-winded post, and I respectfully submit my intention was to not step on anyones toes or feelings. I just feel this is extremely important, as it could potentially set precedents for other approaches in Redline. Best regards, Les
|
Hi Les,
Great post. 'import:' at the top of the file is short hand for 'self import:'. So these statements are equivalent: import: 'com.mydomain.MyClass'. self import: 'com.mydomain.MyClass'. We (core team) debated about dropping the self. In this context the self is the Eigen class that represents the file, because while it isn't typical to do so you can define multiple classes in the one file. So these imports are for the file scope. You showed the longer keyword selector for creating a class: Object subclass: #MySubclassName ... And this works in Redline too, IN FACT the '<' short hand you see in the Redline sources sends a 'subclass:instanceVariableNames:classVariableNames:.....' message. See Class.st. Cutting down typing helps remove a barrier to entry so we have chosen to use the short hand. What Redline doesn't do currently is support the 'subclass:' selector with the 'import:' but this can be easily added. This is part of the Smalltalk ethos. With the 'import:' with out a self aside, Redline has and will continue to be very strict about always sending message to achieve results. Everything is a message to a receiver - and I do appreciate that in this case hiding 'self' was probably a mistake. I'll bring it up again with the core team. Really appreciate your posts and involvement - Please keep it up. - James. On Sun, Dec 9, 2012 at 9:00 AM, Les Hazlewood <[hidden email]> wrote: I realize I am late to this thread as I joined the ML after it was posted, but I have some thoughts on this. |
> 'import:' at the top of the file is short hand for 'self import:'.
I assumed that it was indeed a message to _something_, but I didn't know what that something was, and I guess therein lies my concern: This seems to me to conflict with Smalltalk's principles to have 'short hand' for _anything_ at the language level. You have six reserved keywords and a core memory/messaging kernel and everything else is built up from there. If I define a class in Pharo for example, there is nothing hidden or implicit when I define a class: everything I can do is entirely based on what messages I can send to the parent class. There is no shorthand - there are only messages I can send and that's it. Alan Kay and Dan Ingalls are adamant that VM implementation details should never be exposed to the programmer. That an Eigenclass (or Metaclass) exists that represents a file, to me, is an implementation detail of Redline and should absolutely not be exposed to the programmer. Instead, standard messaging semantics with existing Classes should be used (IMNSHO). Again, I can be way off base here and be totally wrong, but the more 'short hand' and 'convenience' mechanisms you have at the language level always seem to cause problems over time. So many languages downstream of Smalltalk seem to exhibit problems because of these things. And I hope I'm not perceived as meddlesome here - I love the concept of Redline and I'm super grateful to James (and others) that work on the project. Its just that as someone who sees so much promise in Smalltalk (and Redline), I'd like to see absolute laser focus in retaining the purity of Smalltalk as I believe that this is the most important reason why it is one of the most powerful (and unburdened) languages that has ever been created. I wouldn't want to see Redline diverge from this purity in any way not absolutely mandatory. Please keep up the great work - I'm excited to see Redline progress! Best, Les |
Additionally, I would argue imports are not relevant to the Eigenclass
at all - they're only relevant to the Class being defined, and as such, should be encapsulated/represented by that Class only. It's the same reason why instance and class variable names in Smalltalk are defined in the Class subclass message selector and not above it in source code. They are only relevant to the implementation details to the Class being defined. Imports are no different IMO. I hope that helps! Best, Les |
In reply to this post by Les Hazlewood
I'll change all 'import:' selectors to 'self import:' as a first step given your feedback - if you found it confusing then others may to and that we don't want. Will post change ASAP
One thing to keep in mind is that you can use Smalltalk to write scripts not just classes and in terms of that 'self import:' makes sense - at least I think so. Will bring it up with core team - James Sent from Hyperspace. On 09/12/2012, at 9:56 AM, Les Hazlewood <[hidden email]> wrote: >> 'import:' at the top of the file is short hand for 'self import:'. > > I assumed that it was indeed a message to _something_, but I didn't > know what that something was, and I guess therein lies my concern: > > This seems to me to conflict with Smalltalk's principles to have > 'short hand' for _anything_ at the language level. You have six > reserved keywords and a core memory/messaging kernel and everything > else is built up from there. > > If I define a class in Pharo for example, there is nothing hidden or > implicit when I define a class: everything I can do is entirely based > on what messages I can send to the parent class. There is no > shorthand - there are only messages I can send and that's it. > > Alan Kay and Dan Ingalls are adamant that VM implementation details > should never be exposed to the programmer. That an Eigenclass (or > Metaclass) exists that represents a file, to me, is an implementation > detail of Redline and should absolutely not be exposed to the > programmer. Instead, standard messaging semantics with existing > Classes should be used (IMNSHO). > > Again, I can be way off base here and be totally wrong, but the more > 'short hand' and 'convenience' mechanisms you have at the language > level always seem to cause problems over time. So many languages > downstream of Smalltalk seem to exhibit problems because of these > things. > > And I hope I'm not perceived as meddlesome here - I love the concept > of Redline and I'm super grateful to James (and others) that work on > the project. Its just that as someone who sees so much promise in > Smalltalk (and Redline), I'd like to see absolute laser focus in > retaining the purity of Smalltalk as I believe that this is the most > important reason why it is one of the most powerful (and unburdened) > languages that has ever been created. I wouldn't want to see Redline > diverge from this purity in any way not absolutely mandatory. > > Please keep up the great work - I'm excited to see Redline progress! > > Best, > > Les |
In reply to this post by Les Hazlewood
See my other response where I mention scripts - will also look into changing examples to use 'import:' as part of subclass creation - stand by.
Sent from Hyperspace. On 09/12/2012, at 10:03 AM, Les Hazlewood <[hidden email]> wrote: > Additionally, I would argue imports are not relevant to the Eigenclass > at all - they're only relevant to the Class being defined, and as > such, should be encapsulated/represented by that Class only. > > It's the same reason why instance and class variable names in > Smalltalk are defined in the Class subclass message selector and not > above it in source code. They are only relevant to the implementation > details to the Class being defined. Imports are no different IMO. > > I hope that helps! > > Best, > > Les |
Changed the main repo examples to use 'self import:' rather than the
import without a receiver. This should reduce possible confusion. In the context of a file 'self import:' is sending the 'import:' selector to the file asking it to bring into scope the names classes so they can be referenced by the expressions that follow, those expressions may or may not define classes. On Sun, Dec 9, 2012 at 12:56 PM, James Ladd <[hidden email]> wrote: See my other response where I mention scripts - will also look into changing examples to use 'import:' as part of subclass creation - stand by. |
On 08/12/2012 9:32 PM, James Ladd wrote:
> Changed the main repo examples to use 'self import:' rather than the > import without a receiver. This should reduce possible confusion. > > In the context of a file 'self import:' is sending the 'import:' > selector to the > file asking it to bring into scope the names classes so they can be > referenced > by the expressions that follow, those expressions may or may not define > classes. If I might add my 2 cents, I think all this "import" thing is going in the wrong direction. Being a pragmatist, I'd rather have a Redline Smalltalk that feels and behave like... Smalltalk. Why couldn't we defer class definition/reificaton instead of using "tricks" like self import: Whatever ? Redline could just mimic Smalltalk and put unknown definitions into an Undeclared dictionary upon loading until the real class is loaded and compiled with all its methods... Am I missing something ? |
On Dec 8, 2012, at 6:40 PM, Benoit St-Jean wrote:
> On 08/12/2012 9:32 PM, James Ladd wrote: >> Changed the main repo examples to use 'self import:' rather than the >> import without a receiver. This should reduce possible confusion. >> >> In the context of a file 'self import:' is sending the 'import:' selector to the >> file asking it to bring into scope the names classes so they can be referenced >> by the expressions that follow, those expressions may or may not define >> classes. > > If I might add my 2 cents, I think all this "import" thing is going in the wrong direction. Being a pragmatist, I'd rather have a Redline Smalltalk that feels and behave like... Smalltalk. Why couldn't we defer class definition/reificaton instead of using "tricks" like self import: Whatever ? Redline could just mimic Smalltalk and put unknown definitions into an Undeclared dictionary upon loading until the real class is loaded and compiled with all its methods... > > Am I missing something ? James can answer better, but I think that the import is a crutch for now while Redline is still in early development. Pat |
In reply to this post by Benoit St-Jean-4
When Redline compiles the statements in a file it merely turns them into executable
message sends and it doesn't actually know what one message send is doing from another. The statement 'self import: package' sends a message to the script (self) - think Transcript - telling it to import names into the current scope. Why is this different to something like Squeak or Pharo? Because they include everything into memory from a single file (the IMAGE). Redline doesn't have an image and will therefore need to know where to get the files from. These can be over the network or locally and requested at Runtime. Hence we need to 'import:' functionality. Why is the 'import:' not part of the class construction? Well it can be and nothing stops anyone from following a subclass creation message with a ';' cascade that then asks the class to import a class. However, keep in mind the situation where you need to do this: SomeClass subclass: #OtherClass AND SomeClass is not in scope because it has not been imported yet. Who do you send the message to in that case? - James. |
On 08/12/2012 9:48 PM, James Ladd wrote:
When Redline compiles the statements in a file it merely turns them into executable So code could come from files, url, anything? Then why don't we just have base classes (locally) and mimic a FileIn operation that would import code (and keep a reference to its location) and keep a copy locally. The files on local hard disk would then constitute the image. Wouldn't that be more "Smalltalkish" ?!?! -- ----------------- Benoit St-Jean Yahoo! Messenger: bstjean A standpoint is an intellectual horizon of radius zero. (Albert Einstein) |
I think that IS what we have, and that now we are discussing if the message selector is 'fileIn:' or
'import:' - I have chosen import because FileIn has be name 'File' and the thing being imported may not be a file, and where is it being Filed? We also have to handle the case where we need to import a class and then alias it as another name so we can use it - this helps overcome namespace collisions. The selector in question here is: import: as: Lets say there is already a Window class and I want to make use of it in my own code. How do I distinguish between once name and another - given that for compatibility reasons we don't currently allow fully qualified class names. ie: you cant do this - w := com.domain.Window new. The way to get around this is to use 'import:as:' self import: 'com.domain.Window' as: 'ExternalWindow'. w := ExternalWindow new. On Sun, Dec 9, 2012 at 1:55 PM, Benoit St-Jean <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |