[Grace-core] Modules vs Objects

Kim Bruce kim at cs.pomona.edu
Thu Aug 16 06:49:14 PDT 2012


Kim



On Aug 16, 2012, at 2:00 PM, James Noble wrote:

>> We've agreed that modules are really just objects,  but I see some differences that perhaps be implied by the use of the two different keywords.
> 
> given we have a keyword for "class", I won't object too much with a keyword or "module"
> 
>> 
>> We are working on the assumption that 
>> 
>> 	object {											(1)
>> 		def x = exp1
>> 		var y := exp2  
>> 		statement
>> 		method foo { x + y}
>> 	}
>> 
>> really means something like
>> 
>> 	object { 											(2)
>> 		def x
>> 		var y
>> 		initially { 
>> 			x = exp1
>> 			y := exp2
>> 			statement
>> 		}
>> 		method foo { x + y }
>> 	}
> 
> well I think this depends if we end up with a "one-phase" or a "two-phase" design.
> So far we're trying just one phase, which I don't think requires an initially block split out.
> The basic semantics are fine.
> 
>> The syntax (2) is not too bad for objects, but has the disadvantage that the time when the initially method is executed is not precisely specified.  This matters if exp1 or exp2 refer to variables or to mutable objects.  So I think that it's better not to just
>> re-write (1) into (2), but to allow the programmer to choose her syntax and semantics as the situation demands.
> 
> I think we do need to specify 

I had assumed that initially would be called immediately after the object expression was evaluated (or perhaps we should consider it as part of the evaluation -- hence the one-phase style design).  I don't see any advantage to deferring the execution, as you can easily define a different method if you wanted to defer it.  (I worry about timing of side effects)
> 
>> An alternative is to make 
>> 
>> 	module {											(3)
>> 		def x = exp1
>> 		var y := exp2  
>> 		statement
>> 		method foo { x + y}
>> 	}
>> 
>> mean "execute exp1, exp2 and statement now", while
>> 
>> 	object {											(4)
>> 		def x = exp1
>> 		var y := exp2  
>> 		statement
>> 		method foo { x + y}
>> 	}
>> 
>> means "execute  exp1, exp2 and statement later", i.e., (4) is implicitly re-written in to the form with initially, but (3) is not.
> 
> I can see that, but I don't think we need to go there. Yet.
> If we have too many issues with the single-phase design, then 
> we'll need to re-examine this.  

I agree.
> 
>> A file without a top-level object or module is implicitly surrounded by
>> 
>> 	def filename = module {  <file contents> }
> 
> the second half makes sense I think - 
> and is in itself a good reason for a "module" keyword
> (otherwise we can't distinguish implicit and explicit modules)
> 
> I guess one question is, is it an implicit def, or an implicit method? (like a class)

This makes sense to me as being like an object def.
> 
>> This lets 
>> 
>> 	print "hello, world"
>> 
>> remain a valid program, this time defining a module that prints "hello, world"
> 
> which we do want! 
> 
>> 
>> What about inheritance?
>> 
>> 	object {											(5)
>> 		inherits bar.new
>> 		def x = exp1
>> 		var y := exp2
>> 		statement
>> 		method foo { x + y}
>> 	}
>> 
>> really means something like
>> 
>> 	bar.new extendedByMethodsOf object {		
>> 		def x											(6)
>> 		var y
>> 		initially {
>> 			super.initially
>> 			x = exp1
>> 			y := exp2
>> 			statement
>> 		}
>> 		method foo { x + y }
>> 	}
> 
> modulo initially comments!
> 
>> What about 
>> 
>> 	module {											(7)
>> 		inherits module.new
>> 		def x = exp1
>> 		var y := exp2
>> 		statement
>> 		method foo { x + y}
>> 	}
>> 
>> Yes, I think that it does make sense to talk about inheriting from "module.new", and not from module, because this makes it clear that each use of a module creates a new set of fields.

Do we need each use to create a new set of fields?  I'm used to thinking about modules statically, as it simplifies the semantics.  If there are strong motivating examples, then I could see it.

Personally, I'm more worried about the semantics of "import" as I thought we were going to treat that as inheritance of public features of the module being imported.  I see that as the important distinction -- and normally there we do not want to create new fields.  Actually most of the time I don't see modules having public fields to export, however in those few cases where they do (e.g., a counter of some sort), it seems more likely that we would want all importers to have access to the same fields rather than new copies.
> 
> (and is an independent object).
> That also makes sense but then shouldn't modules be methods/classes?
> 
>> inherits would still have the extendedByMethodsOf semantics.  Do you see a need for the deferred execution semantics when one module inherits from another?
> 
> at this stage, we're trying *without* the deferred semantics.
> The more I think about it (i.e. without deferral), the more I like it - which doesn't always happen,
> and nor does it mean that's the way we should go in the end.
> 
> 
> there's certainly stuff here to talk through tomorrow.

Sorry I'll miss the discussion this afternoon.  [Strangely it's already nearly 5 p.m. here while Andrew should just about be waking up, and it is the middle of the night for James.]
> 
> James
> _______________________________________________
> Grace-core mailing list
> Grace-core at cecs.pdx.edu
> https://mailhost.cecs.pdx.edu/mailman/listinfo/grace-core



More information about the Grace-core mailing list