Home Theatre!

Due to a lot of turmoils in my life in the recent past, I had to shift with a friend. Abhinav has been an old friend and college mate, we have hacked on a lot of software and hardware projects together but this one is on of the coolest hack of all time and since we are flatmates now it solved a lot of issues. We also had his brother Abhishek so the hack became more fun.

The whole idea began with the thoughts of making the old laptops which we have to be used as servers, we just thought what can we do to make the best of the machines we have. He has already done few set ups but then we landed up on doing a htpc, it stands for Home Theatre PC or media centre, basically a one stop shop for all the need, movies, tv shows and music. And we came up with a nice arrangement which requires few things, the hardware we have:

  1. Dell Studio 1558
  2. Raspberry Pi 3
  3. And a TV to watch these on ūüėČ

When we started configuring this setup we had a desktop version of Ubuntu 18.04 installed but we figured out that this was slowing down the machine so we switched to Ubuntu Server edition. This was some learning because I have never installed any server version of operating system. I use to wonder always what kind of interface will these versions give. Well without any doubt it just has a command-line utility for every thing, from partition to network connection.

Once the server was installed we just had to turn that server into a machine which can support our needs, basically installed few packages.

We landed up on something called as Atomic Toolkit. A big shoutout for the team to develop this amazing installed which has a ncurses like interface and can run anywhere. Using this toolkit we kind of installed and configured CouchePotato, Emby and Headphones.

This slideshow requires JavaScript.

This was more than enough we could automate a lot of things in our life with this kind of set up, from Silicon Valley to Mr. Robot. CouchePotato help us to get the best quality of videos and Emby gives us a nice dashboard to show all the content we have.

I don’t use Headphones much because I love another Music Application but then Headphones being a one stop shop is not wrong too. All this was done on the Dell Studio Machine we had, also we stuck a static IP on it so to know which IP to hit.

Our sever was up, running and configured. Now, we needed a client to listen to this server we kind of have a TV but that TV is not smart enough so we used a Raspberry Pi 3 and attached it to the TV using the HDMI port.

We installed OSMC on the Raspberry Pi and configured it to use Emby and listen to the Emby server once we booted it up it was very straight forward. This made our TV look good and also a little smart and it opened our ways for 1000s of movies, music and podcast. Although I don’t know if setting up this system was more fun or watching those movies will be.

 

Advertisements

Writing Chuck – Joke As A Service

Writing Chuck – Joke As A Service

Recently I really got interested to learn Go, and to be honest I found it to be a beautiful language. I personally feel that it has that performance boost factor from a static language background and easy prototype and get things done philosophy from dynamic language background.

The real inspiration to learn Go was these amazing number of tools written and the ease with which these tools perform although they seem to be quite heavy. One of the good examples is Docker. So I thought I would write some utility for fun, I have been using fortune, this is a Linux utility which gives random quotes from a database. I thought let me write something similar but let me do something with jokes, keeping this mind I was actually searching for what can I do and I landed up on jokes about Chuck Norris or as we say it facts about him. I landed up on chucknorris.io they have an API which can return different jokes about Chuck, and there it was my opportunity to put something up and I chose Go for it.

JSON PARSING

The initial version of the utility which I put together was way simple, it use to make a GET request stream the data in put in the given format and display the joke. But even with this implementation I learnt a lot of things, the most prominent one was how a variable is exported in Go i.e how can it be made available across scope and how to parse a JSON from a received response to store the beneficial information in a variable.

Now the mistake I was doing with the above code is I was declaring the fields of the struct with a small letters this caused a problem because although the value get stored in the struct¬†I can’t use them outside the function I have declared it in. I actually took a while to figure it out and it was really nice to actually learn about this. I actually learnt about how to make a GET¬†request and parse¬†the JSON and use the given values.

Let’s walk through the code, the initial part is a struct¬†and I have few fields inside it, the Category field is a slice¬†of string, which can have as many elements as it receives the interesting part is the way you can specify the key¬†from the received JSON how the value of received JSON is stored in the variable or the field of the struct. You can see the json:"categories"¬†that is the way to do it.

With the rest of the code if you see I am making a GET request to the given URL and if the it returns a response it will be res and if it returns an error it will be handled by err. The key part here is how marshaling and unmarshaling of JSON takes place.

This is basically folding and un-folding JSON once that is done and the values are stored to retrieve the value we just use a dot notation and done. There is one more interesting part if you see we passed &joke which if you have a C background you will realize is passing the memory address, pass by reference, is what you are looking at.

This was working good and I was quite happy with it but there were two problems I faced:

  1. The response use to take a while to return the jokes
  2. It doesn’t work without internet

So I showed it to Sayan and he suggested why not to build a joke caching mechanism this would solve both the problems since jokes will be stored internally on the file system it will take less time to fetch and there is no dependency on the internet except the time you are caching jokes.

So I designed the utility in a way that you can cache as may number of jokes as you want you just have to run chuck --index=10 this will cache 10 jokes for you and will store it in a Database. Then from those jokes a random joke is selected and is shown to you.

I learnt to use flag¬†in go and also how to integrate a sqlite3¬†database in the utility, the best learning was handling files, so my logic was anytime you are caching you should have a fresh set of jokes so when you cache I completely delete the database and create a new one for the user. To do this I need to check of the Database is already existing and if it is then remove it. I landed up looking for the answer on how to do that in Go, there are a bunch of inbuilt APIs which help you to do that but they were misleading for me. There is os.Stat, os.IsExist¬†and os.IsNotExist. What I understood is os.Stat¬†will give me the status of the file, while the other two can tell me if the file exists or it doesn’t, to my surprise things don’t work like that. The IsExist¬†and IsNotExist¬†are two different error wrapper and guess what not¬†of IsExist¬†is not IsNotExist, good luck wrapping your head around it. I eventually ended up answering this on stackoverflow.

After a few iteration of using it on my own and fixing few bugs the utility is ready except the fact that it is missing test cases which I will soon integrate, but this has helped me learn Go a lot and I have something fun to suggest to people. Well, I am open to contribution and hope you will enjoy this utility as much as I do.

Here is a link to chuck!

Give it a try and till then Happy Hacking and Write in GO! 

Featured Image: https://gopherize.me/

The Open Organization

I was recently going through few of the Farnam Street articles, and I landed on the article on¬†how to read a book, where they basically describe how to read a book; ¬†the fact that there are types of books, and the fact that books can, in the words of Francis Bacon¬†‚Äúbe gulped, some books chewed and others digested.‚ÄĚ

This basically signifies the intensity and the level of awareness to have when you are reading a book. I have gulped lots of books, but The Open Organization is one of those, that I wanted to chew on.

I wanted to learn about how you can build an ecosystem where people are free to voice their opinions, where failure is be worn as a badge of honor for trying. This book filled me with thoughts of how would it be like, if an organization is really an Open Organization.

There are a lots of beautiful anecdotes that I came across, and a lot of values that were given in the book to think on.

The book talks about Purpose¬†and Passion.¬†People specially us Millenials,have been spoiled to an extent that we actually don’t run after money but after a purpose, after a problem. We don’t mind working crazy hours and being paid peanuts, but we do care about people, we care about how are we treated, we care about the problem we are after. One of the quotes in the book says Basis of loyalty is a common purpose and not economic dependency. A lot of people I know believe in this. When you unite with an organization which is after the same problem as you, it‚Äôs a match made in heaven.

The book talks about Passion, the passion about doing good, making a dent in the universe, but sometimes you realize Universe doesn’t give a damn .

One of the most amazing analogies, is when the book compares a structure of an organization with web architecture which is end to end and not center to end. Where there is no central point of control but there should be a central point of co-ordination. The organization is lead by leaders it selects, where Meritocracy is the idea behind every decision.

The other idea that was completely new to me was the difference between Crowd-sourcing and Open-sourcing.To be honest I had not thought open source to be a business model until the recent past. The thing with the wisdom of the crowd is that it works amazingly well when the work can be easily disagregated and individuals can work in relative isolation. I love the point in the book that says members of the organization should be inspired by the leader and not motivated. Motivation is something they already have and that is the reason they are joining your organization. I love this idea a lot because I have seen people complaining about their employees not being motivated enough. I think that this (lack of inspired leadership) is a reason.

“Great companies don’t hire skilled people and motivate them, they hire already motivated people and inspire them.‚ÄĚ – Simon Sinek

I really enjoyed the way the power of purpose is laid out in the book. The other idea was the idea of Meritocracy.¬† I think of ¬†merit¬†as having an amazing idea and idea being the sole reason for doing a certain action. Better ideas win, they are questioned and deliberated upon and that is how innovation happens in the organization. People debate over it, question it, trash it. People just don’t settle for something to avoid conflict. That very same complacency however is what has creeped into organizations where people don’t debate ideas just to avoid conflict so that everyone remains happy. It was so amazing to read stories where someone thought out of the box and wanted to bring in a new way of doing things and how he convinced everyone that this is the right way of doing things, we ought to give it a try.

This book pushes back on the belief in hierarchy and brings to limelight lateral structure, letting people know that the conventional ways of running an organization might have to change, upgrade as it were, to a newer version.

I got a lot of amazing ideas and to be honest I got to know how a person in an organization should be treated. I was awestruck with the insights in the book. Wish someday I could mould an organization in this way. Theories are always romantic, hope the execution and implementation is beautiful as well.

Dockah! Dockah! Dockah!

Dockah! Dockah! Dockah!

I have been dabbling with docker for quite sometime, to be honest when it was introduced to me I didn’t understand it much but as time passed and I started experimenting with it I got to know the technology better and better. This made me understand various concepts better. I understood virtualization, containerization, sandboxing¬†and got to appreciate how docker solves the problem of works on my machine.

When I started using docker I use to just run few commands and I could get the server running, this I could access through browser that was more than enough for me. When I use to make changes to the code I could see it getting reflected in the way I am running the application and I was a happy man.

This was all abstract thinking and I was not worried about what was going inside the container, it was a black box for me. This went on for a while but it shouldn’t have, I have the right to know things and how they work. So I started exploring about the realm and the more I read about it the more I fell in love with it. I eventually landed up on Jessie’s blog. The amount of things she and Gautham¬†has taught me is crazy. I could never think that docker being a headless server could actually be used to captivate an application in such a way that you decide how much resources should be given to it. We at jnaapti have been working on various other possibilities but that for some other time.

So yeah there is more to just starting the application using docker and get things to work. So let’s try to understand few things with respect to docker, this is purely from my experience and how I understood things. So containers are virtual environments which share some of the resource of your host operating system. Containers are just like Airbnb guest for which the host is the Operating System. Containers are allowed to use the resources only when the user of Operating System gives them permission to use. Now the way I use them is basically in two ways, Stateful containers or Stateless containers, stateful being the one which has some data generated and stored in them while stateless is the one which doesn’t have any dependency on data.

Let me show you one of the use case that I generally use containers for; Now people may disagree and say I am exploiting it or using the power for wrong purpose but to be very frank if it solves my problem why should I care XD. Now, imagine I want to learn to write Go¬†and I don’t want to install it on my system but have an isolated environment for it. There are two ways I can pull a docker image which has Go¬†in it or get a normal image and install go in it. An image here is just like an iso¬†file which is used to help you install an Operating System¬†on your machine. Let’s see what all images I have on my machine,

I would run docker images and the output looks like this:

docker-images
docker-images

This shows that I have a znc¬†image I use it to run a znc¬†bouncer. Let’s try and pull a ubuntu¬†image and install golang¬†in it.¬† The command goes docker pull ubuntu.

docker-pull
docker-pull

Now we need to run a docker container and get a shell access to the container. For that we run command docker run -it --name="golang" ubuntu:latest /bin/bash

Let’s break it down and see what is going on here, run¬†tells the docker to start the container -it¬†option tells that this is going to be an interactive¬†session and we need to attach a tty¬†to this,¬†--name¬†is the option to give name to the docker container and ubuntu:latest¬†is the name of the image and /bin/bash¬†is the process that needs to be run.

Once you run this command you will that you will get a root prompt something like this:

docker-prompt
docker-prompt

 

Now you can run any command inside it and you will be totally isolated from your host machine. For installing golang¬†let’s follow these instruction from Digital Ocean. You should ignore the ssh¬†instruction instead run apt update¬†and apt install curl nano.¬†Follow the rest normally and you will see it working like this:

go-docker
go-docker

 

You can play around with golang¬†in the docker and when you are done you can exit. The docker stays it’s just that you are out of it. You want the shell again you can run,

docker exec -it golang /bin/bash

You will get the shell again, this is what is called stateful container since it will have all the files that you have created. You can go ahead and mount a volume to the container using -v option in the docker run statement, this will act as if you plugged in a pen-drive in the docker storage being a directory you have created on the host machine.

