844 karma · joined April 6, 2009
Python uses such reference counting (although it also has a GC fallback to ensure cyclic structures are collected).
Actually, this is incorrect. Although I'm not aware of any courses taught by grad students this year, I now recall that one of the lecturers also taught while a Ph.D. candidate. However, only a small minority of CS courses here seem to be taught by grad students.
Is this actually true? I don't attend Harvard, but I do attend a private university in the top 10 of the US News and World Reports rankings, and I don't believe there is a single CS course taught by a grad student (although some are taught by "lecturers". Some of the classes from the core curriculum are taught by grad students, but that's not actually necessarily a bad thing. Both of the grad students who have taught courses I've taken have been excellent teachers, which can be much more important for a teacher of introductory calculus or such.
> Sure, but it's not like immutable bindings are required for that, just go the internal iterator route and you're set for most cases.
Right. That's why in my first comment, I said that not creating a new lexical scope for the loop body is the real issue here. I didn't make it especially clear that it doesn't matter whether you do that using an internal iterator or by giving for statements a statement-level scope, but of the two examples I gave of languages with mutable bindings and the "correct" (IMO) behavior here, Perl 5 uses the statement-level scope approach, while Perl 6 uses the internal iteration approach(for is very light syntactic sugar for map).
I believe I misread your previous comment as suggesting that mutability was the key issue here. In response to that, I wanted to point out that even in a situation with immutable bindings, one still needs to have each iteration's binding be a different binding to deal with this case.
In either Perl 5 or Perl 6, both of which use mutable variables, the corresponding code does the right thing (although Perl 5 only does so if you actually use a newly defined lexical: as in "for my $m ('do', 're', 'mi') {...}").
Unfortunately, Python's implicit declaration of lexicals means that it would be difficult to do a for loop with an iteration variable that isn't lexical to the loop body if that was the default (where would you put the "nonlocal" statement?).
If your code catches any exceptions that might be thrown by its use of FooBarWidget, then you wouldn't need to specify it as an exception that your code might throw, right? If it doesn't, then your code exposes to callers that it uses FooBarWidget every time FooBarWidget throws an exception.
$_@qw()<>$@{}*&lc()~>>>$.$/$<$:
Which happens to appear to not be valid Perl code. $ perl -e '$_@qw()<>$@{}*&lc()~>>>$.$/$<$:'
Array found where operator expected at -e line 1, at end of line
(Missing operator before ?)
Scalar found where operator expected at -e line 1, near "$.$/"
(Missing operator before $/?)
Scalar found where operator expected at -e line 1, near "$/$<"
(Missing operator before $<?)
Scalar found where operator expected at -e line 1, near "$<$:"
(Missing operator before $:?)
syntax error at -e line 1, near "$_@qw"
Execution of -e aborted due to compilation errors.given temporarily sets the topic($_) to an expression. when smart-matches against topic and executes some code (followed by an implicit "next") if the match is successful.
given can be used without when and vice-versa.
given is useful for situations where you need to perform several operations on the result of an expression but don't want to name it, or in some cases, for when you want to emphasize an operation instead of the operand. For example, instead of 'say (some-long-complicated-expression.with-lots-of-calls-and-operators).perl', 'say .perl given the-expression'.
when can be used in given, but it can also be used in CATCH blocks (where $_ is set to the exception), or in for loops or other blocks where you are taking $_ as a parameter.
That criterion would cause you to dismiss Haskell because it looks different from what you're used to; the example code in the link is quite similar to Haskell code.
The most useful programming languages to learn are the ones most different from what you are familiar with. One would be much better off learning ML, C, and Smalltalk than Java, C#, and Python (in terms of their effect on one's understanding of programming; not necessarily on one's ability to find work). But a programmer knowing only C is unlikely to be able to read ML or Smalltalk with much understanding, nor would a Smalltalk-only programmer understand C or ML easily or a ML-only programmer Smalltalk or C.
allow url("your-url-here")
(with reject or something similar for the opposite).You could even drop the url method and simply write
allow "your-url-here"
if you only need to allow/disallow based on URLs.One of the primary purposes of traits is to fix the problem of having to linearize mixins/parents. Aliasing does ease the problems of linearization, but it doesn't solve them all.
If in a mixin-based system like Ruby you include two modules which initially have no conflicting methods, but at some point methods are added such that there is a conflict, the conflict is silently ignored.
Yes, you should pay attention to changes to the mixins you use, but linearization means that whenever a method is added to a mixin, being certain that your module/class has the right method means going through every single class that uses the mixin and looking at all the other mixins that class uses to ensure that they do not conflict. Traits make changing code easier by doing that checking for you. The one disadvantage is that if you want to ignore a conflict you have to say so, but I don't actually think that is a disadvantage: if a Ruby module says "include Foo, Bar" and both Foo and Bar have an explode method, someone reading the code can't tell if the writer of the code was aware of the two explode methods and chose to use the Bar method, or if they were unaware of the conflict and might have either wanted no explode method or the Foo explode method.
My personal emacs installation evolves regularly, although I will admit that it hasn't evolved at all today.
@employees.grep($predicate1 & $predicate2 & $predicate3);
The predicates can be a function, a regex, a type, or anything that can be smart-matched against.
Alternately, if you want to get the employees that match any of the predicates, you'd do the following:
@employees.grep($predicate1 | $predicate2 | $predicate3);
Or, if you want the employees that match only one of the predicates (think of xor):
@employees.grep($predicate1 ^ $predicate2 ^ $predicate3);
These can also be written, respectively, as:
@employees.grep(all($predicate1, $predicate2, $predicate3)); @employees.grep(any($predicate1, $predicate2, $predicate3)); @employees.grep(one($predicate1, $predicate2, $predicate3));
And, if you want things that match none of the predicates:
@employees.grep(none($predicate1, $predicate2, $predicate3));
You can combine these junction constructors. For example:
@employees.grep(all($predicate1, $predicate2) ^ $predicate3);
Here's the code for buy-beer in Perl 6:
subset CanDrink of Person where *.age >= 21;
subset CannotDrink of Person where *.age < 21;
multi buy-beer (CanDrink $person) { give $person, Beer.new }
multi buy-beer (CannotDrink $kid) { call-cops-on $kid }
No other code in the system need be aware of it. No other code in the system is affected by it.> The Perl 6 article is about all of the syntax that you need to understand before you can read the equivalent piece of code.
I think it's more that the Clojure article just shows the code with very little explanation. Whereas my post was intended to demonstrate some of the basic capabilities of Perl 6's multiple dispatch and type system for people who aren't very, if at all, familiar with Perl 6. People unfamiliar with Clojure can probably guess what the code in the Clojure post does. I think I was able to (although I've dabbled in Clojure and Common Lisp, so I can't speak from the viewpoint of a total newbie to those languages). Some of the Perl 6 syntax I devoted paragraphs to explain were probably as clear as (defrecord Person [name age]), but I chose to explain them exactly to be sure that any readers unfamiliar with Perl 6 were able to know the exact semantics(e.g., that readonly attributes are the default). Some of the syntax is not something someone who has never heard of Perl 6 will be able to look at and know the meaning of immediately. Is that really such a problem, if the meaning of such features(sans bugs in the implementations) can be explained and fully understood in a couple of paragraphs and make things much more convenient for the person who does know the language? You learn them in a day or two and benefit from them for the entire time you use the language.
In addition: the two pieces of code are not equivalent. The Perl 6 functions validate the types of their arguments. The age-group function can tell you the age-group of both a Person and an age. As well, if you want to write another multi dispatching on the age group of a Person, it's easier with the Perl 6, because you just have to do "multi can-have-kids-meal (Child $kid) { True }" and "multi can-have-kids-meal ($person) { False }".
> But, I wonder, what does "generally" mean? It means that you should read the rest of the paragraph to see some examples of its uses. Don't worry, though, the actual spec (http://perlcabal.org/syn/S02.html, grep for "The * character") is much more detailed. My explanation was a bit lackluster, I suppose, but I was trying to not devote much time to it, since the post is about multiple dispatch and the type system, not about the philosophy of DWIM as expressed in the simplicity and usefulness of Whatever.
> Oh. It means that sometimes -- even in the context of a trivial nine-line example -- the damned asterisk will mysteriously fail and will force me to bang my head against the keyboard for half an hour until I finally figure out that I just can't use it. Well, more like five minutes (from time that I noticed the problem until the time that I had figured out the cause of the bug in Rakudo). But, yes, there are still bugs in Rakudo. I doubt this particular one will be around much longer(although it'll probably still be in this month's Rakudo *, since the compiler release was Thursday).
The Perl 5 to 6 articles at http://perlgeek.de/en/article/5-to-6 are very helpful even if you aren't familiar with Perl 5. One thing to remember about them is that they describe Perl 6 as specified, regardless of whether any of the implementations fully support the relevant features.
The Perl 6 Advent Calendar from last Winter (http://perl6advent.wordpress.com/2009/12/01/perl-6-advent-ca...) is more of a "Here are some really cool things about Perl 6" series of articles, but they are also pretty good reads for learning the language.
I'm not sure of the reason behind this, but there are also often minor differences in the English audio and subtitles of films, even when the film was originally recorded in English.
While the radical difference between Perl 6 and Perl 5 might discourage adoption, I wonder if the less radical changes of PHP 4 -> 5 and Python 2 -> 3 may have contributed to their slow adoption. After all, if there is no radical benefit you will receive from switching your code to a backwards-incompatible new version of your language, it can be hard to justify doing so.
On the other hand, I simply cannot stand to write Python because the One Way to Do It that tends to be provided is rarely the One Way I Want to Do It.
It's okay that some communities and some languages say "There should be one-- and preferably only one --obvious way to do it", though. After all, if I believe "There's more than one way to do it", that applies to languages and communities, too. If a language whose community believes in only one way to do it makes you happy, use it. If you're like me and prefer having many options to express individual pieces of code however feels most appropriate for that specific situation(e.g., expressing a series of transformations on a list as either a list comprehension or a pipeline like series of feeds connecting higher-order functions), use a language that lets you do that. Neither is better for everyone. Nor is the programmer who prefers either type of language any better than the programmer who prefers the other.