Last active
December 20, 2025 14:21
-
-
Save sogaiu/36d04c3f33dbc56461bcd16fbfe57b73 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| * code to help with "compiling" / "linking" multiple files into a | |
| self-contained single script | |
| * develop with files split, but "compile" to single script | |
| * rationale | |
| * single file can be copied and used more easily as a script or | |
| library (e.g. easier to "vendor" into projects). though on | |
| windows, the script idea may require an accessory `.bat` or | |
| other launcher file. | |
| * symlinking to single file in repository means that development | |
| is eased because one is working with the current version without | |
| having to "install" | |
| * random | |
| * consider when newer versions of jell should be "deployed" | |
| * how about placing info in the attributes table for nodes for | |
| reference later? e.g. during studying, record notes in attribute | |
| tables. then during later traversals, make use of the previously | |
| recorded info? | |
| * while traversing code, possible to track whether one is within a | |
| quoted or quasiquoted form and then record this either in the | |
| attribute table or elsewhere. this might help in identifying | |
| names that should not be renamed (e.g. peg specials or other | |
| similar situations)? | |
| * combine with idea of having "directives" marking areas (spans?) | |
| or nodes to indicate that jell should behave differently? | |
| * adopt approach of noting limitations and potential features but | |
| waiting until need is dire, painful, etc.? | |
| * document some details of what kind of .janet files can be "brought | |
| together" | |
| * limits and questions | |
| * make small projects for testing | |
| * removes `comment` forms | |
| * removes docstrings | |
| * changes all syntactically top-level definitions to private? | |
| * changes all syntactically top-level definitions to public? | |
| * end result is not reindented | |
| * consider additional testing of jell using other project source | |
| * jackal | |
| * jargon | |
| * jog | |
| * other? | |
| * testing does not involve comparing "compilation" results of older | |
| versions of jell with newer versions. this seems like it might be | |
| a good thing to try. | |
| * compare for identical source - sometimes one might expect the | |
| same output (e.g. if performance was supposedly the only | |
| difference). | |
| * some source differences might be expected - e.g. if the | |
| generated output no longer removed `import` forms but instead | |
| wraps them in `(comment ...)`. | |
| * import forms must not have whitespace or line comments before the | |
| `import` symbol to be processed properly (at least by | |
| `tweak-import-forms`). | |
| * defining forms must not have whitespace or line comments before | |
| the `def...`, `var...`, etc. symbols to be processed properly (at | |
| least by `find-top-level-syms`). | |
| * no proactive mechanisms for trying to warn about symbol | |
| "collisions" between global names and names within quoted / | |
| quasiquoted contexts (e.g. within pegs -- recall example with | |
| `replace` in `jipper.janet`). see note elsewhere about recording | |
| that one is within a quoted or quasiquoted form. | |
| * there isn't yet a "study" mode that can signal the use of | |
| constructs that are not supported (or potentially problematic). | |
| such a mode could be used as a kind of a linter in ordinary | |
| development to keep one's code in a shape that's more likely to be | |
| reusable. it's likely to be a fair bit of work to create | |
| something comprehensive all at once. it's probably worth having | |
| some limited version at first and then gradually add to this over | |
| time. | |
| * not possible to execute single stage (e.g. just study or just | |
| prepare or just link). this might be slightly tricky to do if one | |
| just wants to operate on later stages because all of the needed | |
| pieces may not be available? | |
| * no option to remove "testing" comment forms (or all comment | |
| forms?). may want to always keep this optional even if supported | |
| eventually because the comment block tests being transformed along | |
| with the code can be helfpul in some cases to detect whether the | |
| transformation broke some of the code. | |
| * not making "imported" definitions all private in starting file. | |
| doing so could make the single file work nicely as just a library. | |
| another option might be to prefix pervasively and add a bit at the | |
| end of the file that explicitly defines some "export" names that | |
| are not prefixed. these could be specified via configuration. | |
| all other top-level definitions (except main?) might be made | |
| private. | |
| * not renaming things defined within comment forms | |
| * only .janet files (no c). this limitation seems very unlikely to | |
| be one that can be lifted. | |
| * only handles input files that are siblings within the same | |
| directory. | |
| * only handling files with certain types of import forms (e.g. no | |
| `require` forms or other non-import forms are handled). need to | |
| spell out more clearly the constraints. should detect and warn. | |
| * values for :as and :prefix which contain potentially problematic | |
| characters (e.g. may be :prefix values should not have | |
| slashes?). to do this, details of what is acceptable or not | |
| acceptable need to be spelled out? probably want to stick with | |
| a subset of characters that work for file paths on multiple | |
| platforms? an example of a character to avoid might be "/"? | |
| above may be "global" is meant and not necessarily "top-level"? | |
| * renaming names within macro definitions may be naive. this may | |
| need to be examined more closely but it isn't so pressing atm | |
| because there are no macro definitions in the code being used for | |
| exploration. | |
| * candidates for an optional check phase - might start by writing | |
| usages for jipper as experiments and if these work out, place in | |
| an optional check phase for jell. | |
| * not (yet) handling files with `use` forms. should detect and | |
| warn? | |
| * not (yet) handling code that uses `upscope` (and `compwhen`, | |
| etc.). there is some similarity with the handling of "top-level" | |
| definitions within `comment` forms, though it's not quite the | |
| same. should detect and warn. | |
| * no handling of defglobal or varglobal. they don't come up much so | |
| not much of an issue? detect? | |
| * no handling of defdyn? | |
| * global definitions that have names that are prefixed are not | |
| warned about. better to not support such names initially. | |
| possibly in future. | |
| * no support for arbitrarily nested global top-level destructuring | |
| defines (don't do this in comment blocks either if the comment | |
| blocks contain tests). probably could warn via an initial scan? | |
| very simple things are supported (e.g. `(def [a b] ...)` or `(def | |
| {:a a :b b} ...)`). | |
| * not (yet) handling code that has a top-level definition that has a | |
| name that collides with a non-top-level definition's name (at | |
| least in the same file). can warn about this probably via initial | |
| scan. the old jipper.janet had at least one of these | |
| (`make-state`). more "shadowing detection" might be doable: | |
| * checking names in argument tuples | |
| * checking non-top-level definition names | |
| * any other place that names might be introduced... | |
| it may not be problematic for there to be a non-top-level | |
| definition with name x preceding a top-level definition with | |
| name x (so the jipper.janet case of `make-state` is fine). | |
| the reverse case might be an issue though. however, it might | |
| depend on whether all names are identified before any renaming | |
| is attempted. perhaps better to arrange for renaming of | |
| top-level names and their uses such that only "uses" that appear | |
| later in the file are targets of renaming. perhaps having | |
| available locations of definitions and uses would be a good | |
| idea. | |
| probably better to do the same within comment blocks too | |
| (because of tests)? | |
| * code that uses ordinary tuples (i.e. () vs []) for the parameter | |
| portion of defn, defmacro, etc. is not warned about. probably not | |
| worth supporting in the future because in practice almost no one | |
| writes code like this? | |
| * no warnings for macro definitions that lead to top-level | |
| definitions + calls to such macros. possibly a fair bit of work | |
| to pull off detecting. | |
| * not (yet) handling shadowing of definitions (even between things | |
| within `comment` forms and outside). is there really an issue / | |
| limitation here? warn if a global definition within a `comment` | |
| form "collides" with a non-comment global definition? | |
| * not handling certain kinds of defining, e.g. like what spork's | |
| path.janet does. the symbol renaming that might be needed seems | |
| impractical? path.janet has defmacros that contain defs and | |
| defns. the macros are used later in the file. possibly could | |
| detect and warn? seems hard in general? | |
| * "splitting" of file into modules isn't supported. possibly adding | |
| comments in various parts could make splitting more tractable. | |
| import forms that used to exist are now "(comment ...)"-ed so a | |
| step has been made in this direction. this may make examining the | |
| generated code when investigating issues a bit easier as well. | |
| * "copy one file to install" approach not supported on windows | |
| because no shebang-like mechanism (editing file type associations | |
| doesn't count?). possibly have a way to generate a launcher file | |
| (e.g. a "shim" `.bat` script) via a "one time" special execution | |
| of the janet script (e.g. manually invoke `janet jell | |
| make-launcher`). | |
| * go through and try to merge items with various sections? | |
| * "tree-shaking" -- by tracking which symbols are used in calls | |
| (note: function names can be passed as parameters too!), it might | |
| be possible to do this, but there is stuff like eval, macros, | |
| etc. to contend with so may be not worth the trouble? | |
| * not (yet) trying to handle unprefixing of top-level names being | |
| defined within source files (this is different from prefixed names | |
| that result from use of import). should detect and warn. | |
| in the future might be nice to unprefix if possible. warn if not | |
| possible. perhaps better to note it and avoid using the prefix | |
| for other things? | |
| this was an in issue in zipper.janet (used s/ prefix), but rewrote | |
| to eliminate issue. | |
| jeep has imports which have :as values that use slashes: | |
| (import ./subs/install :as cmd/install) | |
| possibly unprefixing these would be worth considering at some | |
| point? but may be this is a slightly different issue? | |
| possibly unprefixing overall can be avoided by choosing to use a | |
| non-slash character instead of a slash as a separator between a | |
| prefix and an existing name. | |
| * terms with specific meanings -- more or less defined within the text | |
| * starting file | |
| * imported file | |
| * input file | |
| * prefix | |
| * global name | |
| * imported name | |
| * domestic name | |
| * revised version of "stages" idea | |
| * check (optional) | |
| run own checks (i.e. not janet -k) on source to generate warnings | |
| about potentially problematic code. | |
| generating a report of located constructs might be of interest | |
| too? e.g. number of top-level definitions, comment forms, import | |
| forms, etc. | |
| keeping this stage independent means that one is not required to | |
| pay the cost of checking, but one has the option to if desired. | |
| * `use` forms not supported due to analysis depending on `import` | |
| forms | |
| * use of symbols in "data" (e.g. peg specials) may result in | |
| renaming issues. e.g. suppose a file has a peg that uses the | |
| `replace` peg special and further that the file also has a | |
| function named `replace`. when renaming names in this file, the | |
| `replace` in the peg may get renamed. this is undesirable. | |
| would this type of situation always be "interior" to quoted or | |
| quasiquoted content? | |
| * potentially add things from the "warnings during study phase" | |
| section and elsewhere. | |
| * study | |
| given a starting file: | |
| 1. perform some checking of the starting file | |
| 2. identify all relevant imported files and corresponding | |
| prefixes. | |
| step 1 might be done by running a linter on the starting file | |
| before proceeding, but also may be run existing tests. if either | |
| turn up issues, likely it's better to address those before | |
| proceeding further. | |
| step 2 is accomplished via a traversal that begins at the | |
| starting file. as source is examined, `import` forms may be | |
| encountered. each import form is analyzed to determine: | |
| * a corresponding input file, which will be referred to as an | |
| imported file | |
| * a prefix for the corresponding imported file | |
| each newly encountered imported file is then examined in turn and | |
| the process continues recursively. | |
| note that: | |
| * a "starting file" is not an "imported file". the term "input | |
| file" will be used to refer to either type of file. | |
| * an imported file may be encountered more than once and for these | |
| subsequent encounters, the imported file should not be | |
| traversed. i.e. an imported file should only be traversed once. | |
| * however, at each point of encounter of an imported file, the | |
| specific prefix met should be noted as this may differ depending | |
| on the specific import form (typically in different files | |
| though). probably should warn / abort if different prefixes are | |
| being used for the same file. | |
| * for the moment, make use of the existing prefixes for renaming | |
| purposes later. | |
| * prepare | |
| 1. transform each one appropriately for the next stage | |
| X. check transformed content a bit | |
| step 1 is accomplished by first associating a unique prefix to | |
| every imported file (but not the starting file) and then producing | |
| modified versions of all of the identified input files. | |
| the modifications consist of appropriately changing names in each | |
| of the imported files (n.b. though only for "imported names" -- | |
| see below -- in the starting file) as well as import forms in all | |
| input files (n.b. that includes the starting file): | |
| * the first is done by creating new names for certain names that | |
| appear in the file and then performing replacements where | |
| appropriate. | |
| * the second is done by modifying the import forms to use `:prefix | |
| ""` (or changing the `import` form to be a `use` form). | |
| typically only some names in each imported file need to be changed | |
| (e.g. local names are left alone). there are two sorts of names | |
| that may need renaming: | |
| * "domestic names", i.e. those that are "defined" in the current | |
| file. | |
| relevant locations for changing a domestic name include | |
| "definition site" and all "use sites" (e.g. calls or being | |
| passed as arguments). | |
| * "imported names", i.e. those that are "imported". | |
| each imported name will be assumed to have some existing prefix. | |
| the presence of a prefix indicates that a name is imported and | |
| further, the particular prefix uniquely determines which file | |
| the name originated from. previous analysis of import forms | |
| should have made it clear which prefixes are associated with | |
| which files. | |
| the existing prefix (and separator character, e.g `/`) should be | |
| removed and replaced with a newly chosen prefix corresponding to | |
| the file from which the name is imported (plus possibly a | |
| different separator character, e.g. `^`). there should only be | |
| "use sites" (no "definition sites") for imported names and those | |
| should be renamed. | |
| performing the name replacements will initially be done using | |
| multiple passes in order to keep tractability under control and | |
| increase correctness. | |
| * there will be at least one initial pass to determine which | |
| identifiers need to be renamed. | |
| there could be a pass for domestic names that involves examining | |
| where they are defined. there are plain top-level names which | |
| might be handled in one pass and then there are "top-level" | |
| names within comment forms which could be handled in a separate | |
| pass though possibly better to not do initially. names defined | |
| within `upscope` and friends might not be handled initially. | |
| might want to warn / abort if plain top-level names suggest | |
| shadowing / duplication. however, due to the way comment form | |
| tests are written, shadowing / duplication should probably be | |
| allowed (within a file). | |
| there could be a pass for imported names which involves | |
| examining import forms to identifiy relevant prefixes. for | |
| imported names, there could be a separate pass for names within | |
| comment forms. in any case, what is identified is a set of | |
| prefixes which could then be used during traversal (in a later | |
| pass) to determine if some encountered idenitifier is imported | |
| or not and hence whether it should be renamed. | |
| * there may be one or more subsequent passes to actually carry out | |
| the replacements. | |
| possibly one for plain top-level global names. perhaps a | |
| separate pass for "global" names defined within comment forms. | |
| again, names that were introduced within `upscope` and friends | |
| may not be supported initially. | |
| step X. might be done by running a linter across the products. if | |
| the comment-form style testing method is in use, those tests ought | |
| to have been transformed appropriately as well so running them to | |
| check on behavior might be a good idea too. | |
| note that the transformed versions of the input files should still | |
| function together and produce the same results as for the original | |
| input files. (though it seems possible that some kinds of | |
| self-referential operations might produce different behaviors. | |
| may be there are other such kinds of "exceptional" behavior as | |
| well?) | |
| * link | |
| given transformed input files from previous stage, produce final | |
| product out of the inputs: | |
| 1. bring together the modified input files' contents (from the | |
| previous stage) appropriately | |
| 2. deactivate each of the pre-existing import forms | |
| X. check final product a bit | |
| step 1 is currently done by visiting top-level forms one at a time | |
| starting with the modified start file and following relevant | |
| modified imported files via import forms. | |
| step 2 is accomplished by commenting out import forms. | |
| step X might be done in a manner similar to that of the previous | |
| prepare stage, i.e. running a linter and any included comment-form | |
| tests. | |
| * on the necessity of renaming certain names and the terms / phrases | |
| "prefixing", "imported names", "domestic names", and "global names". | |
| * since content from multiple files is being brought together into a | |
| single file, renaming is needed to avoid "collisions" between | |
| instances of certain names being used differently among two or | |
| more files, e.g. | |
| file x: | |
| (def a 1) | |
| file y: | |
| (def a 2) | |
| combined file: | |
| (def a 1) | |
| (def a 2) # oops | |
| "prefixing" of names with `<something>/` is one way of renaming, | |
| e.g. | |
| combined file: | |
| (def i/a 1) | |
| (def j/a 2) # no collision now | |
| prefixing can be done using characters other than slash, | |
| e.g. `<something>^` seems like it could work too. | |
| combined file: | |
| (def i^a 1) | |
| (def j^a 2) # no collision now | |
| postfixing might be another possibility. | |
| combined file: | |
| (def a^i 1) | |
| (def a^j 2) # no collision now | |
| fwiw, prefixing with slash is already what happens when janet | |
| applies `import`, e.g. suppose there's a file with content: | |
| # assume there is a file `my-fun.janet` in the same directory | |
| (import ./my-fun :as mf) | |
| then public top-level definitions from `my-fun.janet` will be | |
| available but via names that begin with `mf/`. so if | |
| `my-fun.janet` has content: | |
| (def j 8) | |
| then within the file with the `import` form from above (assuming | |
| no other arrangements), `mf/j` will evaluate to `8`. | |
| * for a given name which requires renaming, it needs to be renamed | |
| where it is defined ("definition site") as well as where it is | |
| used ("use site"), e.g. | |
| before renaming: | |
| (defn f [x] | |
| (if (zero? x) | |
| 0 | |
| (+ 1 (f (dec x))))) | |
| (f 2) | |
| after renaming: | |
| (defn a^f [x] | |
| (if (zero? x) | |
| 0 | |
| (+ 1 (a^f (dec x))))) | |
| (a^f 2) | |
| * in the most general case, the names which require renaming are | |
| those that are "global", i.e. those that can be used from any scope | |
| (though shadowing might add some nuance). | |
| constructs such as `defglobal`, `varglobal`, and `eval` can | |
| introduce global names dynamically and are thus not generally | |
| amenable to syntactic methods. in short, they won't be supported | |
| fully and likely not at all initially. | |
| syntactically there are at least three cases that might be worth | |
| supporting. | |
| * plain top-level definitions, e.g. `a` and `main` in: | |
| (def a 8) | |
| (defn main | |
| [& args] | |
| (print a)) | |
| * names that are defined within the "top-level" of a use of | |
| `comment`, e.g. `a` in: | |
| (comment | |
| # top-level within `comment` | |
| (def a 1) | |
| # top-level within `comment` | |
| a | |
| # => | |
| 1 | |
| ) | |
| the reason this type of name is being considered is to support a | |
| certain type of testing convention. | |
| * names that are defined within the "top-level" of a use of | |
| `upscope` (or a few others, see later), e.g. `b` in: | |
| (upscope | |
| # top-level within `upscope`; | |
| (def b 2) | |
| ) | |
| # `b` can then be used as if defined at the syntactic | |
| # top-level | |
| (pp (inc b)) | |
| note that `compwhen` also ends up using `upscope`. `compif` and | |
| `comptime` achieve a similar end via `eval`. | |
| although one can write: | |
| (eval (def a 1)) | |
| and end up with `a` defined at the top level, this is doing | |
| something different than: | |
| (eval '(def a 1)) | |
| `eval` is a function and its argument expressions are evaluated | |
| at the scope the expression is in. | |
| all functions have this behavior, but special forms and macros | |
| only sometimes. i.e. at the top-level, when a function | |
| evaluates its argument expressions, those expressions are | |
| evaluated at the top-level. | |
| more generally, the argument expressions are evaluated in the | |
| current scope(?). | |
| perhaps in the future some of these could be warned about... | |
| or handled? | |
| * there are other names that may not need to be renamed from the | |
| perspective of "merging" file content together. some of these | |
| include: | |
| * names introduced via parameter tuples, e.g. | |
| (defn my-fn | |
| [a-name b-name] | |
| 8) | |
| `a-name` and `b-name` are local to `my-fn` and thus should not | |
| be affected by "merging". | |
| * non-top-level names introduced by `def`, `let`, etc., e.g. | |
| (defn my-other-fn | |
| [x y] | |
| (def a 1) | |
| (let [b 2] | |
| (+ a b))) | |
| `a` and `b` are local to `my-other-fn` and thus should not | |
| be affected by "merging". | |
| * are there any other kinds of names that would be unaffected? | |
| * the names that need to be renamed and those that don't need to be | |
| renamed (because of merging concerns) might overlap | |
| (e.g. shadowing) in some cases, e.g. | |
| (def a 1) | |
| (defn f | |
| [x] | |
| (def a 2) | |
| a) | |
| there is a top-level `a` and a local `a` that have the same name. | |
| from the perspective of program transformation, it would probably | |
| make things easier if this kind of situation did not arise. if | |
| practical, it might be nice to detect if there are any instances | |
| in the code about to be manipulated and give appropriate feedback | |
| and/or abort processing. | |
| * some names within a file become "available" via the use of a | |
| construct like `import`. these will be referred to as "imported | |
| names". the names within a file which are defined within the file | |
| will be called "domestic names". the distinction is made partly | |
| to improve thinking and communicating about renaming. | |
| for a given file, renaming the domestic names involves all three | |
| types of global names. for imported names, only the plain | |
| top-level and upscope types of top-level names are the target of | |
| renaming, i.e. global top-level names within comment forms from | |
| another file aren't supposed to be visible outisde of the files | |
| they are defined in. | |
| * constructs that introduce names apart from what has been | |
| mentioned elsewhere... | |
| * parameter tuples | |
| * straight-forward macros | |
| * single name that is easy to detect | |
| * label, with, when-with, if-with, forv, for, as->, as?->, | |
| ffi/defbind-alias, ffi/defbind | |
| * possibly multiple names, but no destructuring | |
| * catch | |
| * possiblly multiple names that might get complicated because of | |
| destructuring | |
| * each, eachk, eachp, let, if-let, when-let | |
| * complicated (but all the same?) | |
| * loop, seq, catseq, tabseq, generate | |
| * most complicated? | |
| * match | |
| * user-defined macros | |
| * provide hooks for handling these - definitely not at first | |
| * this might allow handling of things like path.janet | |
| eventually | |
| * other things which are not relevant? | |
| * names introduced but typically used like ,name | |
| * with-syms | |
| * involves keywords so not needed? | |
| * prompt, with-dyns, with-vars | |
| * is it practical to detect shadowing? it is related to the | |
| "constructs that introduce names" items and as such a better | |
| question might be "how much shadowing would be practical to | |
| detect?". | |
| * misc notes | |
| * organizational challenge of too many notes. perhaps making a | |
| section of "may be later" items would help declutter a bit. | |
| * may be unprefixing can be avoided entirely by using a non-slash | |
| (and non-problematic) separator character. ^ is not used very | |
| much atm (according to some research). as mentioned elsewhere may | |
| be better to allow customization. | |
| unprefixing can't really be avoided for imported names which | |
| typically will have some prefix determined by a corresponding | |
| import form. | |
| * zipper editing does not update location information though | |
| multiple edits appear to be supported (see modify-test.janet). | |
| modifications should then be made after all location information | |
| has been obtained and utilized? | |
| * consider the idea of "normalization" (of source) being applied to | |
| simplify later manipulation (in the context of the "stages" | |
| mentioned elsewhere). an example is: `(import ./hello)` could be | |
| re-expressed as `(import ./hello :as hello)` or `(import ./hello | |
| :prefix "hello")`. however, for this specific case, if `import` | |
| forms are going to be commented out anyway it seems rather | |
| pointless. normalization might be good for other situations | |
| through. | |
| * handy to be able to determine whether a given form is at the | |
| top-level (or within `comment`, `upscope`, etc.)? this might be | |
| relatively straight-forward by using `path` and `leftmost`. | |
| * handy to be able to find the first non-whitespace / non-comment | |
| element of an indexed-type or a dictionary. right-skip-wsc | |
| doesn't check the current location so that needs to be checked | |
| beforehand. | |
| * any use in a self-extraction step for native and other | |
| (e.g. resources) bits? | |
| * on various approaches to carrying out renaming | |
| * one possible way of actually performing the name replacements is | |
| to determine what all of the names are that need changing via an | |
| initial pass and then making a subsequent pass to actually change | |
| the target names. | |
| * another approach might be to scan for a name to change, remember | |
| the current location, make the name change in subsequent locations | |
| in the file, return to the remembered location, and then to | |
| continue scanning for another name to change and repeat as before. | |
| this approach might be conceptually simpler at the cost of a fair | |
| number of traversals. | |
| * a third approach is to carry out identification of names as well | |
| as renaming in a single pass. this may be the most efficient | |
| approach, but it may also be more complicated to get right as well | |
| as maintain and/or modify. | |
| in terms of simplicity and getting things correct / working, | |
| probably taking a multi-pass approach makes the most sense at least | |
| initially. | |
| * notes on specific renaming cases | |
| * forms like ->, ->>, etc. can contain function names in | |
| argument positions | |
| * similar remark for map, filter, etc. | |
| * macro definitions may also contain things? possibly these | |
| are harder to detect? better to examine some actual | |
| cases: | |
| (defmacro toggle | |
| "..." | |
| [value] | |
| ~(set ,value (,not ,value))) | |
| things prefixed with `,` will be within :unquote nodes? | |
| * any other "macro reader" things to be concerned with? | |
| * :fn? | |
| * :quote? | |
| * :quasiquote? | |
| * :splice? | |
| * any other cases? | |
| * overall approach notes | |
| * try breaking up bin/jog into files, then make modifications until | |
| "original" files are "recovered". take notes in the process. | |
| this approach was followed at least for part of the overall | |
| development activity. | |
| * studied bin/jog's current form and compared with the files it | |
| was built out of to see what changes were needed. | |
| * "doctored" files that jog can be built from: | |
| * args.janet - a | |
| * completion.janet - c | |
| * jipper.janet - j | |
| * location.janet - l | |
| * search.janet - s | |
| * report.janet - r | |
| * search.janet | |
| * find.janet | |
| * find.janet - f | |
| * location.janet | |
| * jipper.janet | |
| * main.janet (don't prefix anything in this file...has main) | |
| * args.janet | |
| * completion.janet | |
| * report.janet | |
| * figure out what "doctoring" is needed to arrive at files in their | |
| forms above. manually create versions of files that would have | |
| existed before doctoring and then compare. | |
| * collisions between the peg name "replace" and jipper's "replace". | |
| in general, it won't be possible to avoid these kinds of collisions | |
| as janet's peg system might gain new specials. | |
| in general, some kind of detection / warning seems desirable | |
| * try to detect whether something is a peg or other kind of data | |
| containing symbols? or is it better to not replace symbols | |
| within quoted or quasiquoted things? may be emit warnings if | |
| quoted / quasiquoted stuff is being modified? still need some | |
| way to indicate what to do in such a case to avoid manual | |
| intervention every time. | |
| * don't use `replace` in the peg. | |
| * could use `/` instead, but this won't work in general because | |
| not every peg special has an appropriate abbreviation. | |
| * define something to have the symbol `replace` as its value | |
| and unquote it into place: | |
| (def rpl (symbol "replace")) | |
| (peg/match ~(,rpl "a" "b") "a") | |
| this approach could work, but it would be better if potential | |
| issues could be warned about so the code could get rewritten | |
| appropriately. | |
| went with this approach for the moment and may work on trying to | |
| figure out how to warn. | |
| * if the symbol renaming was slightly smarter in not blindly | |
| renaming all seemingly matching symbols through the entire file, | |
| this particular problem could have been avoided because the | |
| affected `replace` occurred before the definition of the | |
| function `replace`. | |
| doesn't seem likely that code could be written to accomodate in | |
| all cases though. | |
| * changing jipper's api might work, but issues could arise later | |
| if peg/match is enhanced. however, at this point it seems | |
| unlikely that much would get added to peg/match? | |
| * mark with special comment. this provides a finer-grained way of | |
| indicating something that shouldn't be changed, even within a | |
| function body that has other parts that need modification. | |
| some downsides to this approach include a more complex | |
| implementation as well as potential slow-down for lots of | |
| checking. | |
| * try to design comment to be obviously showing certain intent | |
| and be unlikely that people will create by accident. | |
| * check out how clj-kondo does things: | |
| https://cljdoc.org/d/clj-kondo/clj-kondo/2025.07.26/doc/configuration#ignore-warnings-in-an-expression | |
| #_:clj-kondo/ignore | |
| (inc 1 2 3) | |
| #_{:clj-kondo/ignore [:invalid-arity]} | |
| (inc 1 2 3) | |
| * place a special comment (directive) "nearby" candidates: | |
| * before - it's what clj-kondo does and comments tend to come | |
| "before" what they comment on...though there are | |
| "trailing" comments too | |
| * cannot put on same line as item that is being referred to | |
| because janet only has line comments (no equivalent of #_) | |
| * cannot put before first line if file is a shebang script | |
| because the shebang line must be first | |
| * after - seems different from what might be expected. | |
| * can put after first line | |
| * can put on same line as thing it refers to | |
| (replace #< :jell/no-rename | |
| ...) | |
| * either side - flexible but complex | |
| #> :jell/ignore | |
| fun | |
| bubbly #< :jell/ignore | |
| use angle bracket to indicate which direction item being | |
| referred to is located? | |
| * may be helpful to have left-skip-ws and right-skip-ws to be | |
| able to move to comments (similar to left-skip-wsc and | |
| right-skip-wsc except doesn't skip comments) | |
| * general patching mechanism that is applied after the prepare | |
| stage completes? | |
| patches might need to be updated due to underlying source | |
| changes, but this approach might not be a bad compromise, | |
| e.g. compared to trying to support some kind of directive system | |
| which might make things more complicated and slower. | |
| * marking definitions with metadata to flag as "don't rename in | |
| here"? might work for simple cases? won't work for this case | |
| because there is something within the function definition that | |
| needs to be modified -- specifically, `make-attrs` needs to be | |
| renamed. | |
| * observations from rewriting bin/jog to use prefixed identifiers that | |
| reflect which file they might have originated from | |
| * renaming some function names within ->, ->>, -?>, and friends | |
| is more work because of things like: | |
| (->> (map + [1 2 3]) | |
| invert) | |
| i.e. not all function names appear as first elements of tuples. | |
| want to handle this. | |
| * functions being passed as arguments, like for map, filter, etc. | |
| can probably be handled, though unclear whether trying to handle | |
| this will accidentally rename things in cases where there is a | |
| tuple that isn't a call...want to handle the ordinary case. | |
| * in the old `zipper.janet` file there is a local function named | |
| `make-state` and a top-level function of the same name. may be | |
| don't want to rename the local one. how to tell apart the | |
| uses...need to track scope? better to have the limitation to not | |
| allow the same name for top-level and internal things? (change | |
| code in `zipper.janet` to not have this characteristic -- did | |
| this) or at least warn if detected? | |
| * probably do want to "prefix" "top-level" things within comment | |
| blocks so that: | |
| * tests from one file do not collide with test from another file | |
| * tests run after "compilation" | |
| * trickier to rename destructure-defined things, e.g. | |
| (def [a b] [1 1]) | |
| as: | |
| (def [z/a z/b] [1 1]) | |
| perhaps tuple case is relatively straight-forward? except | |
| recursion...struct case is more complicated...may be better to | |
| rewrite code to not use these constructs. could probably warn. | |
| * import forms and the identifiers that use them (see | |
| loc-jipper.janet for examples) seem not straight-forward to handle | |
| in terms of renaming. is this referring to the content of comment | |
| blocks? | |
| (comment | |
| (import ./location :as l) | |
| (l/gen ...) | |
| ) | |
| * zipper.janet and loc-jipper.janet are kind of weird birds...the | |
| latter kind of redefines stuff from the former...can this be | |
| avoided or reworked somehow to begin with (before trying to | |
| process them with highlander)? zipper.janet and loc-jipper.janet | |
| have been merged as jipper.janet to avoid this issue. | |
| * possibly by warning of various issues, could support the idea of | |
| having "patches" that are manually constructed by the author and | |
| can be applied automatically upon each rebuild? | |
| * linter (janet -k) seems pretty good at finding spots that | |
| need renaming (outside of comment blocks) | |
| * name ideas | |
| * jell (current choice) | |
| * highlander (jaylander or jighlander) | |
| * joust (only one remains after?) | |
| * chimera (collection of different things) | |
| * article (a, an, the -> one) | |
| * single | |
| * assimilator, absorber | |
| * old planning notes for related idea of doing use -> import | |
| rewrite below | |
| # 0. parse all files to find all symbols? | |
| # * will use in process of choosing appropriate alias... | |
| # this might be relevant because someone might | |
| # do `(defn my/name [] ...)` so we'd want to avoid | |
| # choosing `my` as an alias. | |
| # | |
| # 1. find all definitions across all files | |
| # * require that all relevant files be specified? or can | |
| # the code make an attempt to manually located "installed" | |
| # code? may not work for things defined in .c files... | |
| # * what about things defined in .c? possibly could work | |
| # if source is available. | |
| # | |
| # 2. find all `(use ...)` forms in all files | |
| # | |
| # 3. replace each `(use ...)` form with appropriate `(import ...)` form | |
| # * avoid alias (i.e. `:as <name>`) collisions | |
| # | |
| # 4. find all uses of things brought in via `use` | |
| # * check all symbols in file for potential matches | |
| # * edge case when later `(use ...)` overrides earlier one. | |
| # * try to identify potential "clashes" earlier in process, | |
| # e.g. after enumerating all symbols across all files | |
| * janet flavor limits | |
| * all input files must be siblings (no files in subdirectories), | |
| i.e. no "multilevel" paths. the `./dir/init.janet` type of import | |
| is not supported (i.e. `(import ./dir)`). | |
| * all import paths must start with `./`, i.e. no syspath files, | |
| working directory imports (e.g. the paths start with `/`), and | |
| `@-prefixed imports are not supported. only .janet files in same | |
| directory as start file. | |
| * import forms with :export true are not supported | |
| * import forms with :only are not supported | |
| * import forms must use :as or :prefix, i.e. a prefix must be | |
| explicitly specified. something like `(import ./alpha)` is not | |
| currently supported. | |
| * the prefixes defined by :as and/or :prefix must be consistent | |
| across files, i.e. if there is `(import ./mine :as m)` somewhere | |
| then all other instances of `(import ./mine ...)` needs to use | |
| `m`. | |
| * continue filling stuff in here | |
| * undocumented features | |
| * env var VERBOSE can be used to dump some output during | |
| execution. possibly useful for investigating issues. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment