[Grace-core] Importing resources

Marco Servetto marco.servetto at gmail.com
Thu Feb 6 22:08:23 PST 2014


I really like this proposal!
42 can not be as clean. the best I could get is MyImage:
Resource"myImage.png", and to u se the image one would ne ed to write
MyImage()

On 7 February 2014 12:10, Michael Homer <mwh at ecs.vuw.ac.nz> wrote:
> Hi,
> I dug up my sketch from the last time I thought about this. This was
> about as far as I got - there are some significant open questions that
> linger. There is a three-sentence summary right at the end. Here's the
> teaser: what if
>   import "logo.png" as logo : Image
>   import "about.txt" as aboutText : String
> just did the right thing?
>
> At the moment, you can import a Grace module with:
>   import "path/to/module" as mod
> to get a Grace object containing the top-level definitions from the
> given module, bound to the name "mod". Given that this is "just" an
> object, there's no reason it necessarily has to arise from Grace
> source code. We already have the ability to import native code
> conforming to the appropriate ABI, for example, which is how the "gtk"
> and "dom" modules work.
>
> One thing that would be interesting is if we could access other
> resources through the same mechanism. In Grace, everything is an
> object, so the representation of, say, an image, is naturally an
> object. Because the implementation of objects is opaque, we don't know
> what's in it or where it came from unless we wrote the object
> constructor ourselves. We could access these through the import
> mechanism.
>
> The modules paper gestures at this a little, under the heading of
> "External Data", but doesn't provide a particularly concrete
> description of anything and points both at F# type providers and
> importing text files with a particular prefix. An earlier version had
> some more detail, and I implemented an "import hook" mechanism to deal
> with that, but there were some practical problems wedging it in.
> Import hooks relied on a prefix that took them outside the ordinary
> import system, with "file://" used in the example but others envisaged
> as well. Type providers remain an interesting area but I don't propose
> to address them here.
>
> Here is the system that I am semi-proposing. All existing working
> import statements continue to have their current meaning. We instate a
> syntactic restriction on the import paths of Grace modules: the given
> import path may not contain a "." character (U+002e FULL STOP) after
> the final occurrence of "/" (U+002f SOLIDUS). Remember that, when
> importing a module, we do not include ".grace" in the name; this will
> only prohibit importing from a path implying a source file name like
> "foo.bar.grace".
>
> If such a character does appear, this import statement is a "resource
> import". A resource import still binds the given name to an object
> identified by the given import path; the difference is that the
> meaning of the import path may be interpreted by other code.
>
> What code is that? It is determined by the part of the name following
> the "." - in essence, the file extension. If I write this in my
> program:
>   import "my/tool/logo.png" as logo
> then the "png" import handler is handed the path "my/tool/logo.png",
> as a string, and returns an object to be bound to "logo". This object
> can be anything the handler likes, but is probably some representation
> of an image in this case. If I instead have:
>   import "my/tool/licence.txt" as licence
> then licence is likely to be a String.
>
> How are these extensions mapped to handlers? Probably, a per-program
> registry is defined, and user code can add entries to it (but see
> below for potential issues). If I am using the "gtk" module, for
> example, it may extend the registry with an entry mapping the "png"
> extension to something creating a GTK+ image object. Other modules may
> provide their own definitions. The system may predefine some handlers,
> like "txt" as a String mapping, but these could be overridden.
>
> What if we assume a Smalltalk-style interface, with a closed world,
> and no "files"? Again, as the interpretation of the path is defined in
> user code, it can be mapped according to whatever approach makes sense
> in that system. The extensions are simply to identify an
> interpretation in that case.
>
> What advantages does this have? We can access resources, like images,
> documentation, or sound files through a single consistent interface.
> It fits entirely within the existing semantics of the language. It
> also provides a logical location to store relevant resources adjacent
> to the code that requires them, and even to distribute them in the
> same way as code (perhaps through the package manager discussed
> today). The meaning of 'import "logo.png" as logo' is likely to be
> clear to the reader, even if they are unfamiliar with other code. The
> disadvantage is that there is an added point of complexity in the
> import system, and that a class of otherwise-valid filenames is
> excluded from use as a module name.
>
> There are some lingering issues with this:
> 1) This global registry may be subject to conflict if two different
> third-party modules both want to hook onto the same extension. Some
> way of resolving an ambiguity may be required.
> 2) A per-module registry might be required rather than per-program.
> This is related to the previous issue and may resolve some of it.
> 3) Typing: given the runtime registry described here, assigning a
> static type to the imported module is difficult and may be impossible
> sometimes. We could require an explicit type annotation to be provided
> in these cases, or use some sort of statically-determined registry
> instead. In many ways gradual typing comes to the rescue here.
> 4) The registry introduces an ordering dependency for imports. If I
> want to import a PNG resource as a GTK+ image, I need to have imported
> the GTK+ module first. This may lead to errors sometimes. Note that
> import order is already semantically important for ordinary modules.
> 5) Sensible interpretations may not map cleanly onto conventional file
> extensions. Note that it is not necessarily the case that the "path"
> given corresponds to an actual path - it simply identifies an
> interpreter that can process the string - so a "false" extension could
> be defined when required.
> 6) This system describes an essentially dynamic lookup process. In
> Minigrace, this would map onto the same sort of lookup as happens for
> dynamic modules now. Potentially it should statically include
> resources instead; if all resources map directly onto concrete files
> it could do this even with the dynamic registry. At the language
> definition level this may be irrelevant, since there is no explicit
> compile-time/run-time distinction, and no concept of static linking.
> 7) Maybe we don't want to make extensions semantically important (the
> morally correct position). Another possibility is libmagic
> autodetection, but that isn't very portable. MIME types are generally
> available on the web and are the "right" way of identifying filetypes.
> This approach would assume a one-to-one mapping onto some sort of
> filesystem and from filetypes to interpretations, which may eliminate
> other interesting or useful cases.
>
> *****************
> Short version
> *****************
> Proposed: That you can import resources using an import path with a
> "." in it. The file extension maps to an object capable of
> interpreting the path into an object to be bound to the "as" name. The
> mapping from extension to interpreter is a per-program registry that
> can be extended in user code.
>
> A list of some potential issues is immediately above the line.
> -Michael
> _______________________________________________
> 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