docker exec -it -v /home/fhackdroid/go-data:/go-data golang /bin/bash

This will mount¬†the /home/fhackdroid/go-data to ‚Äč/go-data¬†in the docker container.

These are the few ways I use docker in my daily life, if you use it in any other way and you want to share do write it to me I would be more than happy to know.

Happy Hacking Folks!

Design Pattern: Singleton

“Beauty!”, when I see some really amazing code that is my first reaction, but what makes a piece of code beautiful? Is it neatly named variables? Is it the uniform indentation?

Well the answer is yes but there is something a little more than these factors and that is an elegant  solution to the problem. When I say elegant solution what is that I am talking about ? What makes a solution elegant? It is the way you approach a problem.

Design Patterns in the programming world adds to the beauty of the solution, it sometimes feels that it is the missing piece of the puzzle. And the solution so magically fits to solve the problem. The various patterns that I came across are Singleton, Mixin, Pub-Sub etc. The way I approached it and studied them is a little different, design patterns are actually tailored way to react to a given situation.

Let me elaborate on that now suppose there is an emergency and somebody got hurt, what is the first thought that comes to your mind ? It is to handle it using First Aid, this is actually a catered thought which has been imbibed in us from ages and people have design First Aid boxes in such a way that it has all the first come fixes for all the emergencies.

For me I see Design Pattern in the same manner it has gone through the test of time and proved to be the best way to solve a specific type of problem.  It is like a ready made template but you should be aware enough to know the problem and to know the pattern that solves that problem. 

I have read about a lot of design patterns but to be very frank I have seldom seen one being applied in the code-base that I have came across, this could be because I have not appreciated it much and also because I was not able to observe the pattern. It was very recently when I was working with Gautham Sir I began to appreciate the beauty of it. We were writing a utility in jnaapti using EcmaScript 6. He made me feel to appreciate the beauty of it and taught me how to implement it as well.

Let us break it down more and see the type of problems in which Singleton design pattern can be used.

What is Singleton design pattern?

A Singleton¬†design pattern puts a restriction of returning the same object irrespective of how many times the class¬†is being instantiated. This makes sure that whatever is the state¬†of object that state is preserved. Don’t be overwhelmed if you are not able to understand it now it will make more sense once you see the code.

The benefit you get is having a kind of a global store where you can put in data and retrieve it when you desire to.

Lets us make it more clear imagine there is a class Library now through out the life cycle of the software what we want is there should be only one Library object and when ever I get this object I should be able to add and delete books from the library hence modifying the library now when I do this the library object anywhere being use should get this information.

Lets chalk out some code and try to understand it, I have 3 files Library.js, Customer.js and LibraryPlayGround.js.  The content of those file are very straight forward.

es6-12
Library.js

Now we need customers or readers for simplifying things i have only included on one method that is return books.

es6-2
Customer.js

Once all this is done we need a playground where we can see things happening and experiment with it.

es6-3
LibraryPlaygroud.js

Now if you see the code farhaan object has tried to access the same Library object that is being exported. No matter what it well return the same instance which has been instantiated in the beginning of the lifecycle of the software. This is how I tried implementing Singleton .

I have used ECMAScript here to demonstrate that concept and to implement it, I am a learner so there could have been certain things I wouldn’t have made clear, you can leave a comment regarding the same, if you have something to add I would love to know.

Till then Happy Hacking

The A/V guy’s take on PyCon Pune

The A/V guy’s take on PyCon Pune

“This is crazy!”, that was my reaction at some point in PyCon Pune. This is one of my first conference where I participated in a lot of things starting from the website to audio/video and of course being the speaker. I saw a lot of aspects of how a conference works and where what can go wrong. I met some amazing people, people who impacted my life , people who I will never forget. I received so much of love and affection that I can never express in words. ¬†So before writing anything else I want to thank each and everyone of you , “Thank you!”.

My experience or association started the time when the PyCon Pune was being conceived Sayan asked me if I could volunteer for Droidcon so that I can learn how to handle A/V for PP, ¬†and our friends at HasGeek were generous enough to let me do that. The experience at Droidcon was crazy, I met a lot of people and made crazy lot of friends. Basically me and Haseeb were volunteering to learn the A/V stuff and Karthik was patient enough to walk us through the whole complex set up, to be very honest I didn’t get the whole picture till now but I some how able to manage. I learned a thing or two about ¬†manning¬†the camera and how much work actually goes to record a conference.

