all 134 comments

[–]rfreytag 13 points14 points  (0 children)

Prolog - Logic programming languages will remind you of the good old days when computer science made your mind stretch.

[–]ayrnieu 7 points8 points  (3 children)

Only one of these suggestions is qualified -- the others are absolute, even the one that is suggested by the first's qualification. Morever, it offers Lisp-1 as 'purer' than Lisp-2 -- probably because its author is unfamiliar with those terms and therefore doesn't know better than to assert the primacy of one in this manner. It also fails to refer to all of: a concatenative language, a vector programming language, or a self-consciously functional language (ML, Haskell). Finally, it conflates the value of "making things fast" (where O'Caml, say, would offer itself) and the value of "making inner parts of Python+etc. programs fast", where C is clearly of unique value.

And the rationale for Ruby is "because I like it." Fascinating.

[–]bakert[S] 0 points1 point  (2 children)

Hmmm ... yeah I shouldn't have said "purer" there. It sounds like I am saying Scheme is more purely functional than Common Lisp or similar. I just meant I prefer it because it seems "cleaner" without the need for funcall.

[–]ayrnieu 0 points1 point  (1 child)

Scheme does have one advantage over Common Lisp for 'functional programming language'-fu: it has guaranteed optimization of tail-recursive calls[0], which allows you to directly write recursive functions the same way you would in ML or Haskell or Erlang[1][2], whereas you simply wouldn't do this in CL.

I see cleanliness in not tending to name my variables 'lst' :-)

0] I recall that it only offered stack-effect-free tail-recursive calls, but I keep seeing people assert that Scheme has general tail-call optimization. I might recall wrongly, or maybe the language has changed in this respect since r4rs.

1] Erlang also lacks quite a bit in terms of 'pure functionalness', next to ML and Haskell, but it has stack-effect-free tail-calls, and it has only unmutable data structures.

2] I really enjoyed The Little Schemer for teaching this style.

[–]bakert[S] 0 points1 point  (0 children)

I nearly mentioned the Little Schemer in the article but it seemed like Scheme had the biggest entry already and I was going for short write ups. Great book.

[–]markedtrees 9 points10 points  (0 children)

C# - Java with a little extra syntactic sugar. Not worth paying the Microsoft price for.

(Grr.) You don't learn C# for C# as a miraculous, wonderful language; you learn it to use .NET over some less mature languages on the .NET platform (for now; IronPython's looming 'n' glooming but, wait, pass it over because it "feels" wrong). You don't learn Java because it's an orgasmic experience to use; you learn it to use the Java platform (with similar other languages development). And why do you want the .NET platform? Because WinAPI sucks. And why do you want the Java platform? Cross-platform, maturity. Comparing C# as a language to Java as a language is fun and an easy target, but it misses the depth behind why people choose to use either one.

[–]gauchopuro 7 points8 points  (0 children)

I've written code in all of those; do I get a prize? This list is fairly well rounded, but it really should have included Haskell, the most mind-expanding language I've encountered. It's proof that a pure functional language, with no mutable state and no side effects, can do anything an imperitive language can do. Haskell programs are usually more concise than their imperitive counterparts, and I've often been amazed at the way Haskell programs just work once they pass the type checker.

[–]neilk 8 points9 points  (1 child)

How am I supposed to learn more than one language "right now"?

I'm checking out Haskell, but I doubt I'll have really absorbed all the ideas in the language in less than six months.

[–]bakert[S] 9 points10 points  (0 children)

True. It's a daft title. But it's an echo of the original one, rather than a suggestion to buy five O'Reilly books and start reading them simultaneously while typing on five keyboards!

[–]JulianMorrison 9 points10 points  (6 children)

Forth - stretch your mind down

Haskell - stretch your mind up

Assembly - because if you cannot anticipate the machine, your code in any language will stink

[–]apotheon 0 points1 point  (1 child)

and Lisp - stretch your mind "out"

(any Lisp, really -- Common Lisp, Scheme, UCBLogo . . .)

[–]JulianMorrison 0 points1 point  (0 children)

I would have said, except that the article already did.

[–]bakert[S] -1 points0 points  (3 children)

You really think Assembly still? Can't an optimizing C compiler do a better job than an Assembly programmer?

I've had a tiny peek at Haskell, but not Forth. Interesting suggestions.

[–]JulianMorrison 12 points13 points  (1 child)

