Playing with Prolog at the moment, after looking through an excerpt of Seven Languages in Seven Weeks. Io looked cool, too, but I can't figure out an easy way to install it in Ubuntu.
I think Learn You Some Erlang is the best online tutorial.
Programming Erlang by the author of the language is the best book.
Erlang in Real Time is a pretty good book, too. Not sure if that's free online or not.
Spawn_link has a great set of tutorial blogs for introducing OTP, the library for building server applications from built-in server behaviors.
And my blog posts about solving some AI homework using erlang. I'll post some day about my MUD if it ever gets off the ground.
Also I just discovered this interactive online tutorial: http://www.tryerlang.org/
type 'ok.' to start!
I love the language and think it's actually pretty fun to write in and even debug. I just miss having libraries available for doing some of the stuff that Java and C# do for you out of the box. Then again, there's a lot of stuff for erlang out there that I don't know about, too.
DudleySmith wrote:I don't know which compiler you're using (Microsoft, maybe?) but gcc allows you to typedef iterator types without inserting the typename keyword. That construct is all over our code. As I said, I don't typedef iterators very often myself, so I wasn't sure.
The gotchas and nasties in the C++ syntax are not due to the people who wrote it not knowing about compilers, but due to it needing to be back-compatible with C syntax, and being unable to properly escape from them without breaking the back-compatibility.
I'm using gcc. Try the code I pasted and see. Dependent template type definitions pretty much always need a 'typename' added. Just using "vector::iterator" will do it. And I disagree about C compatibility in this case. They could have chosen a different syntax for type initialization that didn't cause the parsing ambiguity, chose different template typelist markers that didn't cause that ambiguity, etc, and still been C-compatible. There are other examples of decisions that might have been different if those involved had more experience writing compilers, such as exported templates. Now, there are a bunch of compiler folks in the committee--the EDG folks, Bjarne (obviously, etc)--but design by committee is a tricky thing.
I did a quick search on our codebase, and it's used lots. It might be conditionally compiled out though (the same codebase is compiled for 3 different OSes, 3 different graphics APIs and 3 different processors). I'll have to check tomorrow. Looking this up online, it's due to the possibility that a template specialization might redefine std::vector::iterator to something else, and the C++ standard states that std::vector::iterator is assumed to be a value unless it's prefixed by typename. The point of syntax is to be as unambiguous as possible. Apparently Visual Studio allows typedef std::vector IntItr; by trying the other interpretation if the first one fails. gcc takes the view that you've written incorrect code so it generates an error to force to do write it properly. We compile with -Wall and -Wpedantic and then pass it through a static analysis tool so I'm used to having to be anal about my code. Adding a typename keyword is minor compared to the hoops I have to go through keeping signed/unsigned variables right in the legacy codebase once the Indian and Russian outsource engineers have been at it.
What other syntax could you suggest here? This does not seem like a troublesome enough corner case to cause, for example, replace the double colon with something else for attribute scoping but not subtype scoping. I'd rather have the consistent notation everywhere than change half of it for this incredibly minor niggle.
Template are certainly untidy generally in C++ (and whilst you can do very clever things with templates, I'm fundamentally against the notion of "clever" code). I do see specialized templates as being code smell. Why are you using a template, a construct whose design benefit is enabling you to process multiple types in the same way, in a way that behaves differently for different types?
I think the compiler is probably just being conservative by defining a rule about dependent template names in general. In my example, the compiler should easily be able to determine that the token is a type name, but since it couldn't determine this in other situations (such as declaring a pointer type, since '*' is also the multiplication operator) I bet it just errors regardless. And because C++ doesn't (and probably can't, thanks to macros and the #include model) support look-ahead for symbols (ie. a prototype needs to proceed the use of the type/function/whatever), changing C++-specific syntax may not entirely help here. The pointer vs. multiplication issue, for example, is inherited from C.
One example of appropriate specialization from code I wrote recently is a data lookup table. Internally, the representation is a map of string->string, and the user can specify via a template param what type the underlying value represents. So the generic get() routine does a lexical cast on the value, but I have specializations for string and char* types that skip the conversion and return the string directly. Having only the generic version would work just fine, but it would be unnecessarily slow in instances where the user just wanted the string representation.
Here's something fun: the team at Bandcamp are hiring, and they have a little treasure hunt running in order to find the application details:
One example of appropriate specialization from code I wrote recently is a data lookup table. Internally, the representation is a map of string->string, and the user can specify via a template param what type the underlying value represents. So the generic get() routine does a lexical cast on the value, but I have specializations for string and char* types that skip the conversion and return the string directly. Having only the generic version would work just fine, but it would be unnecessarily slow in instances where the user just wanted the string representation.
I put all string handling in the "non real-time" code category, so I probably wouldn't be worried about optimizing that anyway. You just done nlog(n/2) string comparisons to retrieve the right entry from the map, and so saving yourself a lexical_cast (and some std::string allocation, presumably) at the end for string types when the client is more than likely about to do some I/O with the string is probably not worth the extra specialization code (and maintenance thereof) to do it. lexical_cast uses streams and the << operator to do its work, so it's probably being pretty efficient behind the scenes anyway.
We were only defining iterator types for templates with concrete types (e.g. vector(int) and the like). Template definition code is so messy that the extra typename in the definition is just another turd on the already large pile of turds in any case.
Not to split hairs, the actual implementation uses an unordered_map (ie. hashtable) so lookup is ostensibly O(1). But really, if the data is stored as a string and they ask for it as a string, why push it through a stream before giving it back if the fix is a few lines of code? Note that this is high-performance server code where the extra cycles really may matter. Also, the specializations are maybe 10 lines of code.
For anyone interested in broadening your programming language horizons, I'd like to recommend Seven Languages in Seven Weeks. It gives short but useful introductory tours of Clojure, Haskell, Io, Prolog, Scala, Erlang, and Ruby.
I'm loving Seven Languages in Seven Weeks. Finished with Ruby, Io, and Prolog (awesome for Sudoku and N-Queens), and I'm on to Scala now.
On a programming-related note, I've been in contact with a guy from MS doing surveys of Java developers (for Windows) who use MSDN. I didn't qualify, since I'm no longer a Java developer, but he's asked if I know anyone who'd be interested. I believe it pays $250 for a 45-minute phone survey, so if anyone's interested, shoot me a PM.
C# is startlingly fast. Java can also be really quick, too. C and C++ are still faster, but the bytecode languages are getting very good indeed. Perl, Python, and Ruby are much slower, and PHP is absolutely glacial in comparison.
At the end of this week I'll be changing jobs. I'll be going from a .NET environment to a PHP environment. I'm going to miss you, C#.
At the end of this week I'll be changing jobs. I'll be going from a .NET environment to a PHP environment. I'm going to miss you, C#.
That's rough. I'm just learning C# to tinker with Kinect, but I did a lot of work in PHP the last year. Not a fan. I'd much rather do Python and even Java.
Oh, I like PHP. I've just become very attached to C# over the years.
Hah. No, mostly I'll be writing PHP modules and add-ons for a CMS.
Or maybe I'm just overly optimistic.
Hah. No, mostly I'll be writing PHP modules and add-ons for a CMS.
Or maybe I'm just overly optimistic. :)
Hang on to that feeling. It may not last long..
Lex Cayman wrote:Hah. No, mostly I'll be writing PHP modules and add-ons for a CMS.
Or maybe I'm just overly optimistic. :)
Hang on to that feeling. It may not last long..
Indeed. I just never really liked PHP. Between being loosely typed and having so much bad code out there I ended up really missing Java and Python when I worked with it. I can live with a language that isn't strongly typed like Java. In fact I prefer them for some tasks. But at least with Python the strictures of the compiler and runtime force you to write code that's easier to read and more sane. PHP just felt like so much crazy soup.
Hmmmm... You guys give me warm fuzzies.
Do you think there's something inherent to PHP that causes these issues? Are there things I can do with my own code to avoid these issues? Besides not being strongly typed, it feels very C++ish.
Quick! Fill me up with knowledge!
My background is more in Java and Python so take everything I say with a grain a salt (in case you don't already ). But I would just advise you to find trusted PHP developer blogs, books, etc. and become familiar with those. The biggest problem is that since PHP is so loose and open to how you want to program it people do things many different ways. Some code PHP procedurally like the old ASP days. Some code PHP like Java and bring with them getters, setters and enforce artificial structure that PHP doesn't provide. Some people like to treat PHP like they do JavaScript and use lots of hashes and pseudo-objects and thus have a little structure, but not quite the formality and OOP of a C# or Java.
So I would just suggest you get a lay of the land where you're doing the gig, find some good reference material, and just try to produce something that will be maintainable. There are tons of issues in PHP with security and checking incoming data, etc. But largely there are good libraries to deal with that. What I really disliked about PHP was more the inherent disorganization of it all. It doesn't have to be that way, though. So I think you just read some best practices, figure out how you're going to approach things generally and be consistent. PHP is a language where you can create a robust object graph with dependency injection and everything or you can simply store everything in key value pairs. You might end up doing both depending on the situation, but in the end consistency and readability are going to be important.
Also, PHP has a ton of libraries for doing everything. I feel like in Java (and I've heard this is the same in C#), the community frequently coalesces around a few solutions to problems. Like with Spring there are a couple of competitors, but not many. Same with ORM tools. PHP, meanwhile, seems to have far more of these competing frameworks and libraries, so choose wisely.
EDIT: Oh, and last word of advice would be this. PHP seems like it went through a phase where everyone wanted it to be Ruby on Rails. So there are quite a few heavyweight frameworks that do everything from object marshaling to ORM to controller work. I found this particularly frustrating. I'd be looking for a simple controller to write RESTful web services and I'd discover that practically every one was "infected" with its own ORM solution. So I'd be wary of heavyweight frameworks. I know that you're working with one as you mentioned initially. However, if you add any 3rd party libraries into the mix beware that they may come with more than you want.
That all sounds extremely reasonable. I'll be working closely with one other developer who has been with the company for several years now. I'm sure he'll have his opinions, and I'll be able to provide my own input.
Also, IDEs. I've tried many. So far I'm actually really liking NetBeans. It's the most Visual Studio-esque I've found. After VS2010, I cannot go back to Notepad++.
Ha. Well, I won't be much help there. If I'm doing something that isn't Java I generally use emacs. I love emacs.
PHP actually has some pretty good IDEs. Some actually are pricey, believe it or not. If I were you starting out and didn't now emacs like the back of my hand I'd take a look at PDT, which is a plugin for Eclipse. I know that sounds evil, firing up Java to load a heavyweight Java IDE with a PHP Plugin, but I've used it and it works pretty well. Plus it offers some runtime niceties.
Otherwise the biggie is Zend. I believe Zend offers the ability to connect to an Apache port and actually debug through code, which can be nice.
Do you think there's something inherent to PHP that causes these issues?
Yes. Here are my issues with PHP:
PHP is an HTML templating language, which along the way has ballooned into a "full" back-end development language, in an extremely ad-hoc designed fashion. In many ways, it still is an HTML templating system with everything else grafted on. It's sort of humorous that there are HTML templating systems like Smarty written in PHP, sort of bringing everything full-circle.
As a consequence of being an HTML templating language, the separation between PHP and HTML is extremely low. For this reason, it has been the go-to choice of a lot of amateurs who have learned their way by "fudging" through problems - as once they've fudged through learning HTML, a dynamic language that is kind of an overgrown HTML templating system is the most gentle next step.
That lack of separation between PHP and HTML is a strong contributing factor to the large amount of bad PHP code out in the wild. This gets to your original question, about whether or not there are any issues inherent to PHP that cause issues. I will stop short of using the word "cause" (it is not impossible to organize PHP code well and enforce separation of PHP and HTML, but you are doing this job yourself - or your framework is - because the language doesn't intrinsically lead you down that path), but I will call it a contributing factor.
PHP is powerful and easy to deploy, which is why it has been used so much in the past. Today, though, a lot of PHP's use is inertial - the result of a lot of legacy code. One of the biggest PHP applications in the world, Facebook, would not be written in PHP if they started building it today. They've put a lot of engineering effort into working with PHP but it's almost entirely due to being lower cost to work around PHP issues than to rewrite all that legacy code.
PHP is a one-trick pony. It does web. It is possible, but ultimately pointless, to utilize PHP as a general programming language. Pretty much any of its immediate contemporaries - Ruby, Python, Perl, Java - are much more legitimately applicable to non-web uses than PHP is.
PHP's design, as mentioned above, is very ad-hoc. OOP, for example, was introduced in PHP4 in an incredibly shoddy and incomplete fashion, was improved in PHP5 (lots of people just like to say OOP was added in PHP5 because PHP4's object model was not worth recognizing or using) but still isn't quite up to par with PHP's contemporaries, and is still being hacked on now (see: Traits coming in PHP 5.4).
Another famous example of ad-hoc design is PHP's maddening failure to use consistent naming standards. No modern language compares to PHP's badness in this area. Function names and argument orders vary depending on the phase of the moon when they were added to the language. Legacy cruft remains all throughout the language. It's funny that Python has seen fit to go through the pain of breaking some backwards-compatibility to remove language cruft in Python 3, when Python 2 didn't hold a candle to PHP's cruft. PHP is like the Hotel California - cruft can be deprecated any time you like, but it will never leave.
And yet, I'll still happily use it over any solution slavishly chained to a Microsoft-only platform. Still, it doesn't sit at the top of my preferred language list.
In all fairness to companies like Facebook, my understanding of PHP on large systems (I've largely used Java, so I don't speak from completely authority here, only my understanding of things) is that it actually can be advantageous to use as a backend because it lends itself well to high throughput. From what I have heard you can get pretty decent performance out of banks of cheap Linux boxen running PHP through a light HTTP frontend. Java is not so kind. C# even less so in terms of the operating system being out of your control.
PHP, meanwhile, can be used with specifically compiled binaries that you yourself tweak your server for max performance. That's a major rabbit hole, though. I prefer languages that provide some structure, while still being cross-platform.
Legion is right, though. The legacy of PHP is interesting. I also laughed when someone told me I should start using Smarty. As if the PHP Ninjas had invented templating. Thank goodness for Python.
PHP is pretty performant and scalable, though Facebook uses their recently-open-sourced HipHop converter to transform PHP to C++, which they compile with the GNU g++ compiler.
That's the kind of madness I'm talking about. I hadn't even heard of going that route.
PHP is pretty performant and scalable, though Facebook uses their recently-open-sourced HipHop converter to transform PHP to C++, which they compile with the GNU g++ compiler.
I think for projects starting today, PHP is kind of in a no-man's land.
If you're trying to get up and running pronto, you're going to use something like Ruby on Rails, as Groupon is now, and Twitter did before. And if you're like Twitter and you grow to a point where Rails scaling is a concern, you're going to re-write parts piece by piece in something else. That's where Twitter is now: lots of front-end stuff still in Ruby/Rails, with back-end services having been converted to Scala and probably some other stuff too.
And if you're trying to build something big rather than just get-it-up-ASAP, you're either going to want something that provides better "big development" structure than PHP does (like Java), or do like Twitter or Google where you've got the more front-facing services in lighter stuff like Ruby or Python, and the heavier back-end services in C++, Java, etc.
Pages