11 ms·
Data munging in Perl 6 vs. Perl 5
- Mithaldu 12y agoTo be clear here, that Perl 5 code is not production grade code and i'd send anyone trying to commit that to a repo back to the hash mines.
- bglazer 12y agoCould you elaborate a little? I ask because the Perl 5 code looks a lot like the Perl that I write. I'd like to improve, but the existing Perl code that I'm writing on top of is really bad. Like really, really bad. I don't have much quality Perl to compare against.
- Mithaldu 12y agoTwo examples: $freq{substr $grade{$_}, 0, 1}++ for keys %grade; better: $freq{$_}++ for map { substr $_, 0, 1 } values %grade; best: my @letters = map { substr $_, 0, 1 } values %grade; $freq{$_}++ for @letters; ---------------------------- and open my $fh, '<:utf8', "grades.txt" or die "Failed to open file: $!"; my %grade; while (<$fh>) { m/^(\w+) \s+ ([A-F][+-]?)$/x or die "Can't parse line '$_'"; $grade{$1} = $2; }; better: use 5.010; use IO::All -binary, -utf8; my $line_format = qr/ ^ # line start (?<student>\w+) # name \s+ # gap (?<grade>[A-F][+-]?) # grade $ # line end /x; my $fh = io->file("grades.txt"); my %grade; while (my $line = $io->getline) { die "Can't parse line '$line'" if $line !~ $line_format; $grade{$+{student}} = $+{grade}; }
- hvs 12y agoVery nicely done. I use Perl in my everyday job, and its nice to see that some people still know how to write good Perl.
- Ultimatt 12y ago5.10 in production? Surely you're joking! 5.8 or bust.
- pjfl 12y agoYou should have use strict; use warnings; then you would have noticed the my $fh and the $io->getline error
- Mithaldu 12y agoDammit, you're right. I was working in a buffer without perl instrumentation enabled because i was composing a comment, not a script. Now i can't edit the comment anymore. :/
- peteretep 12y agoExactly. Perl's critics often completely overlook the degree to which liberal use of the map/reduce paradigm can simplify the graphical representation of your code and allow the powerful list processing features to be brought to bear. Consider: use strict; use warnings; use List::Util qw/reduce/; map { print } join "\n", "Distribution of grades by letter:", map { sprintf( "\t%s: %s student%s", @$_, $_ -> [1] == 1 ? '' : 's' ) } map { my $c = $_ ; sort { $a -> [0] cmp $b -> [0] } map { [ $_, $c->{$_} ] } keys %$c } reduce { $a->{chr(ord($b->[1]))}++; $a } {}, map { printf( "List of students with failing grades:\n\t%s\n", join ', ' , map { $_->[0] } grep {ord $_->[1] >68} @$_); @$_} reduce {push(@$a, $b); $a} [], map { printf( "${^A}'s grade: %s\n" , $_ -> [1] ) if $_->[0] eq $^A; $_ } map { $^A="Zsófia"; [split(/\s+/)] } <STDIN> The use of strict and warnings making this particularly Modern Perl, you could almost be forgiven for thinking you were reading Haskell...
- Ultimatt 12y agoneeds use feature 'say'
- deleted 12y ago[deleted]
- mercurial 12y ago> treating regex like it's normal code despite the fact that regex could match a keyword easily I'm confused by this statement. So you could match a Perl keyword with that regexp? What about it? > It's mixing looping logic with exception logic It depends on the context, but that's five lines of readable code. Exposure to 20th-century codebases may have lowered my standards, but I don't find it particularly shocking, especially for something that looks like a quick text file processing script. What do you suggest that makes for better code?
- mercurial 12y agoIt's definitely leaning toward the functional side, but some things look very odd (like calling "filename".IO...). The new operators leave me dubious (eg, '*' to create a one-argument lambda function). And '»'? At least the equivalent '>>' is apparently available, but damn...
- delluminatus 12y agoThe * operator made me laugh out loud. Only Perl would have an operator called a "Whatever star". Although, I actually think a lot of the stuff Perl does is really cool. I wouldn't want to have to maintain a codebase of it, but it never fails to be interesting. Like the whatever star. "*.value" basically saying, "Whatever value is here, gimme the value of it". It's different from a typical lambda declaration, but intuitive in its own way.
- munificent 12y ago> It's different from a typical lambda declaration, but intuitive in its own way. Isn't it pretty similar to Scala's use of "_"? I think _.value creates a one-parameter lambda in Scala.
- tormeh 12y agoYeah, but it would be neat if it was a word instead, for example "that". "*" is hilarious, though. How do you multiply in Perl if the star is taken? I also like that it's named "whatever star", reminds me of Scala's Pimp my Library feature[0] 0: http://www.artima.com/weblogs/viewpost.jsp?thread=179766 http://www.artima.com/weblogs/viewpost.jsp?thread=179766
- cygx 12y agoAn asterisk is only a Whatever if it's in term position: (* * *)(2, 3) will happily print 6.
- 12y ago
- discardorama 12y ago> "and is joined by the new < > variant for literal strings." ... why? What was wrong with {} or [] , as most other languages do? Sigh.
- masak 12y agoThe postcircumfix {} is still there, and used. It just unambiguously takes an expression, and doesn't try to intuit string quotes in some cases. So you use {} for indexing with a general expression, and <> for string indexing.
- discardorama 12y agoI dunno, this sounds like syntactic bloat to me.
- elektronjunge 12y agoWelcome to perl
- sigzero 12y agoI don't think the P6 is more readable myself.
- petercooper 12y agoPerl was my go-to language for 8 years before Ruby so I fancied a comparison. And.. Ruby is rarely as brief, but even with my Perl hat on, it seems much easier to read, especially if you didn't write it: Perl 6: say " {.key}: {+.value} student{"s" if .value != 1}" for %grade.classify(*.value.comb[0]).sort(*.key); Ruby: grades.group_by { |name, grade| grade[0] } .sort .each do |grade, names| puts " #{grade}: #{names.length} student#{'s' if names.length != 1}" end Or if it had to be as 'functional' as the Perl.. puts grades.group_by { |name, grade| grade[0] } .map { |grade, names| " #{grade}: #{names.length} student#{'s' if names.length != 1}" } .sort.join("\n") Both can be improved, of course! :-) I'd be keen to see a Python version actually because I know so few of its idioms but it often does well with these sorts of things as well..
- WayneS 12y agoAgreed, the new perl looks like Ruby. And I am willing to bet Ruby is more self consistent and easier to learn. (Says the perl 5 expert)
- kbenson 12y agoIn what ways do you not find Perl self consistent? There's lots or criticisms that can be leveled at Perl, but I'm not sure I follow that one.
- elektronjunge 12y agoA lot of the standard lib constructs behave completely differently in different contexts. Often subtly. For instance, @globvals = glob("*"); # returns all matches to @globvals $glob1 = glob("*"); # returns the first match and stores it in $glob1 $glob2 = glob("*.c"); # returns the second match of "*" and stores it in $glob2
- zzzcpan 12y agoConsistency is about expectations. It is possible to check if caller wants an array or a scalar and return either or a reference to either. And so nobody expects a single way of returning things across all the functions. Therefore such behavior is consistent.
- cletus 12y agoI don't mean to be snarky but... Ok, sorry I'm going to be snarky. In all honesty, does anyone even care about Perl 6 at this point? It's become the Duke Nukem Forever of programming languages as far as I can tell. Back in the 90s I remember the first CGI scripts I wrote were in Perl but really... the world has moved on.
- cant-be-serious 12y agoKool kid won't care, they're already builds next big thing with nodejs anyway..
- mercurial 12y agoMinus the snarkiness, that's not a bad question. The linked article doesn't showcase most of the interesting stuff in Perl 6 like optional typing, junctions or macros, but there are some cool things about it. That said, I think Python has eaten Perl's lunch, and who knows how things will evolve with the proliferation of statically-typed, non-verbose, fast functional languages? Personally, I'm not going back to dynamic languages as my primary workhorse.
- cygx 12y agoPersonally, the features I'm most interested in are ones you didn't actually list. They are - grammars - grapheme-based Unicode - implicit parallelism This is why Perl6 is still relevant today. Larry is hopeful that Rakudo can deliver sometime next year (not all of these features are quite there yet), but even if it doesn't, the language will remain of interest as long as there is no serious contender in sight.
- agumonkey 12y agoI'm not following the Perl community, but I loved seeing some of Damian Conway's talk (mostly on very very fine and inspiring first class grammar) on P6, do you know some good articles about Perl6 new/weird ideas ?
- hyp0 12y agoHaskell and ocaml fit the bill, but aren't new... which ones do you mean?
- themckman 12y agoGosh...I want my next job to be in Perl...it just looks like such a different language. It makes me smile every time I read it and read about it.
- deleted 12y ago[deleted]
- deleted 12y ago[deleted]
- Skunkleton 12y agoI feel like python provides a more readable solution. #!/usr/bin/env python3 with open('data.txt', 'r') as f: data = dict(x.split() for x in f if x.strip()) print("Zsófia's grade:", data["Zsófia"]) print("List of students with a failing grade:\n ",end="") print(*[x for x in data.keys() if data[x] == 'F'], sep=", ") print("Distribution of grades by letter:") for k,g in groupby(sorted(data.values()), lambda x: x[0]): print(" {}:".format(k), sum(1 for _ in g))
- viraptor 12y agoA working version with some stuff improved - groupby implemented, len() instead of sum(), a less squished version of printing, "student(s)" added: #!/usr/bin/env python3 from collections import defaultdict def invert_dict(data): res = defaultdict(list) for k, v in data.items(): res[v[0]].append(k) return res with open('data.txt', 'r') as f: data = dict(x.split() for x in f if x.strip()) print("Zsófia's grade:", data["Zsófia"]) print("List of students with a failing grade:") print(" " ,end="") print(*[x for x in data.keys() if data[x] == 'F'], sep=", ") print("Distribution of grades by letter:") grouped = invert_dict(data) for k, g in sorted(grouped.items()): print(" {}: {} student{}".format(k, len(g), 's' if len(g) > 1 else ''))
- Veedrac 12y agoNo need for `invert_dict`; you're just counting so `collections.Counter` would work fine: from collections import Counter with open('data.txt', 'r') as datafile: students = dict(line.rsplit(maxsplit=1) for line in datafile) failing = [name for name, grade in students.items() if grade >= 'E'] grade_counts = Counter(grade[0] for grade in students.values()) print("Zsófia's grade:", students["Zsófia"]) print("List of students with a failing grade:") print(" " + ", ".join(failing)) print("Distribution of grades by letter:") for grade, count in sorted(grade_counts.items()): print(" {}: {} student{}".format(grade, count, 's' * (count != 1)))
- codygman 12y ago
- jrochkind1 12y agoQuestion which is meant to be an honest question and not a troll, I really want to know and accept that some might have reasonable answers: Why would you use Perl6 instead of ruby?
- zzzcpan 12y agoIt depends. Why would you use Ruby instead of Perl 5?
- jrochkind1 12y agoRuby instead of Perl5 (not Perl6)? Because I found Perl5 really hard to write maintainable comprehensible code in, requiring weird magic boilerplate, and full of gotchas. Could just be me, maybe could have been overcome, was just my subjective opinion. And I like writing OO code in Ruby style. Also, like many others, what brought me to ruby was wanting to check out Rails (although now I'd say I have fonder feelings for ruby the language than I do for Rails the framework). All just my own opinions and experiences. Those sorts of answers from other's perspectives is what i'm interested in for Perl6 (not 5) over ruby. I think I know many reasons to prefer perl5 over ruby (although I don't), but once you leave perl5 for perl6... I'm not sure why you wouldn't just ruby (or python). But could be just cause you're used to Perl and like Perl. Or could be because there's something about Perl6 you especially like over ruby/python. Etc. I think it's a reasonable question?
- Ultimatt 12y agoYou wont get many opinions of people's experience of Perl6 from Hacker News. Just a lot of rage and assumptions it's somehow just like Perl5, which it's not. There are only a few of us (tens, maybe a hundred very quiet people) actually writing it daily. With no official "released" 6.0.0 version it's not supported that well by Linux distros yet either. Like if you install Rakudo on Debian stable right now it would be about two years out of date iirc. In the last two years a custom Perl6 VM was written with a JIT compiler and tonnes of concurrency stuff was added! You can however easily install it yourself and keep up to date with rakudobrew http://perl6advent.wordpress.com/2014/12/02/day-2-rakudobrew/ http://perl6advent.wordpress.com/2014/12/02/day-2-rakudobrew... My $0.02 is you'd mostly want to learn Perl6 if you were after something like Ruby but perhaps with more room to express yourself and form a community and build new technologies. At least I really love the language and find it very expressive and intuitive to use and it has a lot of features useful for doing Bioinformatics built in (something I'm going to add to the P6 advent calendar on the 15th Dec). The extra level of detail ten years of design puts into a language like all the funky features working together and being consistent helps a lot. So much of the cooler expressive/functional stuff in Python feels out of place like lambda and list comprehensions. Maybe I'm wrong but I wouldn't write anything /that/ complicated or important using Python lambda or list comprehensions. They just don't play that well with the surrounding code you will have to write in a different style. I can't attest to Ruby since I don't know it well. I felt it was quite close to Perl and I'd be better placed learning Python instead, especially for a job writing code that wasn't for the web.