Since I was anyhow going to the conference I thought why not to apply for a talk but somehow I knew I wasn’t going to make it reason being the talks got rejected in a lot of other conferences ūüėõ . But anyhow being my stubborn self I don’t give up on rejection I gathered all the courage and got Vivek involved and we decided to apply for the talk and to my surprise it got in. This was our first conference talk and it was on one of the projects that we really really love, Pagure.

Since these things happened over a large span of time, by the time conference dates came I have nearly got out of touch with the A/V setup I only have vague idea about what is happening. So Sayan who is a one man army stepped in and he assured me that he will help me with getting the setup ready and we turned again to our friends at HasGeek and they were really humble to help us out this time and also help us with the instruments. We literally had a suitcase full of wires in case things go wrong. We spend around 3 days to up skill ourselves to handle the setup but this time the setup was very simple.

After all this happened and Sayan and Chandan took all the instruments to Pune. I arrived at Pune somewhere around two days before the conference the bus that I took from Bangalore to Pune dropped me somewhere near Telegaun which is near to Mumbai than Pune and I somehow managed to get back to Pune and reached Sayan and Chandan’s house. We were bunking together and there were more people about to come. I took some rest and then we were out , first stop was Reserved Bit , oh I can’t forget this place.

It is a perfect place for geeks and I loved every aspect of it. There I met Siddhesh for the first time we have had conversations over IRC though and met Nisha too. Amazing people the whole experience to travel to Reserved Bit and way back was amazing. We went to the venue to checkout where the camera will be and verify various aspects of the venue. After we came back I started working on the setup and man it was very tough and tricky to gather live feed from the camera.

First of all I was little hesitant to use any proprietary software but then I had no option so we somehow found a windows laptop and tried configuring it but almost everytime either we got a “BLUE SCREEN” or “UPDATES” which annoyed me , the sole reason of using windows was because we had a piece of hardware called capture cards, and the driver for which were not available. After long struggle and a lot of digging done by Siddhesh we got driver for Epiphan capture card for Linux and this was around 12 in the night and we all were still there at Reserved Bit. This gave all of us new hope and then it started we kind of got our minimalistic set up and Siddhesh did a “Compiler talk by Angle Fish” , it was a lot of fun by the time we got it working it was somewhere around 4 in the morning. After all this Sayan and Me actually took a walk back home and picked up Subho on the way. The next day CuriousLearner arrived and then Haseeb , Amit and Gaurav.

We were around 10 people squeezed in a single room but without any discomfort we kind of enjoyed our stay with occasional leg pulling to deep intense tech discussion the whole experience was just terrific. Then comes the actual venue setup that was one crazy thing so the video setup was working with Linux , we had Epiphan capture card working on Kernel version below 4.9 and OBS studio as a recording software. I actually spent a good number of hours to install OBS and downgrading kernel to 4.6 so that Epiphan driver works on at least 6 laptops. When we tried the setup on site and it broke because we didn’t take into account the audio from the mic. All of us were stuck in a state of panic then we realized that we have a mixer with us, but its power cord was left at Reserved Bit . By this time this setup kind of became our conference hack and we wanted it to work so badly. We actually ran back to Reserved Bit spent sometime there since we had some work and then quickly came back to the venue, connected the mixer and after few trial and run it worked.

“YES IT WORKED ” our efforts paid off, we recorded the whole conference using this setup, some of the recordings were a little glitchy and one other hack that we added was we weren’t recording the slides from speaker’s laptop we were doing it manually on our laptops. That means one copy of slide was being played on our laptops and we were recording it accordingly.

Apart from this experience I actually got the opportunity to meet all the keynote speaker the first so I met Nick, Honza, Terri,  John, Steven and Praveen. This was another experience in itself to know them and talk to the Rockstars of the FOSS WORLD.

As a speaker Kushal introduced me as the Speaker who is also the Cameraman for the event and that was may be the first time in a tech conference. Vivek and I have been collaborating over the talk for a long time and we figured out the order in which we need to speak and we spoke accordingly we kind of covered all the things that we wanted to and got a great response from the audience. I attended most of the talks since I was The A/V GUY but I had a huge help from rtnpro he was always there humble and ready to help.