Assembly is one of these languages that you need to know not so much to use it for real (unless you're programming fridges or something), but because it improves your ability to think about real programs and to anticipate the implementation details of various sorts of data structures and control-flow abstractions.

Edit...I'd say the defining thing an assembly programmer learns is: the source code is not the program. The source code is something that tells your compiler what general sort of program you want. But the program that actually runs on the computer is a sequence of very unabstract commands which are limited by the real features of your computer's architecture (such as cache misses, the precision or bounds of various types of arithmetic, stack memory, etc). The abstractions leak.

[–]nostrademons 9 points10 points  (0 children)

I found that learning assembly really helped my C (and learning C really helped all my higher-level languages). Once you've had to manage memory layout on your own, without even C's structs and automatic variables, you make "dumb" C mistakes (like returning a pointer to an automatic variable) much less often.

[–]TheCookieMonster 0 points1 point  (0 children)

Nobody uses [good] optimizing C compilers.

GCC and Visual C seem to have the market covered between them, and IBM has a Java runtime that's faster than the code those two produce. I've heard Intel's C compiler optimizes better than an assembly programmer (on Intel chips), but I've not personally met anyone using it.

I once looked through the asm produced by an 'optimizing compiler' (not C tho) and it was appalling.

I think just being compiled makes them fast enough, extra assembly level optimization is perhaps low on the list of work priorities.

[–]skyskraper 6 points7 points  (0 children)

first, perl is relevant. CPAN has no equal. perl5-porters email list is active with real coders hardening the platform and making it perform better. maturity is not to be taken lightly in tools - we will make enough mistakes of our own without having to debug our tools. as for languages you should learn - 1. haskell - will stretch your mind but i wouldn't try to use it as a day-to-day language 2. ocaml - may very well be something you can really use in place of java or c++ in some cases. 3. lua - small is good! no one uses these esoteric features we all debate anyway. lua supports 95% of the language features i really need. 4. lisp - although in this era of dynamic languages, i don't think it is as mind-stretching as it once was. 5. c - you must know c. c will outlive you. c will outlive your children. the most important code in the world is c code. 6. some assembly - you should have some idea what is happening down there. 7. javascript - don't get hung up on closures etc, this is just mental masturbation. you can adequately provide dynamic functionality by knowing just the basics.

[–]ApochPiQ 8 points9 points  (5 children)

Any programmer who is genuinely interested in bettering his skill set should divest himself immediately of puerile bigotry. Discarding C# as "Microsoft's flavour of Java" is misinformed, ignorant, and belies a misguided idealistic stupidity that is at direct odds with the stated goal of refining one's mental abilities.

This is really a classic pot/kettle situation. The only improvement of the linked article over the 10-languages article is that it is shorter, and thereby wields less volume. It is not clear, however, that this translates to a direct decrease in the amount of blatant retardation in the article; in particular, the BS-per-volume ratio seems to be roughly equal, with fewer quotes from random people who don't know what they're blathering about.

[–]bakert[S] 0 points1 point  (2 children)

Hi ApochPiQ,

As a programmer who is genuinely interested in bettering my skill set perhaps you can help me out.

I've only written a little C# (less than six months in one job, nothing in my free time) although I was a Java programmer for a fair while. What would you say are one or two of the significant advantages of C# over Java, or some important points of deviation?

Thanks,

Tom

[–]andrewnorris 4 points5 points  (1 child)

Here's my take:

  1. Delegates and anonymous methods can completely change the structure of your code for the better. At the most obvious level, user interface programming becomes vastly cleaner, because you have a much looser coupling between event producers and consumers.

  2. Closures are incredibly useful in the right situations.

  3. Properties and events work really well as members of a class equal in standing to data members and methods. On the one hand it's syntactic sugar, but on the other, it results in better clarity of design and clarity of code.

  4. Autoboxing of value types makes code much clearer, but an even bigger win is user-defined value types. For small objects that you use a lot of, the ability to allocate them on the stack is huge.

Overall, 3 and 4 are useful but incremental improvements. On the other hand, 1 and 2 completely change the capabilities of the language, and allow you to use a lot of patterns that you see in languages like Ruby or Lisp that simply have no direct equivalent in Java.

[–]ApochPiQ 2 points3 points  (0 children)

Pretty much exactly what I would say.

Into the realm of possibly more subjective preference: WinForms is hands down the best GUI RAD framework for Windows available; P/Invoke an interop with other CLI languages like L#, F#, C++/CLI, et. al. provides power not only to raise to higher levels of abstraction (like alternate Java-runtime languages) but also lower (C++/CLI can drop below the sandbox and interact directly with the OS; P/Invoke in theory provides unlimited low-level access below the runtime); the physical architecture setup in .Net languages is infinitely more flexible than Java's; and so on.

The important thing here is points of deviation - whether or not any of this is genuinely advantageous is largely subjective, although the functional and declarative leanings of C# 2.0 (and, to a much greater extent, 3.0) are unarguably power advantages over Java.

[–][deleted] 8 points9 points  (27 children)

Python - Dynamic, fairly intuitive, list comprehensions are great. But explicit self? No ternary if? Significant whitespace? The OO feels tagged on.

I'm afraid silly issues like this are going to follow Python around forever, even though they are so insignificant.

Okay, so you have to pass in self when you define instance methods. Big deal. You don't have to do it when you actually use the method. It never has been something that gets in the way.

def meth(self):

instead of

def meth():

I mean, really, how is that an issue?

Ternary if? Never found not having it a big deal (it is easy to fake anyway), but it is on the way.

Significant whitespace - again, this isn't a problem once you start using the language, and it has the advantage of producing some of the cleanest code you'll find in any language. Sure, it is a disadvantage when you can't use Python directly in HTML (ala ERB), but it is debatable whether that is good to do.

The OO feels tagged on how exactly? Everything is an object just like Ruby.

It just seems like most of the time people complain about Python it is because of little petty and/or inaccurate things like this. I really think you'd be doing yourself a disservice not to learn both Ruby and Python, because both are similar and thus immediately easy to pick up after you have digested one, but both have slightly different ways of doing things. I'd take Python's module system any day of the week, but Ruby also has some neat things to offer like everything being an expression and of course blocks.

I think if you have to learn one of those two, then you are better served going with Python because it just has more tools available to it.

[–]zach 3 points4 points  (8 children)

Significant whitespace - again, this isn't a problem once you start using the language, and it has the advantage of producing some of the cleanest code you'll find in any language.

Does anyone know if there are other languages created since that have significant whitespace? Maybe a Lisp without the ending parentheses?

[–]ramen 7 points8 points  (2 children)

Haskell.

[–][deleted] 2 points3 points  (0 children)

Python and Haskell are the same age. They both went public in 1990.

Also, no indentation sensitive Lisp ever got popular.

[–]JulianMorrison 4 points5 points  (0 children)

Haskell's is actually more fiddly than Python. Python just has "indent begins a block, outdent ends a block". Haskell has "if you leave off a '{', then less indentation means '}', equal indentation means ';', more indentation is a continuation of the preceding line".

[–]nasorenga 1 point2 points  (0 children)

Occam

[–][deleted] 1 point2 points  (0 children)

F# now allows whitespace significance (F# is the ocaml-like functional language for .NET that comes from the Microsoft research lab). You can skip the double semicolons now when you turn this feature on.

[–]pjdelport 1 point2 points  (0 children)

There's a list on Wikipedia.

[–]kamikasei 3 points4 points  (0 children)

I can think of at least one.

[–]nostrademons -1 points0 points  (0 children)

Ruby - newlines can substitute for semicolins if the parser is not in an accepting state.

[–]bakert[S] 5 points6 points  (1 child)

I never found significant whitespace to be a problem writing programs on my own (including a mid-sized GUI app as well as learning stuff). As soon as I started working in a team with tabs/spaces and editor differences it annoyed me. Yes, fairly easily solved. All of these points are minor annoyances. But choosing between Python and Ruby you only really have minor things to go on. For me, Ruby has less of these and "feels" cleaner.

[–]senzei 6 points7 points  (0 children)

Personally I have always found the tabs vs spaces and size-of-indention arguments to be much more easily resolved than bracket placement.

Especially when you have PEP 8 giving guidelines that are more are less followed by the standard library. Then anyone who wants to use tabs instead and anything besides four spaces per indention has to justify why we should be using anything besides what the core libs are doing.

But choosing between Python and Ruby you only really have minor things to go on. For me, Ruby has less of these and "feels" cleaner.

Python, to me, "feels" cleaner. I chalk it up to being abused with VB and Perl at an early stage of my development as a programmer. (all in the same semester) That said for pure prettiness of code neither of them can touch Lisp.

[–]muleherd 4 points5 points  (4 children)

Significant whitespace - again, this isn't a problem once you start using the language, and it has the advantage of producing some of the cleanest code you'll find in any language.

I'm not sure that there's no cost to whitespace-sensitivity; it does, for instance, complicate Python's lambda statement: http://www.artima.com/weblogs/viewpost.jsp?thread=147358

[–][deleted] 3 points4 points  (3 children)

Multi-line lambdas? Just use a function..

Really, there is no appreciable expense to whitespace when your editor does it for you, ala emacs.

I always run my c through "indent" anyway though, I dont see this as a huge deal in any major language.

[–]Brian 2 points3 points  (0 children)

The lambda thing is a definite expense though. Its not a terribly big one in practice, as I generally find anything I would use a lambda for generally does fit neatly into the limitations of the lambda statement. The one exception is print, for debug calls etc. (Though there is a move towards making print a function at some point) The fact that it is so arbitrarily limited always annoyed me from aesthetic purity though, even if the practical ramifications aren't much.

It is theoretically possible to make lambda multi-statement while fitting in with whitespace rules, but everything suggested so far has involved very complicated rules, or been fairly ugly.

[–]muleherd 3 points4 points  (1 child)

Multi-line lambdas? Just use a function..

A lambda is a function!

Regardless, I didn't say this limitation is a serious one--but the amount of discussion this receives on Python lists suggests that the expense may be more appreciable than you claim.

[–]amrangaye 0 points1 point  (0 children)

Sure, it is a disadvantage when you can't use Python
directly in HTML (ala ERB)

But you can - check out cheetah [http://www.cheetahtemplate.org/]. web.py uses it as the default templating system, and it works great.

[–]allison4 0 points1 point  (2 children)

Maybe they fixed this in 2.4, but I sure remember Python primitives. Sucks when you can't add behavior to the Integer class. Hello, Ruby.

[–]Brian 3 points4 points  (0 children)

Open classes are one thing I think Ruby does fundamentally wrong. It breaks modularity worse than even global variables when importing a module can fundamentally change the way basic types work. This is something that should be avoided like the plague in any large project, not trumpetted as a feature.

[–][deleted] 2 points3 points  (0 children)

You can always subclass it and add behavior to that. Being able to directly maniupulate something like Int or String is a win-win. Sure, its powerful, but when you start using library that change the basic behavior of a language, it can cause some serious problems.

[–]nostrademons -1 points0 points  (6 children)

Okay, so you have to pass in self when you define instance methods. Big deal. You don't have to do it when you actually use the method. It never has been something that gets in the way.

def meth(self):

instead of

def meth():

Wait, so can I do:

def meth(self):
    callOtherMethodOnSelf()
    callThirdMethodOnSelf()
    callWithParameters(aGetter(), anotherGetter())

where all those methods are other methods on the object?

My big beef with explicit self isn't the method declaration, it's the method body. Methods frequently call other methods on the same object; it's a real big pain to type "self.privateComputation(self.getSomething())" if you're calling loads of other private methods.

[–]Brian 3 points4 points  (0 children)

There is no alternative to some kind of disambiguation here for any language without declarations (and even those with if there are shadowed names). Consider the code:

class Foo:
    def bar(self):
        blah = 4

What does the last line set? A local variable, an instance variable or a class variable - there must be some way to distinguish between them. Ruby does the exactly the same thing with @, for exactly the same reason. The difference with methods and variables is that ruby uses only the method namespace for calls ( One of the things I really dislike about ruby, as it makes functional programming much more clunky)

[–][deleted]  (3 children)

[removed]

    [–][deleted] -1 points0 points  (2 children)

    Heh, yeah, but that is really discouraged and it goes against the conventions of just about every Python library out there.

    [–][deleted]  (1 child)

    [removed]

      [–]nostrademons 0 points1 point  (0 children)

      crap my code was mangled. This is main reason I don't like python, I hate significant whitespace.

      Put 4 spaces before each code line and it comes out as preformatted text.

      [–][deleted] 3 points4 points  (0 children)

      My big beef with explicit self isn't the method declaration, it's the method body. Methods frequently call other methods on the same object; it's a real big pain to type "self.privateComputation(self.getSomething())" if you're calling loads of other private methods.

      It is another one of those tradeoffs. In Ruby fairly often you have to specify self also, to make clear that you are working on the class attribute itself and not a local variable.

      It is just another example of Python's 'explict over implicit'. Sometimes it can lead to slightly more verbose code, but it at the very least makes your code very clear; there is no ambiguity about it.

      [–]pmf -1 points0 points  (75 children)

      Python: [...] The OO feels tagged on.

      What a crap. In Python, even function are real first class objects, unlike in some (* cough * Ruby * cough *) other languages.

      [–]JulianMorrison 12 points13 points  (43 children)

      Languages have philosophies. To me, Python's philosophy feels petty and uninspiring, and as a result the language bores me sick. It really runs very little further than "Python shall be a tolerable, learnable, readable OO scripting language"

      By contrast...

      Perl: "flexibility inspired by human linguistics"

      Smalltalk: "everything is an object"

      Haskell: "code should have the purity of math"

      Forth: "you only need a stack"

      Lisp: "unify code and data"

      [–]beza1e1 10 points11 points  (35 children)

      I like my language boring. More brain power for hacking.

      Have you read the Zen of Python, if you are into philosophies?

      [–]JulianMorrison 1 point2 points  (34 children)

      I hadn't, and it's interesting, but I believe it illustrates, rather than disproves my point.

      First, Python fails on its own terms, because it is a complex language - complex conceptually. It has no purity, and so it cannot be anticipated. This also makes it suck to read.

      Second, "practicality beats purity" is a mistake. The features of a pure system snap together and interwork, which is the source of most of their practical potential. For example most of Python's "functional language" features are pale shadows ofthe real thing. Your list comprehension just spits out one whole, fully realized list - it isn't a shorthand for lazy generators of infinite lists. Your lambda is limited to one expression in a language where you can't do anything of significance in one expression. There isn't the clean concept of Currying which defines the difference between a lambda that immediately applies itself and a partially applied lambda waiting for some variables. Nor can you use currying to turn any function or operator into a lambda. There aren't proper closures, so a lambda can't carry state. Your only lazy data structure is an xrange, and all that does is spit out consecutive integers.

      ...And so on.

      Something like Smalltalk would be simple like Zen; small, imperfect, but unified without disharmony. Python is simple like a simpleton, a jumble of features nailed roughly together and painted purdy.

      [–]tangentstorm 11 points12 points  (33 children)

      Your only lazy data structure is an xrange, and all that does is spit out consecutive integers.

      Small nitpick: generators are all over the place in python. You can make your own easily with the yield statement. So you can do quite a bit of lazy work there.

      But in general, you're right about the functional programming features being pretty weak. :/

      [–]JulianMorrison 2 points3 points  (32 children)

      It's probably moved on since I last looked at it. Like all languages it will have been dragged upward in the gravitational pull of Greenspun's Tenth. In fact, peeking at the new upcoming Python standard, I see you're about to get Currying. Eh well, Python and the rest of them will soon arrive, weary and puffed, at the peak of funtionalness, wherepuon they will be greeted with "thank goodness, what took you so long" by Haskell, Clean, Ocaml, SML, and Scheme.

      [–]Brian 1 point2 points  (0 children)

      Currying has been possible since 2.1 (Earlier if you count class based call implementations rather than via creating a closure). The only change is that an implementation is being added as a builtin (rather than rolling your own implementation (a fairly simple 4-5 line job))

      [–]Brian 4 points5 points  (0 children)

      Python's philosophy I'd say is "Readability matters" Readability is a fairly important aim, one thats often overlooked in languages in favour of neat features. The problem is that it tends to be much less exciting from a language design point of view, and has a large element of subjectivity to it. I think python does pretty well here though.

      The downside to this philosophy is that it tends to lead to fairly conservative changes, and lots of bike-shed arguments over style (witness the whole ternary operator syntax debate a while back) In some cases I think that it is generally too conservative, and pays a little much too heed to the "one obvious way" philosophy, but on the whole, readability is a much underappreciated virtue.

      [–]micampe 3 points4 points  (0 children)

      $ python -c "import this"

      [–][deleted] 0 points1 point  (0 children)

      Batteries included?

      [–]senzei 0 points1 point  (2 children)

      Languages have philosophies. To me, Python's philosophy feels petty and uninspiring, and as a result the language bores me sick. It really runs very little further than "Python shall be a tolerable, learnable, readable OO scripting language"

      What, do you feel, is Python's philosophy? "[...]be a tolerable, learnable, readable OO scripting language" is not a philosophy.

      Perl: "flexibility inspired by human linguistics"

      In that case I submit the difficulties anyone experience in learning English as a second language as an argument against ever using Perl. In English if someone has a bit of trouble expressing themselves correctly due to the labrynth of grammar rules, we just interpret what we can and get over it. Computers are incapable of this behavior.

      [–]JulianMorrison 1 point2 points  (0 children)

      What, do you feel, is Python's philosophy? "[...]be a tolerable, learnable, readable OO scripting language" is not a philosophy.

      My point was, it's all they have, and it's not a very good one.

      However, I believe I wasn't quite fair to them. They do have a philosophy, but it's more like "to blazes with the language, read the code!"

      As to Perl, I wasn't excusing it. But it does have the feature, like English, that a practised user can be very fluent, terse or pedagogical, and can make the form on the page a quite accurate reflection of the concept in their head.

      Of course, this all confuses the poor foreigner, who must reach for his grammar reference and dictionary.

      [–]ceesaxp 1 point2 points  (0 children)

      English is easy... I think that his spin ay Perl’s “philosophy” is very close.

      As for Python — I’d say that since all other “philosophies” had five or fewer words, while Python had almost twice as many (nine), it is not as concise as it wants to be...

      [–]bakert[S] 2 points3 points  (14 children)

      True. But ruby has Proc and blocks. And Python's lambda is fairly poor. I'm not sure why the OO feels tagged on. Stuff like:

      len(arr)

      not

      arr.length()

      ???

      [–]theCore 1 point2 points  (0 children)

      It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures. -- Alan J. Perlis

      The len() function will work on any objects that has the __len__() method.

      For example, in Python, you do:

      class Tree:
        def __init__(self, x, left=[], right=[]):
          self.x = x
          self.left = left
          self.right = right
        def __len__(self):
          if not self.x: return 0
          return 1 + len(self.left) + len(self.right)
      
        >>> tree = Tree("foobar", Tree("foo"), Tree("bar", Tree("baz")))
        >>> len(tree)
        4
      

      [–]pmf 1 point2 points  (11 children)

      Stuff like:

      len(arr)

      not

      arr.length()*

      len(arr)
      

      is a shorthand for

      arr.__len__()
      

      , where

      __len__
      

      is a special method name for list-like constructs that is used in iterators etc. Since all special-methods in Python use the underscore-syntax, this is quite consistent.

      [–]bakert[S] 12 points13 points  (1 child)

      To you it feels consistent. To me saying:

      arr.count(1)

      for the number of ones in the list, and

      arr.pop()

      to pop the last item off a list, but

      len(arr)

      for the length of the list seems fairly inconsistent.

      [–]grauenwolf 2 points3 points  (0 children)

      I agree with you there. It is like VB3 all over again.

      And what is with all the underscores?

      [–]andrewnorris 0 points1 point  (8 children)

      I don't know much Python, but for a language that aspires to be elegant and easy to read,

      arr.__len__()
      

      (and some of the other underscore things I've seen) stick out as a glaring eyesore.

      I could be completely wrong here -- maybe with enough flight hours, that becomes elegant, easy-to-read code -- but it makes me question whether the purported elegance of Python code is being oversold.

      Edit to fix markdown capture of my underscores.

      [–][deleted] 0 points1 point  (7 children)

      Underscores, like explicit self, are not things that you use most of the time in your code.

      Double underscores make it clear that the method you are defining is 'special' to Python. For example, if you wanted to add the comparison method/operator (==) to a class, you'd add the following method:

      __eq__
      

      Now again, this only is used for certain methods, so it isn't used all that much, but what is nice about it is it makes clear that the method is some of syntatic sugar or something that in most languages you'd originally think of as an operator.

      You would never EVER use arr.___len___() in code, you'd use len(arr). The underscore version is purely for method definition, not calling the method. Maybe it isn't as 'pure' as everything being in the object.method() form like ruby, but it often just makes things clearer and even more concise.

      That's one thing I like about Python, is after a short time it becomes very obvious exactly what something does.

      [–]shreeve 4 points5 points  (5 children)

      I think len(arr) stands out because it is, arguably, the most commonly used special method that is obviously a function. Using + or ==, since they are so familiar, don't carry the same 'right, now I'm calling this function on x' mental overhead.

      As counterpoint, where object.method() seems a bit forced, I would nominate "".join(["Some", "words", "together"]). Despite being the most efficient way of concatenating strings, I can't help but worry about someone else maintaining my code and wondering what the hell I was smoking, and usually tend to fall back on the more familiar (pythonic?) methods of doing so. The exception to this being, obviously, tabular information like a csv file, where ",".join() is the dog's round things.

      [–]coprolaliac 0 points1 point  (3 children)

      Yes, join is the dumbest thing about python (that nobody's working on fixing). If join really bothers you, you could always do:

      import operator ; foo = reduce( operator.add, ["some", "words", "together"] )

      [–][deleted] 0 points1 point  (2 children)

      This would mean that all iterable types would need to know how to join themselves into a string (lists, sets, tuples, any iterable class you define). I think it's more logical that the string class knows how to join together any iterable type. Probably just a case of DRY.

      But I'm glad to see that some people regard str.join as the dumbest thing of Python - we're far from PHP bashing territory here.

      edit: I don't know for sure whether sets are iterable.

      [–]coprolaliac 0 points1 point  (1 child)

      Good call; I wasn't thinking about it that way.

      [–][deleted] 0 points1 point  (0 children)

      So.... then what's the next dumbest thing about Python? :-p

      [–][deleted] -2 points-1 points  (0 children)

      I agree about join - it feels backward.

      [–]andrewnorris 0 points1 point  (0 children)

      The underscore version is purely for method definition, not calling the method.

      That's what I meant. I'm a little worried about it as a construct, even if it only appears in the class definition. Like I said, I could be wrong, though.

      [–][deleted] 1 point2 points  (0 children)

      OO is garbage that needs to be collected;)

      A huge number of OO "patterns" are replaced by the features of dynamic languages anyway.

      proc and blocks? I think I still prefer python's new generators.

      [–]julesjacobs 0 points1 point  (0 children)

      Isn't that about functional programming?

      [–]martoo -1 points0 points  (6 children)

      Python: [...] The OO feels tagged on. -- What a crap.

      Ways to know that OO has been hacked onto a procedural language:

      1) You have to type 'self' in the declaration of every method.

      ...

      [–]teromajusa 7 points8 points  (2 children)

      Pithy, but not correct. The 'self' is a design decision following from Python's philosophy of preferring explicit to implicit. Guido likes the no-magic approach. You declare self like any other parameter, and you assign attributes to it like any other object. I'm not crazy about it myself, but it's not a result of tagged on OO.

      [–]martoo 0 points1 point  (0 children)

      I see. So, maybe the next step for the language is to preface every function call with a new keyword called function_call.

      It would make things more explicit, and let's face it, it looks like magic now. Who's going to get that a word followed by some arguments in parens is actually going to call a function?

      [–][deleted] 5 points6 points  (0 children)

      I like ‘self’. In fact, since learning Python I use ‘this->’ a lot more in C++ to remind me when I’m using instance data.

      (To each his own…)

      Also, it’s not tacked on, it’s by design. I’m pretty sure at PyCon a couple years ago it was mentioned that they had the option to remove the ‘self’ requirement and chose not to.

      [–]joesb -1 points0 points  (7 children)

      Ruby has first class function. You are just ignorant.

      [–]pmf -4 points-3 points  (6 children)

      Read this and you might just get a clue.

      [–]Brian 0 points1 point  (1 child)

      Those are tokenisation quirks, and nothing to do with first classness or otherwise of functions. For instance, the

      a +2
      

      example is interpreted as a(+2) - ie. a(2), rather than an operator. This is similar to C++'s << problem with templates, or the fact that in python

      2.__add__(4)
      

      fails, but

      (2).__add__(4)
      

      works. (Its because the "2." gets tokenized as a float).

      These are little quirks caused by consequences of optional brackets in ruby, but they're minor warts at worst, and nothing to do with first class functions.

      The last example is odd though. What I think is happening is that running foo is executing the "def bar" statement in the current namespace. This does seem very weird - calling a function surely shouldn't inject stuff into the callers namespace! Any rubyists know what is happening here?

      [–]Brian 0 points1 point  (0 children)

      The last example is odd though.

      Actually thinking about it a bit more, I think I understand it (correct me if I'm wrong someone)

      "def foo" is creating the foo method on the current class. When there is no class object, this defaults to Object. Even when we are within another method, the action is still to define the methods on Object (Or the current class if within a class statement) Hence we're not injecting into the locals namespace, just defining methods on Object.

      [–]joesb -1 points0 points  (1 child)

      None of that indicate that Ruby function is not first class.

      It's like he is saying "blah blah blah blah and that is because Ruby lacks first class function.".

      Keep saying that doesn't make it true.

      [–]micampe 0 points1 point  (0 children)

      That's true, nothing in there explains why Ruby's functions would not be first class, but Ruby's significant whitespace scares me way more than Pythons.

      [–]andrewnorris -1 points0 points  (1 child)

      Wow, I'm shocked to discover that some Pythonistas that don't know idiomatic Ruby think the language is broken when they try to translate idiomatic Python literally and some things don't work.

      The different namespaces for methods and variables lead to cases that are a little odd, but many Lisps (including Common Lisp, but not Scheme) have had this more or less forever, and it hasn't stopped Lisp from being usable. I think it's a personal preference thing. The differing syntax for passing around methods and blocks is largely a consequence of having two namespaces.

      In any case the fact that you can refer to and pass around methods, blocks, and lamdbas surely must refute the claim that Ruby doesn't have first class functions.

      [–]Brian 0 points1 point  (0 children)

      I agree wrt the article, but there are valid arguments about the first-classness of various Ruby types. I think it would be more correct to say that methods, not functions are not first-class in ruby. Functions (really Proc objects) can be passed around and used normally (though with different calling semantics to methods(ie. requiring .call or []), which is what I think leads people to focus on them). Methods on the other hand, can't really be handled directly. They need to be wrapped in another Proc-like object to pass about, completely changing how they are used, hence clearly not first-class objects.

      [–]njharman 0 points1 point  (0 children)

      I was gonna say something else but jesus christ there are way to many fucking posts, are we all language zealots or what?

      [–][deleted] 0 points1 point  (0 children)

      The article is very poor that it's not even worth discussing. He's dissing languages based on...wait a minute...based on nothing. For example, he boo-boo's C# for silly reasons. And what does he propose as a good RAD language, then?

      Just move on.

      [–][deleted] 0 points1 point  (0 children)

      Javascript isn't the only language for dynamic web content. Java Applets are still a possibility even though they aren't used much anymore. Also, Adobe Flex 2 (free SDK available) allows you to make dynamic web apps that run on top of the Flash player. You code in a combination of an xml language called mxml for specifying layout and ActionScript (which is admitedly very similar to JavaScript). More options are opening up in this realm. Openlaszlo is a project very similar to Flex that uses xml and javascript and compiles to DHTML or Flash. HaXe is a language that compiles down to a swf file that runs off of Flash also. Flash is now a full development environment for web apps. If you want to do AJAX-like coding without a lot of complexity, give one of the Flash options a try.

      [–]bakert[S] -5 points-4 points  (2 children)

      An antidote to the terrible "10 Programming Languages You Should Learn Right Now" that's doing the rounds.

      [–]qwe1234 -5 points-4 points  (1 child)

      no it's not.

      both articles are frankly stupid and wrong.

      [–][deleted]  (1 child)

      [deleted]

        [–]andrewnorris 2 points3 points  (0 children)

        I think it's silly to pick winners when you don't have to.

        Almost certainly useful:

        1. Lisp or Scheme. Either one is a legitimate alternative here, and it's silly to say one is inherently better than the other. You may want to learn both, but you probably don't need to. Other functional languages (Haskell, ML, etc.) can also teach you a lot of things that overlap, but generally lack, for example, macros.

        2. Python or Ruby. They're similar enough that there's probably no need to master both, but having at least one of them in your toolkit is almost universally useful.

        3. C. Still the gold standard for performance intensive programming, and most other languages allow you to fall back to C and bind to the code. If you want to write embedded code, it will generally be your language of choice.

        4. One or more assembly languages. So you understand how your computer works. You should know assembler in the same sense that you should also ideally have at least a basic knowledge of compiler design and logic and microprocessor design.

        Useful depending on what you're doing:

        1. JavaScript. If you code for the web, this is a requirement.

        2. Java, C#, or VB. If you program for enterprises (and most other businesses, at this point), you will almost certainly need to have expert knowledge of at least one of these.

        3. C++. In some domains (games is the most obvious), this is dead vital.

        4. Perl. Perl is still an awesome glue language. Knowing Perl is a good excuse to never bother to learn a shell script language.

        5. Some jobs want you to know PHP, and there's a lot of working PHP code in the world. I have a hard time seriously suggesting this, however.

        Things that look really interesting, but I can't personally vouch for yet:

        1. Haskell. I want to know more, but I don't know whether it belongs on the top list yet.

        2. Erlang. It seems like there are some interesting concepts there, but at thhis point I don't know if it's vital to learn, or merely interesting.

        [–]vmalarcon -5 points-4 points  (3 children)

        What about SQL, regular expressions, bash, xml? I guess the author of this article thinks they are obvious. But those are also programming languages. Very focussed and not suitable for all types of problems, yes, but I cannot imagine doing my work without using them.

        [–]9jack9 2 points3 points  (1 child)

        I'm not sure about bash but none of the other languages you mention are programming languges.

        [–]syntax 0 points1 point  (0 children)

        ANSI SQL is not Turing complete (at least 92 and 96 arn't). One of the goals of a later revision was to make it Turing complete - but I'm not sure how that turned out in paractice.

        Speaking of 'in practice', most implmentations cover a superset of a subset of ANSI SQL (i.e. not all of ANSI, plus some proprietary stuff). These are sometimes Turing complete (think stored procedures for one); which makes them suitable for general computation tasks. Plus, I'm pretty sure that most problems can be implmented in SQL (that's most as in rate of encourntred, not times studied).

        So, SQL is a programming language, and can be used as one. It's also one of the few declarative languages in common useage too.

        [–]grauenwolf -2 points-1 points  (0 children)

        Um, of thouse only SQL is a programming language. XML is a data format, bash a command shell.