Feature/composite types - #28
Conversation
Refactors composite suite case generators
Fixes `penalize-nil` in composite suite for all collections
…f a composite type were found.
… take two of the same type as arguments.
…search/plushy.clj
|
I just renamed src/erp12/cbgp_lite/search/pluhsy.clj to src/erp12/cbgp_lite/search/plushy.clj, since it has always confused me. |
LOL. My editor's autocomplete saved me from ever noticing that typo. Thank! |
erp12
left a comment
There was a problem hiding this comment.
Overall looks good to me. Just a few minor questions and suggestions. All of these comments also apply to #29.
I am going to have to think about how best to merge this PR and #29 given the large number of shared commits. Some of these commits seem to have incomplete code, and should be squashed into a smaller set of larger commits that form a working version at each commit. If there is no clean separation of commits it might be best to squash everything into 1 commit. This will generate new commit hashes for each PR and there will be a lot of conflicts.
I think the best thing to do is redirect these PRs into a new branch in this repository and then I can handle the rebasing and squashing from there before merging to master.
In the future, it would be good to make a few workflow changes to keep the PRs easy to work with:
- Pull this repo's main branch to your fork's main branch before creating the feature branch.
- Using
rebaseto pull commits from other branches rather thanmerge. Here is a nice article about the why and how and there is a lot more discussion about this online. - If 2 feature branches depend on some of the same changes, submit an initial PR with those changes and get that merged starting both feature branches. It's always more difficult to synchronize changes to multiple moving targets.
There was a problem hiding this comment.
The local_runner.py script has configuration for launching single runs (example). What is the motivation for having a separate script?
There was a problem hiding this comment.
I made this script before local_runner.py supported single runs, and haven't had time to change my tools to use local_runner.py.
Big picture, last week I made a version of my cluster launching code that doesn't use either of these python scripts and just calls Clojure directly. I made this change because it was a pain to add new command line args to the python scripts, and I didn't see a reason to have another layer of code. So, this file can probably be deleted.
There was a problem hiding this comment.
I don't love having this much site specific information in a public repository, but we have historically done a similar thing for fly. I'm fine with including this for now because we can expect most users to be our collaborators, but we should add a big warning in some hard to miss place that this is for the maintainers of this project only.
Also, please move this to the scripts folder. Perhaps a README.md in that folder would be a good place for details who each script is for.
There was a problem hiding this comment.
It would be fine to delete these and have me keep them in a branch in my fork, if that's easier.
There was a problem hiding this comment.
I'm sure there will be future collaborators who will be developing against the HPC who will want to use these files. As long as you are okay with that code and documentation being public, I think it can be merged so that we don't have to maintain multiple long-lived branches indefinitely.
Moving the collaborator-only files to scripts/ should help reduce confusion to the wider audience.
There was a problem hiding this comment.
This should also be moved to the scripts folder.
| (read-cases {:data-dir "data/psb/" | ||
| :problem "substitution-cipher" | ||
| :n-train 10 | ||
| :n-test 0}) | ||
| ;; => {:train | ||
| ;; ({:inputs ["" "" ""], :output ""} | ||
| ;; {:inputs ["a" "a" "a"], :output "a"} | ||
| ;; {:inputs ["j" "h" "j"], :output "h"} | ||
| ;; {:inputs ["a" "z" "a"], :output "z"} | ||
| ;; {:inputs ["e" "l" "eeeeeeeeee"], :output "llllllllll"} | ||
| ;; {:inputs ["h" "d" "hhhhhhhhhhhhhhhhhhhh"], :output "dddddddddddddddddddd"} | ||
| ;; {:inputs ["o" "z" "oooooooooooooooooooooooooo"], :output "zzzzzzzzzzzzzzzzzzzzzzzzzz"} | ||
| ;; {:inputs ["abcdefghijklmnopqrstuvwxyz" "zyxwvutsrqponmlkjihgfedcba" "bvafvuqgjkkbeccipwdfqttgzl"], | ||
| ;; :output "yezuefjtqppyvxxrkdwujggtao"} | ||
| ;; {:inputs ["abcdefghijklmnopqrstuvwxyz" "cdqutzayxshgfenjowrkvmpbil" "thequickbrownfxjmpsvlazydg"], | ||
| ;; :output "kytovxqhdwnpezbsfjrmgcliua"} | ||
| ;; {:inputs ["otghvwmkclidzryxsfqeapnjbu" "alpebhxmnrcyiosvtgzjwuqdfk" "aaabbbccc"], :output "wwwfffnnn"}), | ||
| ;; :test ()} | ||
|
|
||
| (read-cases {:data-dir "data/psb/" | ||
| :problem "gcd" | ||
| :n-train 10 | ||
| :n-test 0}) | ||
| ;; => {:train | ||
| ;; ({:inputs [1 1], :output 1} | ||
| ;; {:inputs [4 400000], :output 4} | ||
| ;; {:inputs [54 24], :output 6} | ||
| ;; {:inputs [4200 3528], :output 168} | ||
| ;; {:inputs [820000 63550], :output 2050} | ||
| ;; {:inputs [123456 654321], :output 3} | ||
| ;; {:inputs [524221 135232], :output 1} | ||
| ;; {:inputs [586650 803185], :output 5} | ||
| ;; {:inputs [347099 142029], :output 1} | ||
| ;; {:inputs [902215 966305], :output 5}), | ||
| ;; :test ()} | ||
|
|
||
|
|
There was a problem hiding this comment.
Is this debug code that got left behind or is it trying to document something for the reader?
| {:description "Given a map from strings to ints and two strings that are | ||
| keys of the map, look up the values associated with those keys | ||
| in the map and return their sum." |
There was a problem hiding this comment.
Minor formatting wonky-ness in these description strings and they contains all those newlines and spaces. Consider something like:
:description (str "Given a map from strings to ints and two strings that are "
"keys of the map, look up the values associated with those keys "
"in the map and return their sum.")There was a problem hiding this comment.
Good idea, but I don't have time to make all of these changes.
There was a problem hiding this comment.
That's fine. Let's just add a @todo somewhere in this file to fix description formatting.
| ;; Current number of problems | ||
| (count (keys (problems {:penalty nil}))) | ||
|
|
||
| (map :loss-fns (vals (problems {:penalty nil}))) |
There was a problem hiding this comment.
Nothing, just development code that didn't get removed.
This all seems like a good idea if we want this to be a codebase that's really well organized and documented. However, it seems like it could be a huge pain if you're working on multiple features at once that branch off of each other. If you rebase all of these commits, then the branches my students have been working on that are based on these commits will be a pain to clean up, right? Or is it easier than I'm imagining (I've never used a rebase workflow)? In all honesty, I would find it much more helpful if efforts to make this a nice codebase were used to better document the code, rather than worrying about keeping a clean git history. But maybe we can have both? |
IMHO, this is a normal part of collaborating on long-term software projects. I agree that the scientific nature of our work raises additional wrinkles around supporting reproducibility and ephemeral experimentation code, but I think those are fairly well covered by a typical usage of version control. It's fine to make a branch for experiments with no intention of merging that new version upstream. That version should be adequate for reproducibility. If we learn something from those experiments and would like to change the "main" version from which all other people will branch off for the whole life of the codebase, we can find the best way to make that change. It doesn't necessarily have to be merging the exact experimental version (but it might be). If the experiment does not lead us to a definitive change we want to adopt more broadly, it can stay in it's branch for posterity but doesn't need to complicate the main version. In short, I would like this repository to be well organized and documented to the sake of longevity. I think we all have been through a few cycles Clojure PushGP rewrites that all take the philosophy of being an accretive bag of past experiments. I don't love that model, especial after getting burned by my mistakes in pyshgp.
This will indeed be painful. This is why, if you have dependency between changes, it is often encouraged to do multiple smaller branches in series as opposed to multiple levels of branching. In cases where there are multiple levels of branches, the usual approach to have every branch merge into the branch they branched from. In this case, assuming your students all branched off of your (this?) branch that would mean they should all first merge their changes into your branch and then afterwards your branch would be merged. But! I think I have a workflow for our current situation that will let me take over most of the painful merging. I have created a branch off of master called
Both great qualities to strive for, but orthogonal no? :) FWIW, shorter lived PRs and a git history on
In short, caring about the git history is much more about the maintainers than the users. |
Mostly adds composite types problems to CBGP. But also makes a bunch of smaller changes.