Closed kytrinyx closed 5 years ago
Most of the languages (Swift, JavaScript, Python, Scala, Java 8+, Erlang, etc) call a function that that applies a given function to each element of a list and returns a list of results map
. Applying a combining function at each node/element to get one returning value has different names like accumulate
, collect
or often reduce
.
To avoid problems with the but-in map
we could use the term transform
instead.
(Just posted this to x-python by accident. I should have posted here.)
Python has itertools.accumulate that does exactly this, right? I don't know much about functional languages but I would expect a number of them would have a function for this. If a number of them call it something besides accumulate, maybe that would be a better name. If not, maybe accumulate is okay.
I thought it was a little strange that the readme makes a special exception for Elixir and Lisp. Maybe the intent should be that you not call a single function (like itertools.accumulate) but instead implement it somehow as if that single function wasn't available. The readme might defer to the track test suites for more specific instructions. In most cases the track test suites would contain some comments saying exactly what function was disallowed but then it would up to nitpickers to call foul when someone used the disallowed function. Some languages though might have the capability for the test program to explicitly check that the disallowed function wasn't used.
Also there is the list-ops exercise which I think has similar intent. Should these exercises be combined?
Maybe the intent should be that you not call a single function (like itertools.accumulate) but instead implement it somehow as if that single function wasn't available.
Yeah, that's the intent.
The readme might defer to the track test suites for more specific instructions.
I'm reworking some of the exercise API stuff, and will be implementing https://github.com/exercism/x-api/issues/44, which would give us a way to provide this directly in the README.
Some languages though might have the capability for the test program to explicitly check that the disallowed function wasn't used.
In Ruby we've been re-opening base classes and redefining the methods to raise an exception. Dirty, but it works.
Also there is the list-ops exercise which I think has similar intent. Should these exercises be combined?
Ah, that's a really good point. I think we should certainly consider it!
In Python there isn't an itertools.accumulate. In python it is just map()
, a list comprehension, or if you want to be fancy perhaps a filter()
. All of those are provided in Python without an import
My understanding of functional programming constructs in Python is that map
, filter
& reduce
are still in the Standard Library by the skin of their teeth, and that list comprehensions
( dict comprehensions
and generator expressions
also, along with lambda
) are the way to go instead.
It does look as though the list-ops
exercise is similar and could be used here instead?
Yeah, maybe the right thing to do across the board is to deprecate the accumulate exercise and suggest implementing list-ops if it hasn't been already.
Those two exercises should definitely be merged. Maybe under the new name transform
or transform-list
. Should the Lisp and Elixir specific comments be kept?
I think for now the list-ops
name is good. I don't know if we need to keep the language-specific comments. @exercism/lisp @exercism/elixir Thoughts?
list-op
is "ok" but the pedant in me wants the name to be inclusive of other sequence/collection types. The README for this exercise is very light but I think it would be good to have instead of the accumulate
. I also think the README is clear enough that built-in functions should not be used so I don't think we need language-specific comments.
I think list-ops
is fine so long as we make clear that by "list" we don't mean a native type but a general, ordered collection of any kind. I'm glad we decided to forgo the accumulate exercise in @exercism/lisp. It seems like it's redundant with list-ops
, but I feel that and the linked-list
exercise deserve some consideration from us before we commit to implementing them. I'll mention my concerns here since they're kinda on-topic to the discussion, but we can resolve them in issues threads on xlisp.
I don't think it's good idea to have "meta" restrictions about what a learner should or should not do in implementation aside from what we can write reasonable tests for. Consider the roman-numerals
exercise: in CL we have a native function to write Roman numerals, and I think it would be quite excellent for someone new to CL to discover and use that feature for an iteration. After all, they're learning a new language and steering them away from standard libraries and built-ins seems ... odd. Obviously, when and if one is ready to challenge themselves, they may write additional iterations where they can reimplement.
If we decide there's an exercise we simply must write and make implementation requirements on, I don't think it would be a good idea for us to try to enforce those implementation requirements in the tests through package symbol shadowing, read-time conditionals, macros or any trickery functionally equivalent to what @kytrinyx describes above for xruby. In xlisp, we've been trying to make the example files the test of the exercise test suite we're providing learners. For us it makes sense that the example be written in exactly the manner described as forbidden.
I got a lot out of the list-ops
exercise for Elixir, but I think that might be a particularity due to Elixir's model of pattern-matching and recursion and syntax expressing those things in the function signature. It wasn't implementing sequence functions that I learned most, but about writing idiomatic Elixir functions. CL's core syntax and structure is simpler, and founded upon the very things those exercises ask you to reproduce. I doubt lisp-ops
and linked-list
are so rewarding for CL (or any other Lisp). I think we should consider forgoing those too, in favor of other things that show you how to use the tools CL provides for them.
(@verdammelt, following up on the last paragraph, I'm specifically thinking of the 99 lisp problems but much more indirect, translated through some scenario or unexpected medium, like grade-school
or any of the DNA exercises. It's weird how much I've learned just from alternate implementations of bob
.)
So, we deprecate accumulate
in all tracks. Is there a more inclusive name like sequence-ops/collection-operations/etc
or do we stay with list-ops
?
Does every track choose the possible functions like length, reverse, map, filter, foldr, foldl, concat, flat, etc
or do we list them in the README or *.json?
I think:
accumulate
across all the tracks.sequence-ops
, curious to hear what others thing (particularly people with more functional backgrounds)How does renaming an exercise work? Just rename the 2-3 files or do we have to deprecate list-ops
and create an exercise with the new name?
We would have to deprecate the old one and create it with a new name. The problem is for people who have already done the old version, we'd have to run a script to skip
the new version of the exercise, otherwise they'll get it the next time they fetch.
The listops in xelixir does not have fold for both directions but only a single reduce. If you implement it left or right is not enforced in any way. So perhaps over there, the exercise needs to get reevaluated to have a fold for both directions or the common side should make no assumptions about the various kinds of folds.
We have a PR for list-ops
in xelm... would it be worth waiting for an exercise rename, or is that uncertain and/or distant enough that we should just add it and clean things up along with all of the other tracks?
Just add it, @tgecho. I don't know how close we are to a conclusion here. I don't feel comfortable just making a call on this.
Shall we post an issue to each of the tracks suggesting that they add accumulate
to the deprecated
array in config.json
?
In functional languages, which do have pattern matching, you can learn a lot about pattern matching, higher order functions and recursive datatypes with this single and easy exercise. But you can learn about comprehensions as well (if your language supports them).
I'm still in favor of keeping this exercise, but rename it to something like for-each
, apply-each
, map-a-mole
:), or something similar.
This function is pretty much the functional hello-world.
:+1: to map-a-mole
I love map-a-mole
!
I'm in favor of deprecating accumulate
since list-ops
encompasses it and more. And I'm fine with the name list-ops
, but if we really want to change it perhaps functional-ops
? That seems the most straightforward to me since we are talking about functional programming operations.
It doesn't seem worth putting a lot more thought into 'Accumulate' since it's largely been superseded by 'List Ops'; shall we close this, @kytrinyx?
I don't mind deprecating it across the track.
I agree, we should close this.
@sshine Do you think it's worth opening a PR to each track that deprecates it, asking maintainers to make the call?
Yes, I think it's OK.
Probably take into account that some tracks have deprecated it already and can close the issue.
Is there such a thing as deprecating the exercise in problem-specifications, and does it have any consequences other than signal value to tracks?
Is there such a thing as deprecating the exercise in problem-specifications
Yepp, we add a .deprecated
file in the exercise directory, like so:
https://github.com/exercism/problem-specifications/blob/master/exercises/octal/.deprecated
does it have any consequences other than signal value to tracks?
The only value of it is a signal to tracks.
Does someone know why this issue was closed although without the exercise actually getting deprecated? Maybe @petertseng can remember?
I was reminded about this issue in a recent discussion in the python track: https://github.com/exercism/xpython/issues/245
The accumulate problem describes what is typically called
map
orcollect
, I think, in many other languages.I think we should rename this across the board, but I'm not sure what we should rename it to. Thoughts?