2016-10-12 2 views
10

Perl 6 hat lazy lists, aber es hat auch unbegrenzte Range Objekte. Welchen solltest du wählen, um mit ganzen Zahlen zu zählen?Sollte ich in Perl 6 mit einer Sequenz oder einem Bereich zählen?

Und es gibt unbegrenzt Range mit zwei Punkten:

0 .. * 

Es gibt die Seq (sequence) mit drei Punkten:

0 ... * 

A Range erzeugt Listen von consecutives thingys ihrer natürlichen Reihenfolge. Es erbt von Iterable, aber auch Positional, so dass Sie einen Bereich indizieren können. Sie können überprüfen, ob sich etwas innerhalb einer Range befindet, aber das ist nicht Teil der Aufgabe.

Ein Seq kann fast alles erzeugen, was Sie wollen, solange es weiß, wie es zum nächsten Element kommt. Er erbt von Iterable, aber auch PositionalBindFailover, die die Positional Sachen durch eine Zwischenspeicher- und Listenumwandlung vortäuscht. Ich denke nicht, dass das eine große Sache ist, wenn man sich nur von einem Element zum nächsten bewegt.

Ich gehe hin und her auf diese. Im Moment denke ich, es ist Range.

+0

die Mailingliste 'perl6-language' oder der '# perl6' IRC-Kanal auf freenode könnte ein besserer Ort für eine solche Frage sein ... – Christoph

+4

Niemand wird die Antwort nach einer Woche finden. Die Leute finden Antworten auf Stackoverflow. –

+0

aber stackoverflow sollte mehr über praktische Probleme und weniger über die Feinheiten der Sprachsemantik sein; Ich bezweifle, dass du mit der praktischen Antwort zufrieden bist (benutze 'Range', da' ..' kürzer ist als '...': p); Ich bin froh, solche Fragen zu beantworten, aber ich bin mir nicht sicher, ob es wirklich passt ... – Christoph

Antwort

8

Semantisch gesehen, ein Range ist eine statische Sache (eine beschränkte Menge von Werten), ein Seq ist eine dynamische Sache (ein Wertgenerator) und ein faule List eine statische Ansicht einer dynamischen Sache (ein unveränderlicher Cache für generierte Werte).

Faustregel: Lieber statisch als dynamisch, aber einfach über komplex.

Zusätzlich ist ein Seq ist eine iterable Sache, ein List ist ein iterable Positions Sache, und ein Range ist eine geordnete iterable Positions Sache.

Faustregel: Gehen Sie mit dem allgemeinsten oder spezifischsten je nach Kontext.

Da wir es nur mit Iteration zu tun haben und nicht an positionellen Zugriffen oder Schranken interessiert sind, scheint die Verwendung einer Seq (die im Wesentlichen eine umrahmte Iterator ist) eine natürliche Wahl zu sein. Geordnete Mengen aufeinanderfolgender Ganzzahlen sind jedoch genau was eine ganze Zahl Range darstellt, und das ist persönlich das, was ich als am besten für Ihren speziellen Anwendungsfall sehen würde.

Wenn es keine klare Wahl gibt, neige ich dazu, Bereiche für ihre Einfachheit sowieso vorzuziehen (und versuchen, faule Listen, das schwere Gewicht zu vermeiden).

beachte, dass die Sprachsyntax stößt man auch in Richtung Range, die eher schwer Huffman-codiert (Zwei char Infix .., one-char ^ prefix).

+1

@briandfoy: Ich habe einige Gründe für meine Präferenzen hinzugefügt – Christoph

+2

"* Iteration passiert immer in Bezug auf Seq sowieso *" - Ich glaube nicht, dass 'für 1 .. * {}' jemals ein 'Seq' konstruiert. Wie ich es verstehe, sieht die For-Schleife 1, dass sie ein "Iterable" hat, 2) ruft ".iterator" auf, um einen "Iterator" zu erhalten, 3) ruft weiterhin ['.pull-one'] (https://docs.perl6.org/type/Iterator#method_pull-one) für diesen Iterator, bis er ein "IterationEnd" erhält. – smls

+1

@smls: hoffentlich besser jetzt ... – Christoph

-2

Es gibt einen Unterschied zwischen ".." (Range) und "..." (Seq):

$ perl6 
> 1..10 
1..10 
> 1...10 
(1 2 3 4 5 6 7 8 9 10) 
> 2,4...10 
(2 4 6 8 10) 
> (3,6...*)[^5] 
(3 6 9 12 15) 

Der "..." Operator Muster intuit kann!

https://docs.perl6.org/language/operators#index-entry-..._operators

Wie ich verstehe, können Sie nur einmal eine Seq durchqueren. Es ist für das Streaming gedacht, wo Sie nicht zurückgehen müssen (z. B. eine Datei). Ich denke, eine Range sollte eine gute Wahl sein.

+1

Ich habe das schon in der Frage gesagt. –

10

Sowohl 0 .. * als auch 0 ... * sind in Ordnung.

  • Iterieren über sie, zum Beispiel mit einer for Schleife, hat in beiden Fällen genau die gleiche Wirkung. (Weder wird Speicher auslecken, indem er bereits iterierte Elemente herumführt.)
  • Zuweisen einer @ Variablen erzeugt das gleiche träge Array.
  • Solange Sie nur Zahlen bis unendlich um einen Schritt von 1 zählen wollen, sehe ich auch keinen Nachteil.

    Der ... Sequenz Konstruktion Operator ist zwar generisch, dass sie auch auf

    • Zählung mit einem anderen Schritt verwendet werden können (1, 3 ... *)
    • Zählung abwärts (10 ... -Inf)
    • einem geometrischen folgen Sequenz (2, 4, 8 ... *)
    • folgen Sie einer benutzerdefinierten Iterationsformel (1, 1, *+* ... *)

    also, wenn ich so etwas tun sollte, dann würde ich ... für alle in der Nähe und verwandte "Count up by one" auch für Konsistenz betrachten.

    Auf der anderen Seite:

    • A Range effizient indiziert werden, ohne dass alle vorstehenden Elemente zu erzeugen und mit zwischenzuspeichern, wenn Sie also zusätzlich zu indizieren Ihre Zähler wollen darüber iterieren, ist es vorzuziehen. Das gleiche gilt für andere Listenoperationen, die sich mit Elementpositionen befassen, wie : Range hat effiziente Überladungen für sie, während die Verwendung auf einem Seq iterieren und seine Elemente zuerst zwischenspeichern muss.
    • Wenn Sie aufwärts zu einem variablen Endpunkt zählen möchten (wie in 1 .. $n), ist es sicherer, eine Range zu verwenden, weil Sie sicher sein können, dass es nie abwärts zählen wird, egal was $n ist. (Wenn der Endpunkt kleiner als der Startpunkt ist, wie z. B. in 1 .. 0, verhält er sich beim Iterieren wie eine leere Sequenz, was dazu führt, dass Kantenfälle in der Praxis richtig sind.)
      Umgekehrt können Sie sicher abwärts zählen, um sicherzustellen, dass dies der Fall ist Zählen Sie nie unerwartet aufwärts, Sie können reverse 1 .. $n verwenden.
    • Schließlich ist eine Range eine spezifischere/High-Level-Darstellung des Konzepts von "Zahlen von x bis y", während eine Seq das allgemeinere Konzept der "eine Folge von Werten" darstellt. Ein Seq wird im Allgemeinen durch einen beliebigen Generatorcode betrieben (siehe gather/take) - der ...-Operator ist nur semantischer Zucker zum Erzeugen einiger gebräuchlicher Sequenztypen. Es mag sich also deklarativer anfühlen, einen Bereich zu verwenden, wenn "Zahlen von x bis y" das Konzept ist, das Sie ausdrücken möchten. Aber ich nehme an, das ist eine rein psychologische Sorge ...: P
    Verwandte Themen