HNHacker News
TopNewBestAskShowJobs

ekiru

844 karma · joined April 6, 2009

submissionscomments
ekiru··on The context sensitivity of C’s grammar
Alternately, you can implement such context-sensitive features in another pass after the parse.
ekiru··on Linus Torvalds on Garbage Collection (2002)
Linus suggested in the OP that automated reference counting (where the language implementation handles reference counting for the programmer) is preferable to GC.

Python uses such reference counting (although it also has a GC fallback to ensure cyclic structures are collected).

ekiru··on Friends Don’t Let Friends Take Education Advice From Peter Thiel
> I don't believe there is a single CS course taught by a grad student

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.

ekiru··on Friends Don’t Let Friends Take Education Advice From Peter Thiel
> Sure Harvard may employ people who are titans in their field, Nobel Prize winners and the like, but unless you are going to Grad school there it won’t affect you any. They won’t be teaching you, TAs will.

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.

ekiru··on Immutability and Blocks, Lambdas and Closures
I use "variable" to mean "binding" exclusively.

> 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.

ekiru··on Immutability and Blocks, Lambdas and Closures
There are certainly other potential issues with closing over mutable variables. However, if Python's variables were immutable, it would have to create a new scope for the for body(either with statement-level scopes or by using internal iterators/higher-order functions instead of for statements).
ekiru··on Immutability and Blocks, Lambdas and Closures
The real issue is that Python's for construct doesn't create a new lexical scope for the body.

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?).

ekiru··on Real cost of C++ exception vs error-code checking
> It leads to horrendous abstraction leakage (I need to let every caller know I use FooBarWidget in the core of my application??),

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.

ekiru··on Teaching Perl to Undergraduates

  $_@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.
ekiru··on Three unique features of Lisp in 2010
And array/hash slices/elements, including the deletion of a key.
ekiru··on How Lisp macros differ from static code-generation and metaprogramming
What aspects of the actual behavior of loop are unspecified?
ekiru··on Given/when - The Perl switch statement
given/when isn't a switch statement. given and when are two separate constructs that happen to work well together for switch-statement-style purposes.

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.

ekiru··on Sony uses DMCA to silence speech that reveals its security flaws
Or someone selling you an operating system and telling you you can only install it on hardware purchased from them. These things are far from uncommon in technology. (I will refrain from mentioning the other example that came to mind because I don't wish to target a specific company to the exclusion of others, since such practices are widespread.)
ekiru··on Ela Programming Language
Why isn't that a good thing?

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.

ekiru··on Charging Objects in Ruby
Better than either of those, I think, would be

  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.
ekiru··on New to PHP 5.4: Traits
> (last one included wins) This is why Ruby doesn't do this.

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.

ekiru··on Remind HN: Vote
The problem with uninformed voters self-selecting to not vote is that the people who decide not to vote because they are not sufficiently informed tend to be in the middle range of informedness. There are many more people who are even less well-informed and have put less thought into their voting decisions who will vote.
ekiru··on Linux Journal: Readers' Choice Awards 2010 - Best Programming Language: Python
If a programmer writes code that is that bad in Perl, they will write code that is that bad in Python. They will write code that is that bad in C or in Ruby or in Haskell. No language will make programmers who don't care about good code to write good code.
ekiru··on Why Python?
How is this so? Decorators are just syntactic sugar for defining a function then replacing it with the result of calling another function (the decorator) on it.
ekiru··on IDE WTF
vim was released in 1991. emacs did exist 30 years ago, but it's certainly evolved quite a bit since then.

My personal emacs installation evolves regularly, although I will admit that it hasn't evolved at all today.

ekiru··on Ladies, look at your code. Now back to mine.
Perl 6 would do that like this:

@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);

ekiru··on Age discrimination in Perl 6 using subsets and multiple dispatch
I know that this is a pretty tame example of subset types. But do you really think that modifying the return values of person-age for everything in the system is more easily extensible than a subset type which is external to the objects? Suppose that somewhere else in the system, you want to dispatch based on whether a Person is old enough to legally drink alcohol. With subset types, you don't have to be aware of the Child/Adult/Senior partition at all. With the :after approach, you're dependent on the ordering of the after methods and you have to know about the existence of the :child/:senior/:adult test.

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.
ekiru··on Age discrimination in Perl 6 using subsets and multiple dispatch
Hi. I'm the author of the post.

> 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).

ekiru··on Ask HN: Weby: A new python template language, can I have some feedback please?
Apples and oranges are just different approaches to getting the nutrients one needs. It seems like an apt comparison. Whether the normal usage of "apples and oranges" is sensible is a different matter.
ekiru··on Free but Shackled - The Java Trap
The GPL version 3 includes a similar clause. You don't have to give up your patents. You just have to license them to anyone who has rights to use the code from a copyright perspective. If I understand it correctly, this gives the GPL sharper teeth, since someone who violates the GPL not only loses the distribution/derivative rights from the copyright license, but also the patent license.
ekiru··on Welcome Rakudo Star
Check out the PDF of the draft of the Perl 6 book in the R * distribution (as docs/UsingPerl6-draft.pdf or something similar).

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.

ekiru··on Rakudo Star - a useful, usable, "early adopter" distribution of Perl 6
This is now available via the downloads page linked from the announcement, as well.
ekiru··on Lost in Translation
> One caveat is often the audio and subtitles will vary (e.g. tu vs vous); I'm not sure why they do this.

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.

ekiru··on Desperate Perl Hacker
> Think of how non-radical PHP 4 -> PHP 5 and Python 2 -> Python 3 were, and how hard it was to get people to switch. Now imagine differences 100x those, and you can start to see Perl 6's relationship with Perl 5.

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.

ekiru··on Desperate Perl Hacker
I upvoted you because even though I disagree with what you're saying, there's nothing wrong with your having that opinion nor with your expression of it.

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.

← PreviousPage 4 of 10Next →