-
Notifications
You must be signed in to change notification settings - Fork 1
/
on-being-a-polyglot.html
341 lines (299 loc) · 29 KB
/
on-being-a-polyglot.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
<!DOCTYPE html>
<html lang="en" prefix="og: http://ogp.me/ns# fb: https://www.facebook.com/2008/fbml">
<head>
<title>On being a polyglot - Stackdiver as a Service</title>
<!-- Using the latest rendering mode for IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://www.lyh.me/on-being-a-polyglot.html">
<meta name="author" content="Neville Li" />
<meta name="keywords" content="c,cpp,python,javascript,scala,java,clojure,haskell" />
<meta name="description" content="I’m kind of known as a polyglot among coworkers. We would often argue that instead of hiring great Java/Python/C++ developers, we should rather strive to hire great engineers with strong CS fundamentals who can pick up any language easily. I came from scientific computing background, doing mostly C/C++/Python many years ago. Over the course of the last three years at my current job I coded seven languages professionally, some out of interest and some necessity. I enjoyed the experience learning all these different things and want to share my experience here, what I learned from each one of them and how it helps me becoming a better engineer. C The first language I used seriously, apart from LOGO & BASIC when I was a kid of course. It’s probably the closest thing one can get to the operating system and bare metal without dropping down to assembly (while you still can in C). It’s a simple language whose syntax served as the basis of many successors like C++ & Java. It doesn’t offer any fancy features like OOP or namespaces, but rather depends on the developer’s skill for organizing large code base (think …" />
<meta property="og:site_name" content="Stackdiver as a Service" />
<meta property="og:type" content="article"/>
<meta property="og:title" content="On being a polyglot"/>
<meta property="og:url" content="https://www.lyh.me/on-being-a-polyglot.html"/>
<meta property="og:description" content="I’m kind of known as a polyglot among coworkers. We would often argue that instead of hiring great Java/Python/C++ developers, we should rather strive to hire great engineers with strong CS fundamentals who can pick up any language easily. I came from scientific computing background, doing mostly C/C++/Python many years ago. Over the course of the last three years at my current job I coded seven languages professionally, some out of interest and some necessity. I enjoyed the experience learning all these different things and want to share my experience here, what I learned from each one of them and how it helps me becoming a better engineer. C The first language I used seriously, apart from LOGO & BASIC when I was a kid of course. It’s probably the closest thing one can get to the operating system and bare metal without dropping down to assembly (while you still can in C). It’s a simple language whose syntax served as the basis of many successors like C++ & Java. It doesn’t offer any fancy features like OOP or namespaces, but rather depends on the developer’s skill for organizing large code base (think …"/>
<meta property="article:published_time" content="2014-08-21" />
<meta property="article:section" content="code" />
<meta property="article:tag" content="c" />
<meta property="article:tag" content="cpp" />
<meta property="article:tag" content="python" />
<meta property="article:tag" content="javascript" />
<meta property="article:tag" content="scala" />
<meta property="article:tag" content="java" />
<meta property="article:tag" content="clojure" />
<meta property="article:tag" content="haskell" />
<meta property="article:author" content="Neville Li" />
<!-- Bootstrap -->
<link rel="stylesheet" href="https://www.lyh.me/theme/css/bootstrap.min.css" type="text/css"/>
<link href="https://www.lyh.me/theme/css/font-awesome.min.css" rel="stylesheet">
<link href="https://www.lyh.me/theme/css/pygments/monokai.css" rel="stylesheet">
<link href="https://www.lyh.me/theme/css/typogrify.css" rel="stylesheet">
<link rel="stylesheet" href="https://www.lyh.me/theme/css/style.css" type="text/css"/>
<link href="https://www.lyh.me/feeds/all.atom.xml" type="application/atom+xml" rel="alternate"
title="Stackdiver as a Service ATOM Feed"/>
<link href="https://www.lyh.me/feeds/code.atom.xml" type="application/atom+xml" rel="alternate"
title="Stackdiver as a Service code ATOM Feed"/>
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="https://www.lyh.me/" class="navbar-brand">
Stackdiver as a Service </a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
<li><a href="https://www.lyh.me/pages/about-me.html">
About Me
</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
</div> <!-- /.navbar -->
<!-- Banner -->
<!-- End Banner -->
<!-- Content Container -->
<div class="container">
<div class="row">
<div class="col-sm-9">
<section id="content">
<article>
<header class="page-header">
<h1>
<a href="https://www.lyh.me/on-being-a-polyglot.html"
rel="bookmark"
title="Permalink to On being a polyglot">
On being a polyglot
</a>
</h1>
</header>
<div class="entry-content">
<div class="panel">
<div class="panel-body">
<footer class="post-info">
<span class="label label-default">Date</span>
<span class="published">
<i class="fa fa-calendar"></i><time datetime="2014-08-21T21:26:00-04:00"> Thu 21 August 2014</time>
</span>
<span class="label label-default">Category</span>
<a href="https://www.lyh.me/category/code.html">code</a>
<span class="label label-default">Tags</span>
<a href="https://www.lyh.me/tag/c.html">c</a>
/
<a href="https://www.lyh.me/tag/cpp.html">cpp</a>
/
<a href="https://www.lyh.me/tag/python.html">python</a>
/
<a href="https://www.lyh.me/tag/javascript.html">javascript</a>
/
<a href="https://www.lyh.me/tag/scala.html">scala</a>
/
<a href="https://www.lyh.me/tag/java.html">java</a>
/
<a href="https://www.lyh.me/tag/clojure.html">clojure</a>
/
<a href="https://www.lyh.me/tag/haskell.html">haskell</a>
</footer><!-- /.post-info --> </div>
</div>
<p>I’m kind of known as a polyglot among coworkers. We would often argue that instead of hiring great Java/Python/C++ developers, we should rather strive to hire great engineers with strong <span class="caps">CS</span> fundamentals who can pick up any language easily. I came from scientific computing background, doing mostly C/C++/Python many years ago. Over the course of the last three years at my current job I coded seven languages professionally, some out of interest and some necessity. I enjoyed the experience learning all these different things and want to share my experience here, what I learned from each one of them and how it helps me becoming a better engineer.</p>
<h2>C</h2>
<p>The first language I used seriously, apart from <span class="caps">LOGO</span> <span class="amp">&</span> <span class="caps">BASIC</span> when I was a kid of course. It’s probably the closest thing one can get to the operating system and bare metal without dropping down to assembly (while you still can in C). It’s a simple language whose syntax served as the basis of many successors like C++ <span class="amp">&</span> Java. It doesn’t offer any fancy features like <span class="caps">OOP</span> or namespaces, but rather depends on the developer’s skill for organizing large code base (think Linux kernel or git).</p>
<p>Memory management is probably the biggest thing one get from learning the language, and to this day I’m still glad that I learned data structures in C. There are also other low level stuff like interrupts, system calls, and multi-threading which are often abstracted away in higher level languages. For these reasons I would argue that any professional developer should know some C.</p>
<p>I still remember programming my 9-pin dot-matrix printer with bit operators and ports; my first pre-Windows <span class="caps">GUI</span> with interrupts and <span class="caps">VGA</span> memory access; first e-mail client with <span class="caps">UNIX</span> sockets; first shell with all those Unix system calls; and learning two-phase commit by implementing it for <a href="http://www.sqlite.org/">SQLite</a>. While I rarely use C nowadays, many concepts pop up in day to day work and are essential in understanding much more complex systems.</p>
<h2>C++</h2>
<p>A natural next step after C, C++ adds <span class="caps">OOP</span> and many more features like streams, operator overloading, and templates. Several books were instrumental to understanding the language better, including Scott Meyers’ <a href="http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876">Effective C++</a> series, and Stanley Lippman’s <a href="http://www.amazon.com/Inside-Object-Model-Stanley-Lippman/dp/0201834545">Inside the C++ Object Model</a>. The former is regarded as a must read for all C++ programmers, while the latter dig into the language implementation of some mysterious features like object construction, virtual methods, and multiple inheritance. I actually read Effective C++ before studying the language. The first pass was not 100% clear but combined with practise and real world experience, the second read made a lot more sense and really made me comfortable with the language.</p>
<p>I started using it mostly in school for scientific computing, as “C with classes”, where one rarely relies on auto memory management <span class="amp">&</span> threading. Memory were allocated in big chunks, or managed with <span class="caps">STL</span> collections, and often read-only once loaded. And processing large amount of data is often embarrassingly parallel, i.e. crunching through input files in threads.</p>
<p>Fast forward to my current job, C++ is mostly used in the desktop application, heavily threaded with many small objects encapsulating asynchronous backend requests and JavaScript bridge with <a href="https://code.google.com/p/chromiumembedded/"><span class="caps">CEF</span></a>. Race conditions, memory leaks and null pointer crashes are common problems and I started to appreciate mutexes <span class="amp">&</span> <a href="http://www.boost.org/doc/libs/1_56_0/libs/smart_ptr/smart_ptr.htm">boost smart pointers</a>. Features like <a href="http://www.cprogramming.com/tutorial/template_specialization.html">template specialization</a> also helps in creating generic <span class="amp">&</span> performant code while paving the way for understanding type classes in Scala <span class="amp">&</span> Haskell.</p>
<h2>Python</h2>
<p>Probably the most popular of the bunch, Python is favored by many data scientists for its wide range of data processing libraries and I originally picked it up for information retrieval. It’s easy to learn, concise, and perfect for ad-hoc analysis or as a utility language. A colleague once said that any competent programmer should know one static and one dynamic language well, and in that case Python would be many people’s choice for the dynamic one.</p>
<p>When it comes to implementing complex algorithms quickly, list comprehension got me hooked first. Then it was lambda, map, reduce, filter, zip and that was when I discovered functional programming. After that came things like <a href="https://docs.python.org/2/library/itertools.html">itertools</a> and <a href="https://docs.python.org/2/library/functools.html">functools</a>. To me Python was the gateway language to functional programming.</p>
<p>I also did a lot of backend work in Python, and learn to hate <a href="https://wiki.python.org/moin/GlobalInterpreterLock"><span class="caps">GIL</span></a> and love <a href="http://www.gevent.org/">gevent</a>. Performance was still an issue and significant amount of time was spent profiling and optimizing code. And through the process I got a much better understanding of the non-blocking event-driven concurrency model.</p>
<h2>JavaScript</h2>
<p>JavaScript is a language that I write out of necessity, mostly when working with <a href="https://developer.spotify.com/technologies/apps/">Spotify Apps</a> and my <a href="http://labs.spotify.com/2013/11/14/announcing-spotify-visualization-api-beta/">audio visualization</a> hack project. It’s one of those languages that I never learned properly. While the language isn’t drastically different from the previous ones, I did have to wrap my head around various (ab)uses of closure and the whole async requests and callbacks concept, and you learn to organize the code around that to make it more maintainable.</p>
<h2>Scala</h2>
<p>I introduced Scala back to my current job and use it on a daily basis. There are a lot of controversy around the language, mostly due to its steep learn curve and complexity. Learning curve was not so much of a problem for someone who already knows Python and C++, although there are still concepts harder to digest, like variances, bounds and type classes. Complexity, <span class="caps">IMHO</span>, was partly due to the limitation of the <span class="caps">JVM</span>, e.g. erasure and boxed primitives. Despite these problems, Scala seems to have found a sweet spot in the domain of big data, where it allows both development agility and performance, plus interoperability with other <span class="caps">JVM</span> system (Hadoop, Storm, Cassandra, etc.). Apart from powerful generics and operator overloading, Scala took a step further from C++ with implicits, making it easier to extend existing libraries or design new DSLs. <a href="https://github.com/twitter/scalding">Scalding</a>, <a href="http://spark.apache.org/">Spark</a>, and <a href="http://kafka.apache.org/">Kafka</a> are probably the most well known Scala projects, while newcomers like <a href="https://github.com/BIDData/BIDMach">BIDMach</a> are showing a lot of potential.</p>
<p>When it comes to learning the language, Twitter’s <a href="https://twitter.github.io/scala_school/">Scala School</a> and Horstmann’s <a href="http://www.horstmann.com/scala/">Scala for the Impatient</a> are both excellent resources and I enjoyed Joshua Suereth’s <a href="http://www.manning.com/suereth/">Scala in Depth</a> for advanced topics. The biggest reward, often absent from books <span class="amp">&</span> tutorials however, is abstract algebra and category theory. Sooner or later terms like monoid, semigroup, monad will pop up and you’ll recognize such patterns in map/reduce, storm, and even Java libraries like <a href="https://code.google.com/p/guava-libraries/">Guava</a>. To me, that’s the most important thing I learned from using Scala.</p>
<h2>Java</h2>
<p>Another language I use out of necessity. It’s often contempted in the start up world for verbosity and enterprise heritage. Most colleges teach Java in programming 101 and that was my only previous encounter with it (although I skipped most classes in school). The language has a very conservative set of features and probably not a challenge for any seasoned C++ developers. People often associate Java with design patterns, for better or worse, and <span class="caps">IMHO</span> a lot of them, like builder, factory, delegate, were really created to overcome the limitation of the language.</p>
<p>One area that Java excels in, however, is its ecosystem of libraries, tools, IDEs. Before Java I did almost all coding in Vim, using Xcode or Eclipse occasionally for debugging C++ code. After using <a href="http://www.jetbrains.com/idea/">IntelliJ <span class="caps">IDEA</span></a> for a few weeks, I’d say that it’s probably the biggest attraction for writing Java. Verbosity becomes less of a problem once you get used to the <span class="caps">IDE</span>’s features for code navigation, completion, and refactoring. Dependency management is also easier without various platform specific packages. And coming from doing backend in a Python world, the quality and maturity of libraries in the <span class="caps">JVM</span> world is so much better. We ended up spending a lot less time struggling with memcached, Cassandra or <span class="caps">HTTP</span> clients.</p>
<h2>Clojure</h2>
<p>The latest language I used at work. We use it mainly for defining monitoring rules in <a href="http://riemann.io/">Riemann</a> and I also hacked together a few <a href="http://storm-project.net/">Storm</a> topologies in Clojure. With some Scala experience by the time I picked it up, most concepts are no stranger to me. Syntax is surprisingly simple and consistent. I often joke that it’s my language of choice on a plane or boat with no internet, since the core language <a href="http://clojure.org/cheatsheet">cheat sheet</a> fits on a single page. And Its inherently lazy sequence library maps naturally to stream processing and is also fun for solving <a href="http://projecteuler.net/">Project Euler</a> problems.</p>
<p>Some coworkers were appalled by the excessive use of parentheses and existence of plugins like <a href="https://github.com/kien/rainbow_parentheses.vim">rainbow_parentheses.vim</a>. Yes we talk smack about it, joking that 40 columns is enough and one should hook up an elliptical machine to <code>(</code> and <code>)</code>. But I also think of it as a restraint of complexity and break my code down to smaller, reuseable functions.</p>
<p>Clojure is also the first time I was exposed to macros (not the <code>#define</code> kind in C/C++), <a href="http://en.wikipedia.org/wiki/Software_transactional_memory">software transactional memory</a>, and <a href="http://en.wikipedia.org/wiki/Homoiconicity">homoiconic</a> programming languages. Concepts that broadened my understanding of programming language design.</p>
<h2>(Bonus) Haskell</h2>
<p>I always regretted not learning Haskell ever since switching to <a href="http://xmonad.org/">XMonad</a> as my window manager. If Python was my gateway drug to functional programming, then Scala, and more specifically <a href="https://github.com/scalaz/scalaz">scalaz</a>, are my gateway drug to Haskell, the pure functional programming language with strong academic background.</p>
<p>I recently picked up the language again, going through the excellent free book <a href="http://learnyouahaskell.com/">Learn You a Haskell for Great Good!</a> side by side with <a href="http://eed3si9n.com/learning-scalaz/index.html">learning scalaz</a>. It’s easy to see the parallel between the two, how some concepts built into the Haskell language are implemented with generics and implicits in scala(z). It’s also not hard to see why Haskell attracts interest, with its powerful type inferences, type classes, lazy evaluation and many other features.</p>
<p>I probably won’t use Haskell for real any time soon. I probably won’t even use those features in scalaz or <a href="https://github.com/milessabin/shapeless">shapeless</a> in production. Nevertheless I really enjoyed learning these concepts and see how they solve problems with elegance.</p>
<h2>Final words</h2>
<p>You might also say that I’m a jack of all trades and master of none. This is very true and I never became a master of any of these languages and created a framework or library. On the other hand this also allows me to pick up any task or role within the team and quickly become productive. And I often found myself applying techniques from one language to another. All in all I believe it’s much more beneficial to be a polyglot than sticking to one language and platform.</p>
</div>
<!-- /.entry-content -->
<hr />
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_button_google_plusone" g:plusone:size="medium"></a>
</div>
<!-- AddThis Button END -->
<hr/>
<section class="comments" id="comments">
<h2>Comments</h2>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'lyh'; // required: replace example with your forum shortname
var disqus_config = function () {
this.language = "en";
this.page.identifier = '2014-08-21-on-being-a-polyglot';
this.page.url = 'https://www.lyh.me/on-being-a-polyglot.html';
};
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by
Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</section>
</article>
</section>
</div>
<div class="col-sm-3" id="sidebar">
<aside>
<div id="aboutme">
<p>
<img width="100%" class="img-thumbnail" src="https://www.lyh.me//avatar.jpg"/>
</p>
<p>
<strong>About Neville Li</strong><br/>
Data infrastructure @<a href="https://twitter.com/Spotify">Spotify</a>, ex-@<a href="https://twitter.com/Yahoo">Yahoo</a> search, creator of <a href="https://github.com/spotify/scio">Scio</a>, technical cave & wreck diver, lefty guitar player
</p>
</div><!-- Sidebar -->
<section class="well well-sm">
<ul class="list-group list-group-flush">
<!-- Sidebar/Social -->
<li class="list-group-item">
<h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Social</span></h4>
<ul class="list-group" id="social">
<li class="list-group-item"><a href="https://open.spotify.com/user/sinisa_lyh"><i class="fa fa-spotify fa-lg"></i> Spotify</a></li>
<li class="list-group-item"><a href="https://github.com/nevillelyh"><i class="fa fa-github-square fa-lg"></i> GitHub</a></li>
<li class="list-group-item"><a href="https://twitter.com/sinisa_lyh"><i class="fa fa-twitter-square fa-lg"></i> Twitter</a></li>
<li class="list-group-item"><a href="https://www.slideshare.net/sinisalyh"><i class="fa fa-slideshare fa-lg"></i> SlideShare</a></li>
<li class="list-group-item"><a href="https://www.youtube.com/user/sinisalyh/videos"><i class="fa fa-youtube-square fa-lg"></i> YouTube</a></li>
<li class="list-group-item"><a href="https://www.instagram.com/sinisa/"><i class="fa fa-instagram fa-lg"></i> Instagram</a></li>
<li class="list-group-item"><a href="https://www.flickr.com/photos/sinisa_lyh"><i class="fa fa-flickr fa-lg"></i> Flickr</a></li>
</ul>
</li>
<!-- End Sidebar/Social -->
<!-- Sidebar/Recent Posts -->
<li class="list-group-item">
<h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Recent Posts</span></h4>
<ul class="list-group" id="recentposts">
<li class="list-group-item"><a href="https://www.lyh.me/magnolify.html">Magnolify</a></li>
<li class="list-group-item"><a href="https://www.lyh.me/featran.html">Featran</a></li>
<li class="list-group-item"><a href="https://www.lyh.me/automatic-type-class-derivation-with-shapeless.html">Automatic type-class derivation with Shapeless</a></li>
<li class="list-group-item"><a href="https://www.lyh.me/lambda-serialization.html">Lambda serialization</a></li>
<li class="list-group-item"><a href="https://www.lyh.me/lawfulness-of-aggregatebykey.html">Lawfulness of aggregateByKey</a></li>
</ul>
</li>
<!-- End Sidebar/Recent Posts -->
<!-- Sidebar/Categories -->
<li class="list-group-item">
<h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Categories</span></h4>
<ul class="list-group" id="categories">
<li class="list-group-item">
<a href="https://www.lyh.me/category/code.html"><i class="fa fa-folder-open fa-lg"></i>code</a>
</li>
<li class="list-group-item">
<a href="https://www.lyh.me/category/misc.html"><i class="fa fa-folder-open fa-lg"></i>misc</a>
</li>
</ul>
</li>
<!-- End Sidebar/Categories -->
<!-- Sidebar/Twitter Timeline -->
<li class="list-group-item">
<h4><i class="fa fa-twitter fa-lg"></i><span class="icon-label">Latest Tweets</span></h4>
<div id="twitter_timeline">
<a class="twitter-timeline" data-width="250" data-height="300" data-dnt="true" data-theme="light" href="https://twitter.com/sinisa_lyh">Tweets by sinisa_lyh</a> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
</li>
<!-- End Sidebar/Twitter Timeline -->
</ul>
</section>
<!-- End Sidebar --> </aside>
</div>
</div>
</div>
<!-- End Content Container -->
<footer>
<div class="container">
<hr>
<div class="row">
<div class="col-xs-10">© 2020 Neville Li
· Powered by <a href="https://github.com/getpelican/pelican-themes/tree/master/pelican-bootstrap3" target="_blank">pelican-bootstrap3</a>,
<a href="http://docs.getpelican.com/" target="_blank">Pelican</a>,
<a href="http://getbootstrap.com" target="_blank">Bootstrap</a> <p><small> <a rel="license" href="https://creativecommons.org/licenses/by-nc/4.0/deed.en"><img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-nc/4.0/80x15.png" /></a>
Content
licensed under a <a rel="license" href="https://creativecommons.org/licenses/by-nc/4.0/deed.en">Creative Commons Attribution-NonCommercial 4.0 International License</a>, except where indicated otherwise.
</small></p>
</div>
<div class="col-xs-2"><p class="pull-right"><i class="fa fa-arrow-up"></i> <a href="#">Back to top</a></p></div>
</div>
</div>
</footer>
<script src="https://www.lyh.me/theme/js/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://www.lyh.me/theme/js/bootstrap.min.js"></script>
<!-- Enable responsive features in IE8 with Respond.js (https://github.com/scottjehl/Respond) -->
<script src="https://www.lyh.me/theme/js/respond.min.js"></script>
<!-- Disqus -->
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'lyh'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var s = document.createElement('script');
s.async = true;
s.type = 'text/javascript';
s.src = '//' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>
<!-- End Disqus Code -->
<!-- Google Analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-6988688-5']);
_gaq.push(['_trackPageview']);
(function () {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
<!-- End Google Analytics Code -->
<script type="text/javascript">var addthis_config = {"data_track_addressbar": true};</script>
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=sinisalyh"></script>
</body>
</html>