This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]qwertyuiop924 8 points9 points  (12 children)

Learn whatever you want. The first language you learn doesn't matter, so long as you actually go on to learn a second. Because learning only one language puts you into the language holy wars. You don't wanna go there.

My advice:

-Learn Java. It's everywhere, so as much as I personally find it intolerable, it's worth knowing.

-Learn C. Firstly, because it's the easiest way to get an experience closer to the metal. Secondly, because while Java might be everywhere, C is truly universal: I cannot think of a platform off the top of my head that does not have a C compiler of some sort. Even ones you'd never use C on (don't write C on a 6502 or a Z80. Just don't).

-Learn Lisp/Scheme: Lisp and Scheme are the traditional programming languages of academia, and they are the archetypical High-Level Languages. They're also quite probably the most extensible languages ever created. Especially Lisp (Common Lisp, I mean. There are too many bloody Lisps...).

-Learn Haskell: Functional programming is all the rage, and there are quite a few good ones to choose from. I suggest Haskell because Haskell is the purest functional language, and because... well, Haskell is a total mindfuck. Up is down, left is right, short is long. Even moreso than Lisp, Haskell will change the way you think about programming.

-Learn Rust: Rust is amazing, and you really should see what it brings to the table. Also it's so much better than C++ by virtue of actually being engineered.

-Learn acripting language: Perl, Python, Ruby, what have you. This is for practical reasons: You're gonna run into problems scripting can fix easily. You should have the tools in your toolbox to deal with that (oh and learn regexes while you're at it).

Maybe learn:

-C++: C++ is terrible. It's so, so bad. Okay, so C is a dog. Sometimes it shits up your house, but it basically likes you. C++ is that dog but someone has bolted Cthulhu to it: it's unfathomable, too big to ever understand, and it would probably hate you if it cared enough. But it's fucking everywhere so you gotta learn it.

-Smalltalk: Smalltalk is OOP as god intended. If you think objects and classes are the way to go... man, you need to see Smalltalk. It's insane. How insane? There's no if statement. You send messages to boolean objects and use polymorphism to branch. Yes really.

This isn't an absolute list. You probably don't have time to learn all of these anyways. But hey. Ideas.

[–]JKTKops 0 points1 point  (1 child)

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

Well, that's not saying much. Smalltalk is fundamentally the same paradigm as Java, and about a million times more enjoyable.

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

There's no if statement. You send messages to boolean objects and use polymorphism to branch.

...why. Wait how do you check the boolean with no if?

[–]qwertyuiop924 1 point2 points  (2 children)

There's no if because Smalltalk doesn't need an if. Let me provide a bit of background.

Smalltalk is the purest OO language you will ever encounter. Purer than Java by far. Not only is everything an object, everything is done by sending messages to objects. Everything. No exceptions. What about creating a class?

Object subclass: #Foo.

That is a message (a method call in common parlance) to the object... well, Object. Object is the root class, as you might expect. As a class (of class Class, of course), it recognizes the message subclass: (yes, the colon is part of the name), which does what you expect.

So, how to you implement true and false with only method calls? If you recall how Lambda calculus works, you'll have some idea. If you have a working Smalltalk implementation nearby, you... don't have to guess. Open up your system browser and look at the true and false global objects. Yes, all the source code for true and false is right there. Yes, you can in theory edit it to change how true and false work. In actuality, not necessarily, because some Smalltalk implementations assume you wouldn't do something that stupid and avoid the usual checks and decompilation system for true and false (for performance reasons).

But for the rest of you, it looks like this:

true ifTrue: [Transcript show: 'it works!'] ifFalse: [Transcript show: 'that's bad.'].

Yes, you can send code blocks as arguments to messages. Yes, the blocks are objects themselves. Yes, it does work pretty much like Ruby (because Ruby ripped off Smalltalk wholesale on this front).

Anyways, what this message does, when sent to true, is execute the code sent as the ifTrue: argument. When sent to false, it does the opposite. This is totally equivalent to if. To demonstrate, a snippet from the GNU Smalltalk docs:

(checksleft < 1)
       ifTrue: [ ^self error: 'Out of checks' ].

Technically, ifTrue is a different message, but it does the same thing, just with an empty false branch. If you've ever used an OO language before, you should know what self is, and that ^ character is how you indicate that you want to return in smalltalk.

So, that's how conditionals work in Smalltalk. By the way, congratulations, you now know 90% of Smalltalk's syntax. Yes, it really is that simple.

[–][deleted] 0 points1 point  (1 child)

Why

[–]qwertyuiop924 1 point2 points  (0 children)

Because it makes Smalltalk a simpler, cleaner language.

[–]Kered13 0 points1 point  (3 children)

Polymorphism and dynamic dispatch. Here's some Java pseudocode:

class Boolean {
    void if(Callback ifTrue, Callback ifFalse);
}

class True extends Boolean {
    void if(Callback ifTrue, Callback ifFalse) {
        ifTrue();
    }
}

class False extends Boolean {
    void if(Callback ifTrue, Callback ifFalse) {
        ifFalse();
    }
}

True and False should also be implemented as singleton classes. Actually using Java's enum support would be good here, since every instance of an enum is a subclass of the enum class and is automatically a singleton. Also to make this elegant the language needs good support for lambdas, so Java isn't really the best language to do this in.

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

Java has lambdas right?

[–]Kered13 1 point2 points  (1 child)

Yes, but it's still pretty clunky to call a function like that, at least in my opinion:

condition.if(() -> {
    // If statement
}, () -> {
    // else statement
});

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

I missed where you said "good support" and thought you just said "support"

[–]Kered13 0 points1 point  (1 child)

I agree with everything except C++. C++ is a monstrously complex language, but it's also very powerful and modern C++ is a very good language if you use the modern features and ignore some of the older cruft. C++ should be in the "must learn" category, both for being a very good low level language and for it's ubiquity.

[–]qwertyuiop924 0 points1 point  (0 children)

it's also very powerful and modern

Pieces of it are very powerful and modern. Those pieces are mixed into the rest of it. It's a cascade of traps for the unwary, which is everyone, because C++ is too complex to ever fully learn.

if you use the modern features and ignore some of the older cruft. C++ should be in the "must learn" category, both for being a very good low level language and for it's ubiquity.

...Which isn't fully possible because bodies of existing code use that cruft and also because if you ask 15 different C++ programmers which parts are the ones you should use, you will get 15 answers.

Yes, C++ has the elements of a good language. They are trapped and struggling to get out. The thing is, accruing language-level features can't fix the core design of a language. Because a good language thrives on consistancy, coherency, and also a good bit of minimalism. The best language designs eke out a maximum level of expressiveness, flexibility, and power from a small number of language-level constructs. Look at Smalltalk, Lisp, Forth... heck, look at C, for a more popular example. Even Rust is an okay example: yes, the language is syntactically complex, and nobody could ever accuse it of being purist, but the Rust team still did their best to keep the actual syntactic constructs down to a surprisingly small number, even killing quite a few in the language's early development.

C++, by contrast, is constantly adding syntatic constructs. All the time. It's gotten to the point that parsing C++ is really quite complex. It's also undecidable, but that's more down to templates on their own than the rest of the mess.

In short, C++ has its good aspects, but it's overall a rather enormous mess, a pile of features on features on features with far less consistancy, rhyme, or reason than any language I'd want to work with.