KSP-KOS / KOS

Fully programmable autopilot mod for KSP. Originally By Nivekk
Other
691 stars 229 forks source link

LIST FILES IN var. tweak? #1277

Closed crafty-geek closed 8 years ago

crafty-geek commented 8 years ago

(I'd add the Enhancement tag if I knew how to.)

Any chance LIST FILES IN allFiles. could be either changed or (more likely) extended in light of the recent LEXICON addition? My suggestion: If the allFiles variable is already initialized to a Lexicon, have the C# code speedily generate and return a Lexicon<string, FileInfo> mapping NAME to the fileinfo that contains that name.

Currently, to check if a file exists (so as not to error out on a COPY or RUN or similar), one must loop through a (potentially long) list of fileinfos in Kerboscript, checking each entry against the file of interest - an O(N) operation at Kerboscript speeds. The Lexicon, however, provides (I assume) a C# backend which, from a Kerboscript perspective, would be an O(1) operation or damn near close to it.

I understand you don't want to break legacy code, hence why I'm not suggesting changing the output altogether; making it type-sense the variable it's asked to populate almost by definition means it won't break legacy code, as I see no scenario in which someone would choose to have their lexicon overwritten and List-ified unless they were then going to pass it off to a Lexicon-izing function, eg what I currently do to make my filesystem-related code run reasonably fast:

global directory is lexicon().//at least it is most of the time
//Populates directory with the local drive's contents.
FUNCTION FS_UPDATE_DIRECTORY{
  LIST FILES IN directory.//No need for a local
  SET directory TO _lexify_fileinfos(directory).
}
FUNCTION _LEXIFY_FILEINFOS{PARAMETER fList.
  LOCAL retLex IS Lexicon().
  FOR fInfo IN fList{ retLex:ADD(fInfo:NAME, fInfo). }
  RETURN retLex.
}

If type-sensing like I describe is nontrivial, perhaps a new 'phrase' that doesn't invoke the LIST behavior could do the same thing?

Also, might this behavior be useful for some other Listable keywords? (Bodies and Vessels have no need of this with the ability to do, eg BODY("MUN"), but it would be nice to extend to Processors, Resources, Parts [which until the String update you had to search for with the full name anyway], Elements, and subtypes of Part)

Dunbaratu commented 8 years ago

I'd much rather this use a different syntax form rather than rely on what the existing var type is to switch behavior. It's very much a break in design style to start saying that when assigning into a thing, the behavior of the assignment differs if the thing is existing from what it would do if the thing wasn't already existing. The context everywhere else is "throw away the value it already may have had and start over", not "populate the existing value with some data".

Furthermore the "list blah in blah" formation is, imo, a bit wrong because it puts high level API stuff at too low a level, the level of language syntax. I'd like to see less of it, not more. Wouldn't it be better if all things of type Volume were designed to implement the lexicon interface too so you could use the volumes AS lexicons?

gisikw commented 8 years ago

Oooh, so myVolume:HASKEY("myFile.ks") just sorta falls out of the implementation as an existential file check? I really like that idea!

crafty-geek commented 8 years ago

Good idea @Dunbaratu - deprecate LIST FILES altogether by giving volumes the authority. Maybe give Volumes, specifically, a HASFILE alias to HASKEY, just as syntactic sugar?

Heck, you could even create volume:COPYTO(filename,otherVolume) and volume:COPYFROM(filename,otherVolume) to deprecate that syntax... basically scroll through the File I/O page and see what can be brought under the Volume umbrella...

Still leaves the question: is there a smooth way to get the same sort of Lexicon-mapping behavior for the types mentioned in the last paragraph of the original post?

Edit: left out an argument in example code snippets, got link to render right

hvacengi commented 8 years ago

Even before deprecating the features, it would make sense to migrate as much of the functionality as possible into the volume structure. It would mean that as much as possible we can keep volume related code into the volume's structure, so there's only one place to change that function. We could then modify the existing system to use those methods, or deprecate them outright.

I am very in-favor of offering a files lexicon on the volume object. It's a little complicated due to the suffix nature, but there is potential for a huge execution bottleneck if you continually reference volume:filelex instead of set files to volume:filelex because the dictionary is reconstructed every time you call the suffix. Maybe we could institute some intelligent caching. For that reason, I still support the idea of a volume:hasfile suffix, since we can streamline the call substantially if we don't need the file object itself. On the archive, it should be faster to create the string array of file names and iterate through it than it is to instantiate a new FileInfo for every file. This may not be the case for local hard drives however, depending on how the file information is stored there.

As for the syntax: I think the big issue is that list [x] in [y] is straight forward enough, but that structure doesn't work well when you move to other types of verbs. How would you do the same thing for a lexicon? How about with a queue? It's a good shortcut, but it's a little limiting. At the very least, anything that is available using that special syntax should be available as a list suffix (either as a global binding, or a suffix on a global bound variable).