The conference came to an end where Nisha told all the people about the effort that was put in from every person and specially Sayan. After this we had two days of devsprint where we had amazing projects, Vivek and I were mentoring for Pagure and we got a lot of new contributors and quite a number of PRs ( 13 to be precise ), the devsprint was a run away success.

I also got chance to interact with mbuf and man I saw him smile and crack jokes for the first time and it was crazy fun , ¬†I think it was the dinner after the last day of the conference. One of the most amazing experience was to talk to Haris and yes his name is Haris not Harish. The whole experience was so lovely that I don’t think that it can be better than this.

PS: We fixed my Macbook too

PPS: Video of our talk at PyCon Pune

Functional Programming 101

“Amazing!” ¬†that was my initial reaction when I heard and read about functional programming , I am very new to the whole concept so I might go a little off while writing about it so I am open to criticism . ¬†This is basically my understanding about functional programming and why I got hooked to it .

Functional Programming is a concept just like Object Oriented Programming , a lot of people confuse these concept and start relating to a particular language , thing that needs to be clear is languages are tools to implement concepts. There is imperative programming where you tell the machine what to do ? For example

  1. Assign x to y
  2. Open a file
  3. Read a file

While when we specifically talk about FP it is a way to tell how to do things ? The nearest example that I can come up with is SQL query  where you say something like

SELECT  * FROM Something where bang=something and bing=something

Here we didn’t tell what to do but we told how to do it. This is what I got as a gist of functional programming where we divide our task into various functional¬†parts and then we tell how things have to be implemented on the data.

Some of the core concepts that I came across was pure functions and functions treated as first class citizen or first class object . What each term means  lets narrow it down .

Pure functions  is a function whose return value is determined by the input given, the best example of pure functions are Math functions for example Math.sqrt(x) will return the same value for same value of x. Keeping in mind that x will never be altered. Lets go on a tangent and see that how this immutability of x is a good thing, this actually prevents data from getting corrupt.  Okay! That is alot to take in one go, lets understand this with a simple borrowed example from the talk I attended.

We will take example of a simple Library System¬† now for every library system there should be a book store, the book store¬†here is an immutable¬†data structure now what will happen if I want to add a new book to it ? Since it is immutable¬†I can’t modify it , correct ? So a simple solution to this problem is every time I add or remove a book I will actually deliver a new book store¬†and this new book store will replace the old one. That way I can preserve the old data because hey we are creating a whole new store. This is probably the gist or pros of functional programming.


book_store = ["Da Vinci's Code", "Angles and Demons", "The Lost Symbol"]
def add_book( book_store, book):
    new_book_store = []
    map(lambda old_book: new_book_store.append(old_book), book_store)
    new_book_store.append(book)
    return new_book_store

print add_book(book_store, "Inferno") # ["Da Vinci's Code", "Angles and Demons", "The Lost Symbol", "Inferno"]

print book_store # ["Da Vinci's Code", "Angles and Demons", "The Lost Symbol"]

In the above code you can actually see that a new book store is returned on addition of a new book. This is what a pure function looks like.

Function as first class citizens , I can relate a lot to this because of python where we say that everything is a first class objects. So, basically when we say functions are first class citizen we are implying that functions can be assigned to a variable, passed as a parameter and returned from a function. This is way more powerful then it sounds this bring a lot modular behavior to the software you are writing, it makes the project more organized and less tightly coupled. Which is a good thing in case you want to make quick changes or even feature related big changes.


def find_odd(num):
    return num if(num%2 != 0) else None

def find_even(num):
    return num if(num%2 == 0) else None

def filter_function(number_list, function_filter):
    return [num for num in number_list if(function_filter(num) != None)]

number_list = [1,2,3,4,5,6,7,8,9]
print filter_function(number_list, find_odd) # [1,2,5,7,9]
print filter_function(number_list, find_even) # [2,4,6,8]

In the above code you can see that function is passed as an argument to another function.

I have not yet explored into lambda calculus which I am thinking of getting into . There is a lot more power and beauty in functional programming.  I want to keep this post a quick read so I might cover some code example later, but I really want to demonstrate this code.


def fact(n, acc=1):
    return acc if ( n==1 ) else fact(n-1, n*acc)

where acc=1  this is pure textbook and really beautiful code which calculates factorial of n ,  when it comes to FP it is said To iterate is Human, to recurse is Divine. I will leave you to think more about it, will try to keep writing about things I learn.

Happy Hacking!