Saturday, June 17, 2017
Tuesday, February 24, 2015
Nim is the best programming language!
Many may discount the idea of "best programming language" with "all languages have positives and negatives and that no one language could be the best". But I believe, given a set of criteria we could compare various programming languages and attempt to figure out which one is better in most criteria. I will attempt to do so in this article.
And to those who may say that "languages don’t
matter; only algorithms do" - may I remind you - COBOL is (was?) a
programming language.
Just so you know where I am coming from - I am
very familiar with C (I have used it to implement x86 kernels) and Perl (I've
read and love the Camel) and have studied the following languages - Haskell,
Clojure, Go, Rust and Nim. (I'll leave Java and C++ out of the discussion
because they make me bitter). I consider myself as a power vim user - I
switched to Emacs about 4 years ago after being bitten by the functional bug.
Non criteria
Static vs Dynamic typing
One argument that supports Static typing is
that it helps in proving correctness. The argument against it is that one can
only prove that the types line up - whether the program is correct from the
programmer intention point of view is questionable. Second, it is argued that
static types help with refactoring. Again, to the extent of types aligning. Remember
sum = foldr (-) 0
is correct Haskell code - as in it compiles.
The argument for dynamic type system, in my
opinion is flawed - they talk about "compiler does not come in the
way" etc. - as in, one is allowed to write "incorrect code" and
are told about it only at run time.
Anyway, my point is - if you have to shoot for
correctness and speed (development and runtime) - shoot for a good design
first. The rest will follow.
Design is a somewhat diluted term in the
software industry so I'll go with Rich Hickey's definition - which is, I
paraphrase here - the art of breaking down a problem such that it can be
composed back. Essentially, your implementation must contain tiny modules each
of which do one thing. This, will help writing "evident code" that is
"obviously correct; instead of, without obvious mistakes"[0]. The type
system of the language per se does not help or come in the way of design.
IDE support
I'm just saying that I am not considering that
as a parameter for language comparison. If you think that's a grave omission,
you should stop reading this article here.
Indentation level as block structure
I can totally get it if you hate the idea. I
myself did not like it one bit. It was only after I studied Haskell that I
learnt to bear it and later love it.
So I feel - "Don't judge a language by
it's choice for block structure"!
Software Transaction memory, CSP style channels
Clojure has demonstrated that these things can
be built as a library when your language is powerful enough.
Criteria
Higher order function / Function as first class value
Lambda calculus is "Turing Complete"
and it contains nothing more than function definition and function application.
There are plenty of articles on the internet that demonstrate how, using just
the capability of function definition and function application, one could build
all the computing constructs - starting from numerals, booleans etc.
Even in "Why function programming
matters", John Hughes demonstrated how vital higher order functions are. Of
course, he also said that lazy evaluation is vital - I disagree there since one
can build "lazy evaluation" once equipped with higher order functions
[2].
Therefore, a programming language that has
first class functions is more powerful than a programming language that does
not have it.
Almost all modern languages (new versions of
old languages) support hugher order functions in some form or other.
Macro support
If the word macro evokes "C macro" /
"conditional compilation" in your mind, your probably also believe
macros are bad. On the other hand, folks from LSIP side believe that macros
give them that extra power (super power of programs that write programs [4]).
Therefore, a programming language that does
not have a "powerful macro" (access to AST at compile time) support
is inferior.
Languages (that I know of) that support macros
are - Lisp/Scheme, Clojure, Rust, Nim,
Strict (Applicative order) evaluation
According to "Why Functional Programming
Matters" - Lazy evaluation is one of the two key features that is
necessary for a language to facilitate modularity. The other feature being
higher order functions. Two points to keep in mind here
- Lazy evaluation can be implemented in strict languages
- http://matt.might.net/articles/implementing-laziness/
- Laziness mixed with IO is unpleasant (to put it very
mildly)
So I conclude that a language that has
Laziness by default and a tedious way to do/reason about IO is undesirable.
The only "mainstream" language that
has lazy evaluation by default and unreasonable (as in hard to reason about) IO
is Haskell.
Reach
These days I almost always have to deal with
Mac, Linux and Windows and switch between them. On top of that I play with
Raspberry-pi. So if I have to invest "10,000 hours" I'd like to it to
be in a language that I can use across all machines (of today and tomorrow).
A language that limits my reach is inferior to
the one that does not.
Only C and Nim are the good languages in this
category.
Ability to target machine code
It is a good idea to program an abstract
machine, instead of a real machine. However, not at the cost of never being
able to program a specific machine for it's cool features - or having to jump
through hoops to do it.
Generating native binaries also make it easier
to use it with other systems. Almost all languages (that don’t generate native
code) provide a mechanism to load shared libraries (DLL's) and invoke
functions.
Now, you may say that, so long as your job
gets done, it does not really matter if the actual machine code is executed vs
iterpreted by another layer of software. Also, you may argue that virtual
machines provide additional opportunities for optimization. I don't agree with
either.
First of all, I'd like to waste as little
cycles as possible. Now, battery life etc are legitimate reasons for it but I
argue that it is actually the essence of using computers - improving
efficiency. So, it does matter to me if I am not using optimum memory and CPU
cycles. I mean, if you use up more than required resources in "getting
your job", the remaining resources will limit what more can be achieved.
About optimization opportunity - yes, it is
possible to demonstrate some kind of runtime optimization that may not be
possible on today's hardware - but that can never be something that cannot be
fixed in the next version of the processor/compiler.
So, if your compiler does not emit native
code, it's inferior to the one that does.
Haskell, C, OCaml, Rust, Go and Nim are the
good languages in this category.
Memory management / Garbage collection
Garbage collection are of two kinds [5] -
tracing and non-tracing. The tracing variety is the most common and it involves
keeping track of which objects are "reachable" from root. This
introduces a fair amount of non-determinism in the runtime of the program.
Typically, the languages that have tracing garbage collector do not give direct
access to memory. So, if a language uses a tracing garbage collector and does
not give you a mechanism to handle memory directly then it's inferior to the ones
that give you direct access to memory and either don’t have garbage collection
or use a non-tracing garbage collection.
C, Rust and Nim are the good languages in this
category.
Summary
Based on the criteria that I came up with, Nim
is a clear winner :)
References
[0]
Simon Peyton Jones talks
[1] http://matt.might.net/articles/implementing-laziness
[2] http://www.cs.kent.ac.uk/people/staff/dat/miranda /whyfp90.pdf
[4] http://www.paulgraham.com/avg.html
[5] http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
[1] http://matt.might.net/articles/implementing-laziness
[2] http://www.cs.kent.ac.uk/people/staff/dat/miranda /whyfp90.pdf
[4] http://www.paulgraham.com/avg.html
[5] http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
Monday, February 23, 2015
Using nim with Visual C++ as the C compiler
Like everything else in Nim, its pretty straight forward. All you have to do is set the compiler to vcc in the config file - nim.cfg. The config file resides in a sub-directory called config under the Nim installation location. The default install location of Nim on windows is c:\Nim
Once you've set the C compiler, open a command prompt and set the environment variables up using the command as follows -
"c:\Program Files (x86)\Microsoft Visual Studio 14.0\vc\vcvarsall.bat" x64
You can omit the x64 bit at the end if you are interested in building 32 bit code.
That's it.
After that you can compile your nim programs using the usual nim c file.nim
Once you've set the C compiler, open a command prompt and set the environment variables up using the command as follows -
"c:\Program Files (x86)\Microsoft Visual Studio 14.0\vc\vcvarsall.bat" x64
You can omit the x64 bit at the end if you are interested in building 32 bit code.
That's it.
After that you can compile your nim programs using the usual nim c file.nim
Wednesday, November 12, 2014
Tuesday, November 11, 2014
Good HTML5 video
https://www.youtube.com/watch?v=WqV5kqaFRDU
The guy talks about reading and writing files in JS.
Also - mentioned indexdb - which is the persistence solution for webapp
CORS - cross origin resource sharing
EasyXDM - cross domain messaging - uses iframe
The guy talks about reading and writing files in JS.
Also - mentioned indexdb - which is the persistence solution for webapp
CORS - cross origin resource sharing
EasyXDM - cross domain messaging - uses iframe
Sunday, November 9, 2014
Creating a bootable HD image using grub
It is nicely documented here - http://tomermargalit.wordpress.com/tag/create-grub2-bootable-image-over-loopback-device/
#!/bin/sh -x
#!/bin/sh -x
dd if=/dev/zero of=out.img seek=8MB count=1k bs=1
outlo=`sudo losetup -f --show out.img`
parted -s ${outlo} mklabel msdos
parted ${outlo} mkpart primary ext2 32k 100% -a minimal
parted ${outlo} set 1 boot on
partx -a ${outlo}
mke2fs ${outlo}p1
mkdir -p /mnt/out
mount -t ext2 ${outlo}p1 /mnt/out
grub-install --boot-directory=/mnt/out/boot/ --modules="ext2 part_msdos" ${outlo}
#####
umount /mnt/out
partx -d ${outlo}p1
losetup -d ${outlo}
Friday, November 7, 2014
Starting a network service on Ubuntu 14.04 at boot
I run an Ubuntu 14.04 VM on my Mac Mini with Yosemite. For some reason I cant get "bridged" network to work so I have to stick to NAT. What I needed was for the VM to start a Remote Port forwarding onto the host Mac at boot - so that I could simply use ssh to log into my VM. I needed answers to the following questions for this -
1. How do I get my networking to start at boot?
I am not sure of this I had to do this - add
1. How do I get my networking to start at boot?
I am not sure of this I had to do this - add
auto eth0
iface eth0 inet dhcp
into /etc/network/interfaces
2. Add a cron job to ssh into my mac -
#!/bin/sh
x=`ps -Aef |grep 2222:localhost:22 | grep -v grep`
logfile="/home/kashyap/Desktop/log.txt"
if [ "$x" = "" ]
then
echo "Started the service" > $logfile
date >> $logfile
ssh -N -i /home/kashyap/.ssh/id_rsa -R 2222:localhost:22 10.0.2.2 &
else
echo "Service already running" > $logfile
echo "$x" >> $logfile
date >> $logfile
fi
Tuesday, November 4, 2014
Sonic Pi
A nice program for Raspberry Pi- works on regular machines to -
A nice video introduction by the creator -
https://skillsmatter.com/skillscasts/5809-live-coding-in-the-classroom
Sam talks about a couple of things here -
1. Why's programming guide to Ruby - I think it is this - http://mislav.uniqpath.com/poignant-guide/book/
2. live_loop :loop_name do
end
3. Examples in sonic pi are cool
A nice video introduction by the creator -
https://skillsmatter.com/skillscasts/5809-live-coding-in-the-classroom
Sam talks about a couple of things here -
1. Why's programming guide to Ruby - I think it is this - http://mislav.uniqpath.com/poignant-guide/book/
2. live_loop :loop_name do
end
3. Examples in sonic pi are cool
Wednesday, January 15, 2014
midi in clojure
It was a pleasant surprise for me to learn that core java ships with midi support. Mix that with clojure and one can have some music up and running really quickly
(ns music.core)
(import 'javax.sound.midi.MidiSystem)
(def synth (. MidiSystem getSynthesizer))
(. synth open)
(def mc (. synth getChannels))
(def instr (. (. synth getDefaultSoundbank) getInstruments))
(def yy (. synth loadInstrument (aget instr 0)))
(defn dhun [c f] (. (aget mc c) noteOn f 40))
(defn tune [f]
(new Thread (fn [] (loop [] (f) (recur)))))
(def beats (tune (fn [] (dhun 9 40) (Thread/sleep 500))))
(def lead (tune (fn [] (dhun 0 40) (Thread/sleep 500))))
Monday, January 13, 2014
Emacs24 on ubuntu 12.04 LTS
http://devajava.blogspot.in/2012/08/emacs-24-on-ubuntu-1204.html
To add this PPA:
$ sudo add-apt-repository ppa:cassou/emacs
$ sudo apt-get update
$ sudo add-apt-repository ppa:cassou/emacs
$ sudo apt-get update
Then, for emacs-snapshot:
$ sudo apt-get install emacs-snapshot-el emacs-snapshot-gtk emacs-snapshot
$ sudo apt-get install emacs-snapshot-el emacs-snapshot-gtk emacs-snapshot
*Or*, for emacs24:
$ sudo apt-get install emacs24 emacs24-el
$ sudo apt-get install emacs24 emacs24-el
Friday, January 10, 2014
Getting started with clojure on emacs
I found this link to be the most useful -
http://www.kedrovsky.com/blog/clojure-emacs-nrepl-and-leiningen
You need the following things installed -
- leiningen - http://leiningen.org/
- emacs - http://ftp.gnu.org/gnu/emacs/windows/
(require 'package) (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/")) (package-initialize) (when (not package-archive-contents) (package-refresh-contents)) (defvar my-packages '(clojure-mode nrepl)) (dolist (p my-packages) (when (not (package-installed-p p)) (package-install p)))
And after that
M-x nrepl-jack-in
Monday, April 8, 2013
Quick intro to git
Here are some quick steps to setup a project under git - Say, you have a project called project at /path/to/project
git add f1
1. Initialize the git repository
cd /path/to/project
git init
This will create a directory called .git at /path/to/project
2. git add file1 file2 ...
Add the files that you'd like to be tracked
3. git commit -m "comments for commit"
This will "commit the changes
After that, you can make changes to the file and then do a "git diff" to see the changes
Unlike other repositories, you need to do "git add" each time
Say, you make changes to file - f1 - to put the changes into the repository, you need to do
git add f1
git commit -m "comment"
Friday, March 15, 2013
Thursday, March 14, 2013
Running cron under cygwin
Not a big deal at all ... I got it working on windows8 today ...
All I had to do was - run cron-config (after installing cron under cygwin ofcourse) .. inside a cygwin terminal that was started as administrator!
Thanks to this link - http://stackoverflow.com/questions/707184/how-do-you-run-a-crontab-in-cygwin-on-windows
All I had to do was - run cron-config (after installing cron under cygwin ofcourse) .. inside a cygwin terminal that was started as administrator!
Thanks to this link - http://stackoverflow.com/questions/707184/how-do-you-run-a-crontab-in-cygwin-on-windows
Saturday, February 23, 2013
3 steps to HTTPS on Ubuntu
Got it from https://help.ubuntu.com/10.04/serverguide/httpd.html
1. sudo a2enmod ssl
2. sudo a2ensite default-ssl
3. sudo /etc/init.d/apache2 restart
SSL clinent/server using openssl
Telnet is nice program that allows us to create a TCP socket connection with a server and then interact with the server on the terminal. This ofcourse does not work when the server uses SSL. That is where openssl comes to the rescue.
openssl s_client -connect imap.gmail.com:993
Similarly an SSL server can be cooked up instantaneously -
openssl genrsa 1024 > key
openssl req -new -x509 -nodes -sha1 -days 365 -key key > cert
openssl s_server -accept 12345 -cert cert -key key
openssl s_client -connect imap.gmail.com:993
Similarly an SSL server can be cooked up instantaneously -
openssl genrsa 1024 > key
openssl req -new -x509 -nodes -sha1 -days 365 -key key > cert
openssl s_server -accept 12345 -cert cert -key key
Subscribe to:
Posts (Atom)