Comparing Languages Through a Simple Task!
I find programming languages to be fascinating. There are so many different ways to express the same ideas and get the work done.
In this brief article, let us try to get a simple task of making a GET REST API call in different languages. It's doable in any language (including command-line). It's neither trivial like a "hello world" program nor complex as writing a full-fledged computer game, so its a good choice.
For neutral language comparison, I am going to "generate" code instead of "hand-coding" it - one reason is to avoid "bias" and another reason is that I don't know all the languages covered in this article. By generating code, I can compare the code and you can also replicate the same code independently in your machines in just a minute or so!
If You Are New To Postman
(Skip this section if you are already familiar with Postman). The example code segments are generated using Postman tool for making the REST API call, so head to postman.com website and download the tool from here. Once downloaded, press the Orange color "New" button and you are all set to try out APIs with Postman.
Using The meetup.com API
(Skip this section if you don't really care which GET API to call). For the illustration purposes, we are going to use the meetup.com API - the documentation is here. You can use any REST API with Postman, but here I am using this API because a) the API is simple & reasonably well-documented b) there is a "Try Out" area where you can play around calling the APIs.
The API we are going to try is GET API for meetup groups; yes, there are many more APIs that we can try out, but this simple one is sufficient for our article purposes. This is the AI & ML meetup group that we organize (join you haven't already done so): https://www.meetup.com/Bangalore-AI-ML-Meetup/. You can get details of this group programmatically by calling this API: https://api.meetup.com/:urlname. Replace the :urlname with the group name. In this case, it is "Bangalore-AI-ML-Meetup". If you make this API call, you'll get result like this one; or you can use Postman for the same:
{ "id": 25245944, "name": "AI & ML", "status": "active", "link": "https://www.meetup.com/Bangalore-AI-ML-Meetup/", "urlname": "Bangalore-AI-ML-Meetup", "description": "<p>This group is for anyone interested in Cognitive Technologies. Topics covered include Artificial Intelligence, Machine Learning, Deep Learning, Natural Language Processing and ChatBots. Unique aspects of this meetup: <br>* This meetup is for developers by developers <br>* More focus on hands-on and practical aspects (and least focus on theory) <br>* Focus on frameworks, libraries and toolkits and hands-on programming Ours are typically half-day meetups on Saturdays, and are hosted in corporates. All skill levels are welcome, but our focus will be on beginners to intermediate level (not advanced levels). Bottom-line: If you are a developer in Bangalore looking for up-skilling in AI, ML, DL, NLP, etc, this meetup is for you.</p>", ...
In Postman, under the "Save" button, you have a small Orange color "Code" button - click that and select from different languages for which you can generate code for this API call.
Ok, now on to the task!
Generating REST API Calling Code For Different Languages
cURL
From the command-line, you can make the curl call like this:
curl --location --request GET 'https://api.meetup.com/Bangalore-AI-ML-Meetup'
Simple and elegant! Of course, when the query gets complex (esp. with embedded double quotes, etc), it becomes messy to deal with escape characters, etc. Also you cannot use it for programmatically calling the APIs. Yet it is handy to use curl from command-line to make API calls like this - its simple and straightforward (though it takes time to learn how to use the command-line options). And also you don't have to deal with downloading dependency modules / libraries / packages like we have to do with programming languages. So, command-line is still a winner.
PowerShell
Let's give a try with PowerShell:
$response = Invoke-RestMethod 'https://api.meetup.com/Bangalore-AI-ML-Meetup' -Method 'GET' -Headers $headers -Body $body $response | ConvertTo-Json
Not bad, but not good either! What to say, as its name indicates, is really "powerful", but it didn't call itself "EasyShell" or "CoolShell", right?
C - libcurl
Yes, you can make REST API calls from the grand-old C using libcurl!
CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); curl_easy_setopt(curl, CURLOPT_URL, "https://api.meetup.com/Bangalore-AI-ML-Meetup"); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); struct curl_slist *headers = NULL; curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); res = curl_easy_perform(curl); } curl_easy_cleanup(curl);
Hmm, that's not nice code to write - we need to use a pointer (CURL*), do init, cleanup, and deal with crazy things that scream in capitals like CURLOPT_FOLLOWLOCATION... Easy to lose hair dealing with such code (need proof? I have become bald with early days in my career programming exclusively in C and C++!). Its nerdy fun, but often it isn't worth it!
Go
Go is a really popular language and is a replacement for C as a systems programming language. This is how the code looks like:
package main import ( "fmt" "net/http" "io/ioutil" ) func main() { url := "https://api.meetup.com/Bangalore-AI-ML-Meetup" method := "GET" client := &http.Client { } req, err := http.NewRequest(method, url, nil) if err != nil { fmt.Println(err) return } res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) }
Really, oh really, all this to make just an API call? And, if you thought the code will be nice and simple with Go, we're certainly disappointed. We need use low-level code to deal with too much of error handling - most of the time seems spent in checking if err != nil - sorry, I have other important things to do! I hate to say this, but honestly, I hate this code! Worser than C and verbose too :-(
Of course, we can argue that both C and Go are "low-level languages", but what does it really mean? Is calling REST API's a "high-level" or "low-level task"? (does it matter if our objective is to get the work done?)
C#
Here is the code using RestSharp:
var client = new RestClient("https://api.meetup.com/Bangalore-AI-ML-Meetup"); client.Timeout = -1; var request = new RestRequest(Method.GET); IRestResponse response = client.Execute(request); Console.WriteLine(response.Content);
Not bad at all - its concise and clear!
Java
Here is Java code that uses OkHttp library.
OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://api.meetup.com/Bangalore-AI-ML-Meetup") .method("GET", null) .build(); Response response = client.newCall(request).execute();
The code size is comparable to C# and the way the code works is different; however, that is due to the library differences and not really language differences. And, despite Java being infamous for being a "verbose" language (other than complaining how many times should we call Builder & build), it's not that bad!
JavaScript
Here is the code using the popular 'axios' package: (Earlier people would use 'request' package but it is deprecated now.)
var axios = require('axios'); var config = { method: 'get', url: 'https://api.meetup.com/Bangalore-AI-ML-Meetup', headers: { } }; axios(config) .then(function (response) { console.log(JSON.stringify(response.data)); }) .catch(function (error) { console.log(error); });
The asynchronous aspects in NodeJS immediately show up in this simple code itself with us having to deal with Promises. The code also shows how we are forced to deal with exception/error in NodeJs *every single time* when we don't wish to do so. Efficient approach to programming, but certainly, not a friendly language given its "eccentricities".
PHP
Here is the code in PHP:
<?php $client = new http\Client; $request = new http\Client\Request; $request->setRequestUrl('https://api.meetup.com/Bangalore-AI-ML-Meetup'); $request->setRequestMethod('GET'); $request->setOptions(array()); $client->enqueue($request)->send(); $response = $client->getResponse(); echo $response->getBody();
I think the creator of PHP loved dollars - '$'s - so much he/she has littered it everywhere in the code! It's straightforward code, but why so many calls to $request->'s? My eyes hurt reading them again and again - what's the problem if we could set the request url, method and options in one go? No thank you PHP, you can keep all your dollars, I don't want it!
Python
Here is the code that uses requests module in Python:
import requests url = "https://api.meetup.com/Bangalore-AI-ML-Meetup" response = requests.request("GET", url, headers={}, data={}) print(response.text)
Don't care if you call me biased, but this is such a cutie - such short, sweet, and straightforward code: loving it!
To express it poetically: The lark's on the wing; The snail's on the thorn; God's in His heaven—All's right with the (Python) world!
Swift
import Foundation var semaphore = DispatchSemaphore (value: 0) var request = URLRequest(url: URL(string: "https://api.meetup.com/Bangalore-AI-ML-Meetup")!,timeoutInterval: Double.infinity) request.httpMethod = "GET" let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data ?= data else { print(String(describing: error)) semaphore.signal() return } print(String(data: data, encoding: .utf8)!) semaphore.signal() } task.resume() semaphore.wait()
Really! Oh Really! It sucks having to deal with Semaphores and Tasks for this simple thing to complete! And my head is spinning (hasn't stopped yet!) trying to read and understand the code. Surprisingly this task is so common in mobile applications - which is one of the main reasons for using Swift. Thank you Swift, bye bye.
Ruby
Ruby often comes across in developer circles as language that helps writing very readable code and friendly towards developers. Let's see if it lives up to the expectations:
require "uri" require "net/http" url = URI("https://api.meetup.com/Bangalore-AI-ML-Meetup") https = Net::HTTP.new(url.host, url.port) https.use_ssl = true request = Net::HTTP::Get.new(url) response = https.request(request) puts response.read_body
It's certainly not as bad as Go, C, or Swift, but could be better and shorter and to the point. But do I really need to bother about host, port, ssl etc if all I care is to call the API to get the data? Good that I don't have to type meaningless semi-colons, but what's its love with so many ::'s instead of quickly getting to the point? Are developers serious when they say it is one of the best languages to write readable and understandable code?!
Ocaml
How many of you have heard or or used Ocaml? (I have heard but haven't used - its a functional language). So how does the code look?
open Lwt open Cohttp open Cohttp_lwt_unix let reqBody = let uri = Uri.of_string "https://api.meetup.com/Bangalore-AI-ML-Meetup" in Client.call `GET uri >>= fun (_resp, body) -> body |> Cohttp_lwt.Body.to_string >|= fun body -> body let () = let respBody = Lwt_main.run reqBody in print_endline (respBody)
No surprises why geeks who love to program in pure functional languages often complain of getting headaches! And clear & good reason why these languages are not mainstream!!
The Verdict
Python & command-line are clear winners in this simple task of making a GET REST API call. Closely followed by C#, Java and PowerShell. Next comes NodeJS/JavaScript, PHP and Ruby. The clear losers are Go, Swift and OCaml. Note that this is only for one simple task but it does give a taste of these languages, isn't it?
Agree, disagree? We programmers LOVE to argue about languages and its features, and which one is better and how the other person is wrong. Nevertheless, would love to hear from you! :-)
Engineer @ Honeywell
3 年It's not logically correct to compare all languages with a certain scenario. Let's take a scenario of team game . Do we really expect over boundary from all player ? neither same performance from each footballer. I believe there is deep thought and purpose behind every programming language. We know there are certain library in python which can multiply NXN matrix in 2 lines of code where we have to write 100 lines of hand written algorithm to implement same in C# or Java. Again, C# / Java / C++ Does gives great support of OOP where C , Python , Swift may not provide( It does but not as flexible as C# or Java ) . We know C is the master piece for system programming and hardware level Interaction where PHP , JavaScript , C# etc does not. So, to summery- Programming languages are king in there own domain. Let's not compare result with static set of question.