Talk:List comprehensions: Difference between revisions

m
fixed section header name.
m (fixed section header name.)
 
(16 intermediate revisions by 11 users not shown)
Line 1:
==Pop11 example==
The Pop11 example does not use the sort of syntax specified in the requirements. --[[User:TBH|TBH]] 09:22, 23 May 2008 (MDT)
 
Line 25 ⟶ 26:
 
:We have some tasks that are specific to other sections of programming languages - those with explicit pointers, or those with OO features for example. Functional programming languages such as Haskel, ML and OCaml are, in some ways, the new kids on the block and I think it is right to have some tasks expressed from a functional viewpoint as well. The task is to show how some languages explicitly borrow from set-builder notation to form what is called a list comprehension in many of those languages and to show the similarities between the languages syntax and that of set-builder syntax. It is like a task to show how to create a class; some languages might be able to do the same thing with a structure and maybe pointers to functions, but the writer of the example should state that the language designers did not have the idea of a class in mind when they created structures and function pointers. Similarly in a task about goto statements, if asked to use a goto to jump to the end of a function, I would not think it correct to raise an exception that is caught just before the function returns. You could state that it works the same, but it would not be using a goto statement. (P.S. I like the debating on RC, it's civilised) --[[User:Paddy3118|Paddy3118]] 21:07, 20 April 2009 (UTC) :-)
:: So what if we were to have a template for identifying when key language paradigms are used in a language? Would that obviate a significant amount of the need for tasks dedicated to those paradigms? I don't have time to make all of my points. I'm supposed to be working... --[[User:Short Circuit|Short Circuit]] 03:24, 21 April 2009 (UTC)
 
:: I've noticed that, and the Omit From exists for this reason. Some tasks can be done more easily in different programming paradigms... but this does not rule out automatically languages that can't use that paradigm, unless the point of the task is to show where the power of that paradigm is... '''and''' it wouldn't be too long to give that "functionality" to the lang; I've often thought about "cheating" for such language or paradigm-specific tasks... to me this is not wrong, since, if succeeded, you're surely teaching something about the flexibility of a language, while reaching the aim of the task (unless it is prohibited to use "tricks"... but sometimes it is not reasonable to put such a constraint).
 
:: Further reasoning about the Rosetta part and goto example: if a programmer is able to show how to use exception to simulate a goto which is not part of the lang of choice, ... why not? I believe sometimes people can get interested in such a creative use of the language... If the task is properly written (e.g. show how to hijack execution of code inconditionally from point A to point B...; explanation: think about goto in most well-known languages like BASIC), exception-based-languages' lovers can put their efforts in simulating a goto. The only limit (among the one explicitly given by the task) could be: how easy would it be? E.g. giving a full set of OO properties to C would take too long (lines of code), even though possible, and so to show that in a single page of RC could not be so pleasant for a reader. Moreover, it would be too long for all non OO languages; so sometimes, depending on the task and how it is written, it is natural to omit a language even though of course it could have the ability to achieve the task someway. '''But''', if there are few lines that are task-compliant in the final intention (reaching the ''result''), ... why not? Just to say, the presence of a "complex" syntactic sugar in C, achieved by intense (but short enough) use of macros and code, wouldn't ruin other "real" ''list comprehensive'' languages... the opposite: it would stress the strength of that syntax and paradigm for such a task. Back to Algol: it's short, and with my knowledges I can't see where it really differ from E, Clojure, Common Lisp, Erlang, Haskell, Python... but in syntax. --[[User:ShinTakezou|ShinTakezou]] 00:42, 21 April 2009 (UTC)
 
Describing some''thing'' and setting an example task is tough! it can be very difficult to give a task that is precise enough to only allow solution by ''thing'', and comprehensive enough to demonstrate all the features of ''thing''. I know I am incomplete in the RC description; and even the longer WP description has flaws; But what to do? If you see lots of solutions clearly showing how to complete the task, but make no effort to explain that it is the languages way of supporting ''thing'' then you could try and explain thing better, and/or refine the example task, and/or try and have example solutions removed that stray too much from the ''thing''. Welcome to my dilemma! --[[User:Paddy3118|Paddy3118]] 07:28, 21 April 2009 (UTC)
 
: My first solution is: do not remove Algol; and let's take time to think about it more deeply. My second more opinionable solution is to remove the first constraint (distinction of syntax between for loops and list comphrension): after all there exist languages that use a "list" syntax to loop, and it is the same they use to express list comprehension (Haskell ''docet''). Maybe a more relaxed constraint can be put, but I have no good ideas (yet). Let's take time to think about it too (I believe there's no need to hurry) --[[User:ShinTakezou|ShinTakezou]] 14:20, 21 April 2009 (UTC)
 
I suggest that this is not appropriate for a '''programming task''', which is meant to show how to ''solve'' a ''problem'' (according to the box at the top) perhaps using a particular type of data structure or algorithm, rather than display some specific syntactic sugar. If this sort of page is to be kept, it should be in a separate page category - eg ''Syntatic Feature''. --[[User:TobyK|TobyK]] 23:54, 9 August 2009 (UTC)
 
==J and set builder notation==
Could the J solution add a comment as to how the syntax follows set builder notation (or not)? It is a big part of being a list comprehension , and so it would be good if language examples would point out were they don't follow set builder notation (see the WP page); or point out where the similarities are - if it is hard to see. thanks. --[[User:Paddy3118|Paddy3118]] 19:51, 28 August 2009 (UTC)
 
:I have attempted to make this clearer. --[[User:Rdm|Rdm]] 15:19, 29 September 2010 (UTC)
 
==Is it time to remove some examples?==
There are several that make no attempt at following set-builder notation. (Maybe turn them into an omit from) --[[User:Paddy3118|Paddy3118]] 16:30, 16 November 2009 (UTC)
:That seems OK. "List comprehension" is really about the shorthand syntax, so examples that need explicit loops for this should removed. The omit option is best I think. Just make sure you keep examples that use set-builder-like language instead of notation. --[[User:Mwn3d|Mwn3d]] 16:36, 16 November 2009 (UTC)
 
== Ruby notes ==
 
Before I edited the page, the Ruby code used Enumerable#collect (also known as Enumerable#map) and Array#compact.
 
<lang ruby># no temp array, but a lot of housework to flatten and remove nils
(1..n).collect {|x| (1..n).collect {|y| (1..n) \
.collect {|z| [x,y,z] if x**2 + y**2 == z**2}}} \
.reduce(:+).reduce(:+).compact</lang>
 
I changed this to a mess involving Enumerable#flat_map and Enumerable#select, but have now simplified the code by using Array#keep_if.
 
<lang ruby>r = ((1..n).flat_map { |x|
(x..n).flat_map { |y|
(y..n).flat_map { |z|
[[x, y, z]].keep_if { x * x + y * y == z * z }}}})</lang>
 
The above code is now on the page. Contrast the below code, which uses Range#each (like 'for' loops in other languages) and Array#<< to append to an array.
 
<lang ruby>r = [] # start with an empty array
(1..n).each { |x|
(x..n).each { |y|
(y..n).each { |z|
r << [x, y, z] if x * x + y * y == z * z }}}</lang>
 
--[[User:Kernigh|Kernigh]] 04:38, 4 February 2011 (UTC)
 
== Minor correction in Prolog code ==
 
I'm not a Prolog pro, yet I'm curious why define my_bind predicate, if it does the same thing as member predicate?
 
== What can we learn, in retrospect, from a defective Rosetta 'task' ? ==
 
All human works fall somewhere in between complete success and complete catastrophe, and nearly 8 years later, after much productive work, but also, frankly, after too many skirmishes, objections and actual or attempted deletions, it's all too clear that there was something about this 'task' which, from the beginning, didn't quite ring true for everybody, and which has continued to prove divisive, and less than entirely satisfactory, even in recent weeks.
 
What can we learn from this, with the benefit of hindsight ? What additional work on the framing of this question, back in 2007, might have yielded more value and less friction in the years that followed ?
 
Let's look at it in relation to Rosetta's 3 goals, which are captured well, and formulated clearly, on the landing page:
 
:# "The idea is to present solutions to the same task in as many different languages as possible,
:# to demonstrate how languages are similar and different, and
:# to aid a person with a grounding in one approach to a problem in learning another."
 
'''As many different languages as possible'''
 
:'''Problem''' – An immediate failure in this axis. Many languages were effectively excluded by sacrificing Rosetta's principle of [[Rosetta_Code:Add_a_Task#Task_focus|Task focus]] to a preoccupation with a particular notation. This was immediately noticed and commented on at the the time, and was later argued to authorise moves to entirely delete notionally or notationally 'ineligible' entries for particular languages.
 
:'''Solution''' – In retrospect, more work should have gone into thinking beyond the surface notation, and clarifying the underlying class of problem. Entries could have been harvested from ''as many different languages as possible'' by framing the task in terms of efficiently defining and populating complex sets.
 
'''to demonstrate how languages are similar and different'''
 
:'''Problem''' – Not only was the number of eligible languages diminished by the slippage from task toward surface notation, but the scope for contrastive insight was also reduced. What is interesting about the definition and population of sets is that it can be done in various ways – for example with a monadic 'do' notation, with iteration, with structured recursion, etc. Ironically, the list comprehension notation, which is never part of core syntax, actually happens to conceal the variation in what is really going on in different languages. Python's list comprehensions are implemented, under the hood, as for loops (see http://morepypy.blogspot.co.uk/2008/06/list-comprehension-implementation.html) while Haskell's are syntactic sugar for a 'do' notation which in turn desugars down to lambda applications (see http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html).
 
:'''Solution''' - Richer insight into the differences and similarities between languages could have been yielded by explicitly inviting demonstration of ''differing'' approaches to defining and generating sets. List comprehensions could have appeared as notationally elegant solutions, compared and contrasted with other solutions.
 
'''to aid a person with a grounding in one approach to a problem in learning another'''
 
:'''Problem''' – Reduced language coverage and reduced scope for insight converged here to offer no help at all to learners of some languages, and reduced insight for those whose languages were covered.
 
:'''Solution''' – Understandable distraction away from the underlying concepts (and core editorial values) by what was, at the time, a novel notation, could have been mitigated by a discipline of stepping through Rosetta's 3 core goals, using them both as a kind of check-list, and as a stimulus to raising the game, and reflecting a little harder both on what the underlying issues really were, what list comprehensions really were (useful syntactic sugar for deeper processes in the core syntax of particular languages) and on what it would take to reach the largest number of languages, and the deepest and most useful levels of contrast, comparison and insight.
 
The Rosetta stone was useful precisely because the focus was on meaning and task, without distraction by notation.
 
If Ptolemy the V had said "use all the languages of the realm, but ONLY if they are written in hieroglyphics" then the stone would simply have been another lump of granodiorite, with much less lasting value.