Hey Ricardo :-) Ricardo Wurmus <ricardo.wur...@mdc-berlin.de> writes:
> Hi Maxim, > >>>> (call-with-input-file requires.txt >>>> (lambda (port) >>>> - (let loop ((result '())) >>>> + (let loop ((required-deps '()) >>>> + (test-deps '()) >>>> + (inside-test-section? #f) >>>> + (optional? #f)) >>>> (let ((line (read-line port))) >>>> - ;; Stop when a section is encountered, as sections contains >>>> optional >>>> - ;; (extra) requirements. Non-optional requirements must appear >>>> - ;; before any section is defined. >>>> - (if (or (eof-object? line) (section-header? line)) >>>> + (if (eof-object? line) >>>> ;; Duplicates can occur, since the same requirement can be >>>> ;; listed multiple times with different conditional >>>> markers, e.g. >>>> ;; pytest >= 3 ; python_version >= "3.3" >>>> ;; pytest < 3 ; python_version < "3.3" >>>> - (reverse (delete-duplicates result)) >>>> + (map (compose reverse delete-duplicates) >>>> + (list required-deps test-deps)) >>> >>> Looks like a list of lists to me. “delete-duplicates” now won’t delete >>> a name that is in both “required-deps” as well as in “test-deps”. Is >>> this acceptable? >> >> It is acceptable, as this corner case cannot exist given the current >> code (a requirement can exist in either required-deps or test-deps, but >> never in both). It also doesn't make sense that a run time requirement >> would also be listed as a test requirement, so that corner case is not >> likely to exist in the future either. > > I mentioned it because I believe I’ve seen this in the past where the > importer would return some of the same inputs as both regular inputs and > test dependencies. OK! >>> Personally, I’m not a fan of using data structures for returning >>> multiple values, because we can simply return multiple values. >> >> I thought the Guile supported multiple values return value would be >> great here as well, but I've found that for this specific case here, a >> list of lists worked better, since the two lists contain requirements to >> be processed the same, which "map" can readily do (i.e. less ceremony is >> required). > > “map” can also operate on more than one list at a time: > > (call-with-values > (lambda () > (values (list 1 2 3) > (list 9 8 7))) > (lambda (a b) (map + a b))) > > => (10 10 10) That's what I meant by "requires more ceremony". I can simply apply "map" to the return value of the function and get what I need, rather than having to use "values" in the callee, then "call-with-values" in the caller and establish a binding for each list. > Of course, it would be simpler to just use a single list of tagged > items. Do you feel strongly about it? I don't; I'm open to try to use a tagged list if you feel this is worth it. Maxim