Or how to process a list using "Head" and "Tail" split with recursion.
In prolog language, "write()" is the way to print an item to the console.
As an example, you can do:
write("Hello World!\n").
to display the "Hello World!" with a new line.
However, it get really old when you want to "write" a mix of variables and strings to
display your result. Imagine you have the variable Name = "Rei", and you want to print
"Hello, Rei". You need to do
write("Hello "),write(Name),write("."),nl
to get
Hello Rei.
The more variables and text mashup you have the more tedious it becomes.
One way to address this problem is to write your own function to write
out a list. For example given the following list:
["Hello", Name]
where Name is a prolog variable which contains "Rei"
Your function - let's call it "writelist/1" with the ["Hello",Name] as its argument
should print an output as above.
I start his series as a way to keep my notes on how I learn
nodejs. If you have a comment or
a suggesting, please drop me a note.
Prerequisite
You should familiar with the following topics:
Computer programming. Experience with any programming language will do.
I recommend Coursera if you are looking for brushing up or learning a language.
JavaScript - Knowing JavaScript programming is definitely good.
But it is not a deal breaker. I didn't know anything about JavaScript
when I started this. I google most of the stuff as I go along.
Access to a computer. You should definitely have access to a working computer.
Any operating system will do.
"Node" runs on most of them.
You should definitely make sure node install on it.
Looking at https://nodejs.org for an instruction on how to install it on your computer.
You know how to create a text file and save on the computer
The very first example in the "Getting Start" section of the nodejs is to create a simple web server.
The code is very similar to what I have here in Figure 1.
In this example, the node creates an HTTP server. The server listens to the incoming HTTP request to the IP address 127.0.0.1 port 3333.
"127.0.0.1" is an internal address of a computer. Most, if not all, computers have one.
I also call it a "loopback" address - a lot of people too. "3333" is the TCP port number.
You can pick any number that is greater than 1024. We talk more about that later.
Figure 1. A simple "Hello World!" web server
// Most simple web server based on node
const http = require('http');
const srv = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/text'});
res.end("Hello World!");
});
const myAddress = "127.0.0.1";
const myPort = 3333;
srv.listen(myPort, myAddress, () => {
console.log("Listening on " + myPort);
});
Understand line-by-line
Let's go through each statement and see what they do.
The very first line on the top:
// Most simple web server based on node
This line begines with "//". This means that it is a comment. A comment will not be executed by "node".
I use it for readability and as a note to people who will be reading my program.
The second line is
const http = require('http');
This tells node that I want to use a module call "http". "node" will load the module and store
it in a constant variable name http.
In node, a module is used to manage code. Instead of writing your own HTTP server or include other HTTP server
code into your program, you can simply load a pre-built module and use it.
There are several advantages of using a module insteads of writing your own code. One is saving your time.
using a
The "http" module is part of the node distribution. You don't need to install any module in order to use it.
The next part is a little bit longer. But it is really simple. Basically, this section define a "srv" constant
based on http.createServer( ) method.
We define the srv such that when a new srv is created by a http connection it send out a text message
"Hello World!" with an appropriate HTTP header.
In previous steps, we prepare our code. We define things that we want our program to do, but we haven't
create anything,yet. In the last step. We instruct the srv to start listening on TCP port 3333.
The first to line define two constants that we will be using in srv.listen. These two constants are not necessary.
We can actually put these two values inside the srv.listen() - like so srv.listen(3333, "127.0.0.1", () => { ....
However, I have a habit of not using a constant ina system call. You can do it either way.
After the last step, you have yourself a mini web server listing to an incoming HTTP request on port 3333.
To test this, you can use your favorite browser, or a program called curl to make a request to it as follow:
curl http://127.0.0.1:3333
How you enjoy reading this. I will update this from time to time. Please stop by and make a suggestion when you do.
References
"https://nodejs.org" - nodejs site - retrived 2018-12-29
I can't believe that we only have a week left until 2017. Yeah, 2016 was just like previous year. Many promises and resolutions made. And how many have I kept. Let's see... So here is the list of what I intended to do and how did I do on them.
Learning new languages
For this one, I was hoping to learn new human languages. I did actually learn few words in Chinese. But not enough to make a conversation with people. And certainly can not read it. I also didn't get to use any of my Japanese. I was hoping that I keep up my reading, but I keep forgetting to do that. My Thais is still ok, I actually wrote a letter in Thais. One whole letter, LOL.
As a side note, I did manage to start learning a couple of new computer languages. But not a lot of usage in daily works. The primary language is still "C" - not even "C++". Most of the work done were also functions and routines.
I did managed to use "R" for quarterly report. The report is actually easily done in Word and Excel, but it is such a manual workflow. Using R with a couple of simple Bash scripts helps tremendously when it is time to create figures and table. However, I am still using PowerPoint to create my presentations. I am hoping to automate creating presentation also. This will be something that I will try to figure out for Q1 2017.
New Knowledges
This year I have seen a lot of growth in automation. There have been many tools that I use at work. As such I had to learn them too. Using containers - docker and Linux containers - is something new that I learn and use in 2016. Currently, I have migrated all my VMs to containers. No more Ubuntu Server VMs for code testing. I am using Docker containers exclusively for that. The only case which I am still running VMs are when i am trying to simulate network topology and testing related tools.
Learning Docker containers has been a major productivity improvement for me. Now I can not only spin up servers and services much quicker, but also using much less resources. With VMs, previously I had a couple of VMs running on my laptop. They consumes quiet a bit of disk space - about 4G-8G bytes per VM, and if I am at my mom's house, it is impractical to import them over slow Internet connection. Comparing to containers, the one that I use usually takes about 100M bytes. This is much improvement for me.
Personal, Wellbeing and Relationships
I managed to make a few people on-line which I think I can really call them my friends. Let's no name names here, cuz I don't think it matters that much. However, the relationships is real, and I am grateful for that. No new boy friend, or girl friend of the lover kind. I think it is cool and I kind of like it that way. Right?
I also got promoted at work. LOL. Imagine that. But that means I am going to more meetings. Actually meetings now becomes 50% of how I spend my time at work. Interestingly, the amount of works that I have to do does not seem to reduce. This means that I have to manage to get time to work on projects some how. Now I know why a manager spends time in meetings and boss people around. OMG super annoying. Like seriously. I also got to play a manager a little bit during Summer. My boss had a couple of Interns during the summer and I had to babysit them - j/k. They are super cute. It is great that we got an opportunity to get them for Summer. I actually learn a number of things from them. Mentoring them probably is the best thing happening for me this year. They are very smart and energetic and full of questions. Not only I have to relearn about technologies that they asked, but also learning how to have a good personal relationships with younger generations. I think Internship program works out great not only for the interns but also the company. I hope we can continue this again this Summer.
As to my personal wellbeing... I still meditate everyday, at least 5 minutes. But mostly I mediate about 20 minutes. Once in awhile - like monthly - I did about an hour. I think meditation is the best thing that I had learned since I remember - really. I keep this up for sure. If you have not tried meditation, I really encourage you to learn. There are a number of resources that can help you get start. Usually, you have one weekly class and you come back and practice at home. I learn to meditate at a Buddhist temple. My classes led by Buddhist monks. The class is secular. These monks are Thais and are English learner. I got to practice my Thais with them. The temple also fed lunch. Highly recommended.
I managed to gain weight. Actually, I don't have to really spend effort. I gained 8lb during summer - to 135lb. Must be because of the lunch with the interns. I am still about 2lb off from normal and a little far for my goal of 120lb. LOL. One day I should get there.
I think that's it for now. I got to go pick up my dog from the grooming place. Later K. Much love.
Sometime it is useful to create a "static" link "expect" package. This enable us to have a self-contained package without a worry if other tools or libraries are available. A use case is to have expect run on a Juniper router or switch. When you run a "flex" image on a switch with Intel processor such as QFX series, or a EX9200, it is possible that you can install your own utilities written and compiling by using either FreeBSD 6.1, or Junos SDK. In this example, I am using a FreeBSD 6.1 VM to build expect package.
Configuring Expect
Read the README file to understand the general idea and the prerequisites. Since expect is a derivative of TCL it is very likely that you will also need to install Tcl 8.4 also. Please check the TCL code for more information.
The following command is what I use to configure expect. This will also designate the location of the final directory to install into /var/tmp/expect
./configure --perfix=/var/tmp/expect --disable-load --disable-shared
After run the configure, it is time to run make to compile the software. The make will fail to build expect binary. But this is expected since we need to do a couple more things. I did the following modifications:
in Makefile line 397 - added "-lutil -static"
link libexpect545.a to libexpect.a using the following command: ln -s libexpect.a libexpect545.a
The above is called soft linking - which will make libexpect545.a an alias of libexpect.a. IMHO, this could be done in the Makefile and I may put my version on github at some point
Run make install - this time it should work fine and all needed files installed at /var/tmp/expect
I was trying to compile expect for an old OS today and got stuck with the following error when linking
ld: Cannot find -lexpect545
It turns out that the problem with the default Makefile is to just creating libexpect.so.1 which is a dynamic link lib. But there is no recipe to create libexpect545.so.
Fortunately, The fix is pretty easy. All I had to do is to link libexpect545.so to libexpect.so.1 with the following command:
ln -s libexpect.so.1 libexpect545.so
or if you are using static linking... try the following:
ln -s libexpect.a libexpect545.a
Yeah, I know. This is super annoying. How come they don't do it correctly. I probably should put mine up on Github just to track it.
Lately, instead of spinning up a full virtual machine to get some work done, I have bee experimenting with "container technologies", well, right now mainly is just "Docker"
I found out that it is possible to run a very lightweight container based on Ubuntu with a foot print of about 180M bytes. This is impressive considering a typical Ubuntu VM that I use for my web development work is usually about 8G bytes of disk space. LOL. Yeah, that is a big difference. Then I got an idea that may be I can strip down Ubuntu that I use to be a little bit more "skinny". While researching the topic, I ran into a result of CenturyLink's quest to find a smallest containers. This is where I ran into "Alpine Linux". The article said that the smallest foot-print is Alpine and it is about 5M bytes. When I read this part, I think to myself, "Wow, 5M bytes. Is it a type?" More research and it turned out that Alpine Linux already have several things on Docker Hub.
The following is my experiment to find out how big will the image be when I loaded it with all the Dev tools. Alpine's development package is called "alpine-sdk". It is really a meta-package which pulls down 52 separate packages. The total space is 184M bytes. You can see the detail in the following section.
Content of the "alpine-sdk" package when installed
Result docker images with all the "alpine-sdk" installed is about 182M bytes. I include based Ubuntu 14.04 and based "alpine" Linux for your reference
reia@reia-G770:~/Devel/github/dockers/alpine-sdk$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine-sdk latest 1d7cd1e6622e 6 minutes ago 181.3 MB
alpine latest 70c557e50ed6 7 days ago 4.798 MB
ubuntu latest e17b56e5200a 12 days ago 188 MB
reia@reia-G770:~/Devel/github/dockers/alpine-sdk$