Programmer


“Programmer” is a weird name for a professional. Programmer simply refers to a person who programs or writes code. Similarly, we call person who speaks Chinese a Chinese speaker. Now we would find it ridiculous when someone says their profession is a Chinese speaker, yet we refer all people who programs programmer.

Speaking certain programming language is merely a skill, a more and more fundamental skill as we stepping into next age, a skill just as reading and writing in this age. The real profession is really what you do with the language — designing and optimizing algorithms, computing physics problems, or designing interfaces. Now when we keep in mind what we want to accomplish when we recruiting, we should see that the ability to program is really a minuscule criteria.

We have plenty of programmers, 99% of them won’t help you accomplish your task. They know how to speak a language, they just don’t know what to speak in the language. You can’t speak an idea that is not in your head. Or are you just looking for a professional programming language translator?

Share |
Posted in Philosophy, Programming | Leave a comment

IPad App – Note Quiz

NotesQuiz - music notes flash card
My son has been learning piano for a year. He likes playing piano but somehow he has barrier mastering the notes. For each new song, he would “guess” the notes and then start playing along and never have second reflection on whether he played the right note or not. When being questioned, he would stumble and hardly can continue. So finally his piano teacher had a temper session and demanded him to master the notes. He was fine — what a personality — but I was feeling awlful. So I decided to help him.

Rather than shop for some flash cards, I thought I should code up something on the iPad. So a few days later, here it is:

Notes Quiz in IPhone Simulator

The app is simple and sweet. There is no need to explain anything for my son to start playing it. At level 1, he gets 30 seconds for each quiz. As he levels up, the allowed time for each quiz shortens until it reaches 1 second limit. At low level, if he answers the quiz quicker, he gets bonus score and could level up quickly. At high levels, the bonus is harder to get, but I guess one don’t really need to play it any more once reach high level. My son says he hates timers, so there is no beeps as time goes by and it seems nothing would happen when the time reaches 0. But I didn’t tell him that when time reaches 0, although there is no beep or any alerts, he will not get score even he answers it correctly — effectively he has to do more quiz if he doesn’t concentrate. Any wrong answer results in penalty — as much as half of his level score, but never lowers a level. He learns to be careful not to make mistakes quickly.

Every day, I demand my son to reach 5 levels on this app. The app is designed so the more concentrated he is, the faster and quicker he will reach the level. So far it only has been two days, and it seems to be working.

Share |
Posted in Programming | 2 Comments

Reading “Why Chinese Mothers Are Superior”

Going extreme, selecting controversial words, and provoking resentments can be very successful technique. WSJ.com published Amy Chua’s article Why Chinese Mothers Are Superior, and it has been generating a thousand comments per day since it was published. I read the article the first day, and it seems to be a reasonable article that voices opinions that most Chinese families should share and certainly provides some refreshing views to western families. A couple of days later, it surprises me that it creates a commotion even among Chinese families. One of my friends, who grew up in China, forwarded a comment to me, and citing the comment was well voiced. It surprises me because I know this friend personally shares many characters that Amy Chua describes, yet she is evidently crying against this article. So I read the comment she forwarded and can’t help wonder that why so many people just don’t know how to read.

Amy Chua’s article, in summary, are merely voicing following opinions:

Western parents worry a lot about their children’s self-esteem. But as a parent, one of the worst things you can do for your child’s self-esteem is to let them give up. On the flip side, there’s nothing better for building confidence than learning you can do something you thought you couldn’t.

Western parents does worry more about their children’s self-esteem than Chinese parents. And the opinion follows is arguably reasonable.

All decent parents want to do what’s best for their children. The Chinese just have a totally different idea of how to do that.

Hardly can deny.

Western parents try to respect their children’s individuality, encouraging them to pursue their true passions, supporting their choices, and providing positive reinforcement and a nurturing environment. By contrast, the Chinese believe that the best way to protect their children is by preparing them for the future, letting them see what they’re capable of, and arming them with skills, work habits and inner confidence that no one can ever take away.

Essentially, Amy Chua is actually trying to explain the difference of two cultures and especially the beliefs in Chinese culture.

Reading through the comment, it is apparent that for many readers, these opinions, which was what the whole article was about, never even get into their mind. They never really thought on these opinions — before they start commenting.

Here is the comment my friend cited:

Chris Mah wrote:
I was the youngest of five children raised by Chinese parents, and I
can say with confidence that even by Chinese parents’ standards, Amy Chua’s views and methods are extreme and dangerous.

Here we see that from the start, this commenter is really commenting on Amy Chua’s specific examples rather than commenting on Chinese culture in general. In a plain language, this commenter is saying: I share your Chinese culture, but you are too extreme.

I grew up with Chinese parents who were strict but fair and tough but loving. They had their own ideas of what they wanted for me, but supported me even when my ideas were different. I ended up with a degree from an Ivy League school, was a Division I athlete, gave solo violin performances in four different continents, and landed a job at the most successful technology company in the world.

So this commenter fits in a stereotyped Chinese image. The fact he is presenting here is that his parents were strict, fair, tough, loving. But do note that he already assumes that Amy Chua is strict, not fair, tough, not loving. Where does “not fair”, “not loving” coming from?

I say this not to impress anyone, but to illustrate that any parent can use fear, intimidation, and shame to produce a robot child who can play concertos and multiple 6-digit prime numbers in their heads, but it takes a special kind of parent to raise a high achieving child who is also well-adjusted, socially competent, and has characteristics like humility, open-mindedness, and empathy, traits which are sorely absent in people like the author.

Assumes more “facts” that Amy Chua was mainly practicing “fear, intimidation, shame”, and here children is not “well adjusted, socially competent”, and lack “characteristics like humility, openmindedness, and empathy”. I re-read Amy Chua’s article, it is not possible to get these “facts” from her words, they are just not there. This commenter generates these ideas in his mind, and possibly right after he reads the title and first paragraph. Like this:

Why Chinese Mothers Are Superior

– Superior? My family is superior. Let’s see how you can be more superior than ours.

Here are some things my daughters, Sophia and Louisa, were never allowed to do: … …

– Our family was different. I was sometime allowed to … So we are different, but you can’t be superior than mine, so your children must lack certain traits, such as … …

Our mind works faster than we realize, and before we know it, we already read more than the article writes. All the following reading are automatically mixed in with these conjured up “facts” in mind.

Children who are raised by parents like Amy Chua turn out to be adults
like Amy Chua: paranoid, insecure, abrasive, and incapable of forming
healthy relationships with their children, friends, or spouses. Even in this
short essay, it’s clear that the way she alienates her friends, passive-
aggressively insults her husband, and belittles her children point to
some serious social deficiencies which she is sadly passing on to her
children.

More “facts”: paranoid, insecure, abrasive, unhealthy relationship with their children, friends, husband. Where do they come from?

Even more disturbing is the pride and satisfaction she seems to get out
of the controversy she knows she is generating by advocating such extreme views. What any rational person would perceive as “abuse” she no doubt considers “tough love”, and she will no doubt reject any critics as “weak” or “soft”.

Further projections based on conjured up “facts”.

She has a twisted perception of herself as the selfless martyr who sacrifices blood, sweat, and tears so that her child can succeed despite
their effeminate, bleeding-heart husband’s attempts to undermine her at
every turn. In reality, everything she is ostensibly doing for her children
is actually all about Amy Chua: she knows that readers will despise
her, but she wants to feel the jealously of others who can’t muster her
toughness and discipline to reap the rewards of her perfect brand of parenting.

Further development based his earlier “projection”.

This kind of parenting disgusts and appalls me. This kind of willful,
condescending, simplistic, narrow-minded, unapologetic idiocy disgusts
me even more. I feel pity for Amy Chua, her husband, and her children.

Now seeing the “facts” this comment sees in his mind, me too, pity for Amy Chua, her husband, and her children.

But through this comment, I don’t see which point that he is against that is actually written in the article. Did he read?

Share |
Posted in Family, Philosophy | 1 Comment

The Natural Language Approach



Since I was reading about programming language, I picked up the book “Perl 6 Essentials”, which has been lying on my shelf since like for ever. In the front part of the book, it mentions this “water-bed theory of complexity”. It says that the natural tendency in human languages is to keep overall complexity about equivalent. So in that case, our natural language is actually a very complex one compared to the programming languages. Think about how many vocabulary we use in our daily communication. So according to the waterbed theory of complexity, it made the language itself complex to ease our daily communications. Indeed, our natural language is capable of express very complex ideas and we never stress about it.

So if this natural language approach makes sense, then the future programming language trend should probably going toward complex ones rather than simple ones. In that sense, the functional language is definitely on the opposite side of this direction. Perl, with its much diversified vocabulary, is in the right direction. And in the future, we probably should see some languages that is much more complex.

It also makes sense. To really achieve the ease of our daily communication, we really paid our effort in learning our natural language. And the result is very rewarding. Similarly, once some of us paid our effort in learning vim, we never felt the same in editing. And it makes perfect sense that a really effective programming language may need us to spend quite some effort to get used to.

“Am I heard right? You want to make learning programming even harder? Aren’t we all complaining our current programming languages too hard to learn already?” Well, once we really had the effective programming paradigm, who are to say that we still need so many programmers?

Share |
Posted in Programming | Tagged , | 13 Comments

Reading Haskell – Purity


Haskell is the only programming language that is conjured up not by individuals, but a group. It was born to be pure, and the result is just beautiful. In my mind, if one is to study programming as a science, then Haskell is a language to begin, to return to, and to last. That is, if you are pursuing something in theory.

Just like math, pure math is very beautiful. You are not concerned with the purpose of math like everyone else does; you are just following math, discovering math, and enjoying math. You find math is intrinsic in the universe and is beyond anything in the universe. You feel like you are speaking what god speak and seeing what god see. And what about purpose? There is no purpose — God create the universe just to watch.

However, the rest of the time, math is always used with a purpose, and rarely pure. We just want math to give us an answer. In pure math’s eye, all answers are the same, it is whether an answer exist that takes interest. if there is this and that constrain, there will be an answer, and the answer will be revealed by following this path — Isn’t it beautiful? Do I have to reduce myself to get the actual answer? Ah, that is just ugly.

So most of time, when we live with a purpose, we hate math — It is just difficult and never gives us what we need right away. Only when we cleared of purpose — either by fulfilling or giving up — we will sit down and read math to enjoy its pureness.

Programming language is like that. Most speak programming language with a clear purpose, they want get things done. And most of the time, the programming language in such use is just ugly — spaghetti code, familiar? Only when one don’t really have a clear purpose, those who are not thinking about getting things done, do programming with a style, and enjoys the programming (instead of just enjoying doing things). And to the purest of programming, there is such a group of people, who are under no pressure of get any actual job done, will produce something pure, something beautiful, like Haskell.

Just as math, we hate them but we know we need them. We know we need the guidance of pure math to reach any practical purpose. So what we actually used is something look like math but not exactly is math. We take this axiom and that axiom, then ignore the details, and happily hacking away. The real world is just that practical. Most of the time, we get right results, and we live happily. Once in a while, we realize we are not reaching our purposes, so we first curse the math, then after some struggle, we drop our pride, and go back to pure math, and correct our behavior to the extent we can reach our purpose again, and continue to be happy.

Well, we start doing programming in its ugliest way, then we realize it is so ugly to the point that we can no longer get things done. So we curse the language, then drop our pride, go back to pure programming, and learn a few styles and discipline, and happily find we can get things done again and happily move on.

Just as we almost never do pure math for practical purposes, we speak some non-pure math languages. The less pure our language is, we get along more easily: Get me some apples, it doesn’t matter how many; get me more apples, you know what I mean. Then for some purpose, we need speak purer: each apple cost 50 cents, get me 4 apples for 2 dollars. But we never speak pure math: .5 x 4 = 2 for practical purposes.

Now back to programming, we speak like this: do this then do that, and apply that. If we speak like this: Apply the result of you doing that after you doing this — you struggle.

However, we always first teach our kids to babble, and then to speak a natural language, then insist on how they speak, and at some point, we will urge our kids to learn .5 x 4 = 2. Similarly, we always start programming by just giving short instructions, then a language like basic or whatever can get us a job, then at some point, you should learn a pure functional programming language even though you may never use it.

Math is underlying how things work, but we somehow developed into our natural language which is a compromise between math and how we want easily get along. There are casual version of our language and purer version of our language and all serves our purpose without too much struggle.

Now this is my belief: a perfect programming language after the test of evolution will be a language that fits on what our mind works but underlying observes the principles of pure programming. Pure programming language such as haskell will always be valuable, but it is always another practical language that most of us speak.

Share |
Posted in Philosophy, Programming | Tagged , , , , | Leave a comment

Reading Clojure — Walking the Math


In the book “Seven Languages in Seven Days”, the author Bruce Tate associates a movie character to each of the language. For Clojure, it is Master Yoda, from “Star Wars”. That is quite fit. Yoda is old, speaks in reversed order, and full of wisdoms. Well actually, “star wars” were much younger than LISP, could it be that Yoda was inspired from LISP?

LISP is a concept and language created by mathematicians, it is not really an odd language once you put your mathematical thinking hat on. Math is all about rigorous derivations — start from basic rules and build up proofs after proofs until reaching (actually, often it is discovering) the goals. Math finds natural languages too noisy and ambiguous, so they build up their own languages with symbols and numbers rather than words. Math do not “describe” things, math “derive” things. Going through Math often resembles walking through a maze — you know the maze is walkable because you just did, but you still feel not sure.

Lisp is very much like a language of math. The basic components of Lisp are very simple and each segment (one pair of parentheses) is very easy to understand. Just like inside the maze, each direction of turn is clear as crystal. Unlike procedural programming, where the segments of code is connected by timeline, and unlike object oriented programming, where the segments of code is connected by layers, in LISP, the segments are connected by logic. Just like walking a maze, each turn accumulates on the RESULT of previous steps — or rather, each turn accumulates on the result of ALL previous steps. So when walking in a maze, you have to have faith that all your previous turns are in the right direction and keep going, or you will have to keep a map of walking path in your brain, and build on to that map after each step. Keeping track, easy for machines, but difficult for humans.

Coding in LISP often reminds me of doing proofs in math. For a hard problem, you don’t really know where you should go at the beginning. You only have some hunches. So you start walk anyway by making probes, and at some point, all your hunches connects and hurrah, you reach the answer — magically. That is much of the fun doing math, you find yourself doing magics all the time.

Here is a good essay on LISP programming where the author called it “Bottom-Up” programming. In a top-down approach, our mind plots the path. In a bottom-up approach, our mind is not sure about the path, neither before nor after.

In the essay, Paul Graham lists 4 advantages of bottom-up programming:

  1. Code is concise
  2. Promotes code reuse
  3. Easier to read
  4. Helps to clarify ideas

Well, these are just looking at the bottom side of the code. Surely the code is concise as it relies on the reader to supply the logic tracking; Surely you can reuse the code to turn left and right; Surely the direction of turn left or right is clear as crystal; The clarifying is a process of bottom-up programming as they getting closer to the goal. But it also says that you don’t really have a clear idea to begin with, you are actually probing your way; and more importantly, for a maintainer that is not familiar with your idea, he needs to walk the bottom up whole way to clarify these ideas all over.

There is no denying that math and LISP are powerful, elegant and magical. But there is also a reason that we don’t speak math in daily instructions.

Share |
Posted in Programming | Tagged , , | Leave a comment

Reading Erlang — functional programming


Scala appears to me as a language for the language’s sake. In contrast, Erlang is a much more interesting language to read. Unlike Scala, which is a language created with no purpose (other than replacing Java), Erlang is created with specific purpose of writing reliable distributed applications. It is well worth reading right there.

Now, Erlang is a functional language. There are two sides of functional programming — the expressing side and the restricting side.

People are embracing the expressing side of functional programming(FP): being able to pass and return functions allows neat tricks in writing concise codes. And for many of the features that people are embracing, they are not really shifting their programming paradigm. Rather they are merely employing a new way of expressing their original (OOP or procedural) sentences.

For example, the use of tuples and pattern matching allows working with multiple variables at once rather than the original pattern of one variable assignment at a time. And the “foreach”, “map”, “filter”, “foldleft” allows neat ways of saying iteration over a list and do something. These are syntax sugar that are not really hard to swallow and often people would like the taste.

But a real functional language comes with its restrictive side as well, and embracing that side will demand a paradigm shift, a new way of thinking in programming. For one thing, in a typical functional language, there is not really a loop construct. Tasks that typically performed in loops are accomplished with recursions instead.

At least for me, whether loops or recursions are more expressive or concise is the wrong question. The right question is which is more ready for our mind to comprehend. At least for me, recursion (and induction), albeit powerful, are not a ready state for our mind to comprehend. Every time I go through the proof with induction, I always need go back to the problem and attach the conclusion and then sink in the results. Similarly, a recursion is like walking a maze: even though the direction is simple as turn left or right, our mind is often in a lost state. For our mind to comprehend, we need visualize the “whole” picture, we need have rough ideas such as how big, how long, how complicated the thing is! A iterative loops often gives us that idea, or at least shows explicitly how the loop begins and ends so our mind have some sort of clues on how the whole thing is run. But a recursion algorithm is abstract of these direct information.

Just like induction, recursions are powerful. There are many hard problems that are much more straight forward to do it in recursion. But often, we feel that we didn’t really solve the problem even after we solved it! And often we have to be very clear on the algorithm and carefully study very step logically to make sure we are doing the right thing — often, I never feel certain.

As an example, have you ever read a syntax specification of a language such as this one in BNF format? That is a concise functional definition. But how is your mind comprehending it?

Without an easy comprehension of the code, there are cost in formulating the code and cost maintaining the code, and there are limits in reusing the code.

So, are we ready to take the leap in faith and start doing all loops in recursions?

Another hard pill is in functional programming, functions are more of the type of mathematical functions — they always return values and always return the same values given the same input. Put it plainly, are we ready to say bye-bye to the procedures that we are used to?

Those are the hard pills of functional programming, one should better swallow them first before they predict the next programming paradigm is functional programming. Functional programming is as old as FORTRAN, and LISP is as good today as 50 years ago. What changed?

The really interesting part in Erlang is its support in distributed applications. Here comes the famous “Let it crash”. A philosopher must be behind this motto. While others are headlong solving how not to crash, this philosopher recognizes that “crash” is an inevitable result, and then recognize the right problem to work out first: what to do when it crashes, which is a much easier problem to solve and utterly most important. Just like buying life insurances and writing wills.

I am still wondering what exactly is Erlang’s “lightweight processes”, but I really like the sound of it. For many problems, multi-process is really sufficient to achieve parallel processing and it really simplifies the programming. Just like what I believe in myself: don’t multi-task if I don’t have to, focus!

Share |
Posted in Programming | Tagged , | Leave a comment

Reading Scala — Replacing Java


Touring through “Seven Languages in Seven Weeks”, now I am at Scala. Scala seems to be a copycat of C++. Just as C++ trying to build OOP on top of C, Scala is trying to build FP (functional programming) on top of Java. Just as C++, it seems most promising to emerge as one of the key languages of the new programming paradigm in industry.

Now, when I read Scala, I have to remind myself that, a language that is designed for the industry has quite different goals and concerns than a language that is designed for the designer himself. The latter is designed to work for the designer, yet the former is designed mainly for others — most of whom are mediocre programmers that will mess up if it can be messed up. So while a programmer that is original and creative, he will emphasize on the expressing side of the language and frown on the restrictions of private variables, strong typing, immutable variables, the managers will recognize the value of these straight jackets over many programmers who are just following orders and trying to get jobs done. Industrialization means to scale, and they favor a language that can help with design goals and has enough restrictions that can prevent their anonymous labor pool messing up.

So we see how Java and C# being used over among large enterprise and how ruby and php being used among start ups. The former have full time designers that do nothing but write specifications and documentations; The latter will not afford any of these. Twitter switching from Ruby on Rails to Scala was just the type of story.

I will jump directly to the functional part of Scala.

scala> list.foreach(hobbit => println(hobbit))

I wonder what will it do when the anonymous block is much more complex. I certainly prefer this way:

foreach list as hobbit
  println(hobbit)

It provides a clean and consistent style, be a single line block or multi-line complex ones.

scala> words.count(word => word.size > 2)

A built-in function that accepts functional parameter. Again, I believe the code will grow ugly once the anonymous block gets complex. But these built-ins are nice. They are like candies that a language designer used to lure customers. It kinds of remind me that how php include many builtin functions just to lure users from the perl community.

And here is another functional built-in:

scala> val sum = (0 /: list) {(sum, i) => sum + i}

Currying, a nice gem from FP.

Then, there are good support for XML, regular expression, and concurrency, I see how hard it is to resist if you are doing Java.

However, when C++ sweeping over industry, they had a majority pool of C programmers. And the OOP concept fits very well with industry’s need of separating designs and implementations. Now Java is still not a dominating language, and functional programming is really focusing on the expressing side rather than the restriction side. So I kind of suspect that even after a wide adoption of Scala, the industry probably will still be mostly working with its OOP side and it may not mean a programing paradigm shift at all.

Share |
Posted in Programming | Tagged , , , , | Leave a comment

Reading Prolog — Sudoku


Continue on to Prolog. Now I remember what impression I had on prolog — it is not really a programming language, rather it is an application to solve logic problems. There are facts and rules, but no algorithm. Well, you know there are always algorithms for computer to do anything. The algorithm must has been built into the compilers. Then immediately I have this question, how do we ensure the algorithm will be optimal? I guess whether an algorithm is optimal or not is for programmers, not really for application users. Applications are fine, they let us focus on what we need to do.

In prolog, the algorithm probably is just enumeration. It has to be, right? If prolog is a programming language, should it belong to the same family as flex and yacc?

Anyway, the book has an example of solving sudoku. I had wrote similar program in perl a few years ago. I’ll dig that code up and present it in my macro system and compare with that prolog version.

Here is the code in prolog (following the Author’s 4×4 example):

valid([]).
valid([Head|Tail]) :-
fd_all_different(Head),
valid(Tail).
sudoku(Puzzle, Solution) :-
Solution = Puzzle,
Puzzle = [S11, S12, S13, S14, S15, S16, S17, S18, S19,
S21, S22, S23, S24, S25, S26, S27, S28, S29,
S31, S32, S33, S34, S35, S36, S37, S38, S39,
S41, S42, S43, S44, S45, S46, S47, S48, S49,
S51, S52, S53, S54, S55, S56, S57, S58, S59,
S61, S62, S63, S64, S65, S66, S67, S68, S69,
S71, S72, S73, S74, S75, S76, S77, S78, S79,
S81, S82, S83, S84, S85, S86, S87, S88, S89,
S91, S92, S93, S94, S95, S96, S97, S98, S99],
fd_domain(Solution, 1, 9),
Row1 = [S11, S12, S13, S14, S15, S16, S17, S18, S19],
Row2 = [S21, S22, S23, S24, S25, S26, S27, S28, S29],
Row3 = [S31, S32, S33, S34, S35, S36, S37, S38, S39],
Row4 = [S41, S42, S43, S44, S45, S46, S47, S48, S49],
Row5 = [S51, S52, S53, S54, S55, S56, S57, S58, S59],
Row6 = [S61, S62, S63, S64, S65, S66, S67, S68, S69],
Row7 = [S71, S72, S73, S74, S75, S76, S77, S78, S79],
Row8 = [S81, S82, S83, S84, S85, S86, S87, S88, S89],
Row9 = [S91, S92, S93, S94, S95, S96, S97, S98, S99],
Col1 = [S11, S21, S31, S41, S51, S61, S71, S81, S91],
Col2 = [S12, S22, S32, S42, S52, S62, S72, S82, S92],
Col3 = [S13, S23, S33, S43, S53, S63, S73, S83, S93],
Col4 = [S14, S24, S34, S44, S54, S64, S74, S84, S94],
Col5 = [S15, S25, S35, S45, S55, S65, S75, S85, S95],
Col6 = [S16, S26, S36, S46, S56, S66, S76, S86, S96],
Col7 = [S17, S27, S37, S47, S57, S67, S77, S87, S97],
Col8 = [S18, S28, S38, S48, S58, S68, S78, S88, S98],
Col9 = [S19, S29, S39, S49, S59, S69, S79, S89, S99],
Sqr11 = [S11, S12, S13, S21, S22, S23, S31, S32, S33],
Sqr12 = [S14, S15, S16, S24, S25, S26, S34, S35, S36],
Sqr13 = [S17, S18, S19, S27, S28, S29, S37, S38, S39],
Sqr21 = [S41, S42, S43, S51, S52, S53, S61, S62, S63],
Sqr22 = [S44, S45, S46, S54, S55, S56, S64, S65, S66],
Sqr23 = [S47, S48, S49, S57, S58, S59, S67, S68, S69],
Sqr31 = [S71, S72, S73, S81, S82, S83, S91, S92, S93],
Sqr32 = [S74, S75, S76, S84, S85, S86, S94, S95, S96],
Sqr33 = [S77, S78, S79, S87, S88, S89, S97, S98, S99],
valid([Row1, Col1, Row2, Col2, Row3, Col3, Row4, Col4, Row5, Col5, Row6, Col6, Row7, Col7, Row8, Col8, Row9, Col9, Sqr11, Sqr12, Sqr13, Sqr21, Sqr22, Sqr23, Sqr31, Sqr32, Sqr33]).

As any application, we just need to describe the problem. However, not having full features of general programming languages, even describing the problems can be cumbersome. The predicates fd_all_different and fd_domain certainly helps. There are many more predicates implemented in gnu prolog and some of them probably exist so describe the rules for a 100×100 sudoku problems can be possible. But as you go through the list of available predicates, you probably will have have the feeling of learning a new application, rather than learning a language.

I actually wrote a perl script to output this prolog code, so it is not so much trouble for me to do 100×100 sudoku in prolog if I have to.

Here is running the program:

$ gplc sudoku9.pro

$ ./sudoku9

GNU Prolog 1.3.1

By Daniel Diaz

Copyright (C) 1999-2009 Daniel Diaz

| ?- sudoku([4,_,_,_,_,_,_,_,_, 6,5,_,_,7,2,_,_,8, _,_,1,_,9,3,_,5,4, 7,_,_,8,3,1,9,_,5, 9,_,_,_,_,_,_,_,1, 3,_,2,9,5,4,_,_,7, 1,4,_,3,6,_,5,_,_, 5,_,_,2,1,_,_,8,6, _,_,_,_,_,_,_,_,3], Solution).

Solution = [4,_#16(2..3:7:9),_#37(3:7:9),1,8,5, _#121(2..3:6..7),_#142(3:7:9),_#163(2:9), 6,5,_#210(3:9),4,7,2,_#278(1:3),_#299(1:3:9),8, _#333(2:8),_#354(2:7),1,6,9,3,_#435(2:7),5,4, 7,6,4,8,3,1,9,2,5, 9,8,5,7,2,6,_#741(3..4),_#762(3..4),1, 3,1,2,9,5,4,8,6,7, 1,4,_#963(7..9),3,6,_#1010(7..9),5,_#1044(7:9),_#1065(2:9), 5,_#1099(3:7:9),_#1120(3:7:9),2,1,_#1167(7:9),_#1188(4:7),8,6, _#1235(2:8),_#1256(2:7:9),_#1277(6..9), 5,4,_#1340(7..9),_#1361(1..2:7),_#1382(1:7:9),3]

Kind of disappointing that it didn’t give us the final answer. There probably are some thing in the menu to explain how to get a usable solution, just more learning. I am too old for that.

Here is my perl program written in my macro system:

page: sudoku
    subcode: main
        # Input
        my $t=$ARGV[0]
        # Workspace is an array of 9x9x(1+9+1) array
        # $l=($i*9+$j)*11
        # $work->[$l] : answer for that cell
        # $work->[$l+$k+1]: possible answer $k for that cell
        # $work->[$l+$k+10]: number of possible answers
        my $work=[];
        # The program uses check1 and check2 subroutine
        # just as how we solve a sudoku problem manually,
        # but if failed, it has to resolve to bruteforce
        # trial
        my @trystack;
        # Maximum trial recursion levels.
        # You don’t want it to run forever.
        my $maxlevel=100;

        $call initialize
        print_result()
        trysolve(0)

        # There are only two perl functions.
        # We can use more if that is desired
        $list trysolve, print_result

    # Master solver
    fncode: trysolve
        my $level=shift;
        my $flag_updated=1
        my $flag_done=0
        my $flag_failed=0
        $while $flag_updated
            $flag_updated=0
            $flag_done=1
            # Any cell with only 1 possible number left?
            $call check1
            # Any number with only 1 possible cell left?
            $call check2
        $if $flag_done
            # I havn’t try much, but those I have tried
            # got a solution here if it has unique solution
            print_result()
        $if !$flag_done and !$flag_failed
            $if $level<$maxlevel
                # Pick a cell, choose one possible number,
                # push the rest to stack
                $call try
                trysolve($level+1)
            $elif !$flag_failed
                print_result()
        $elif $work=pop @trystack
            # Try solve the other case.
            trysolve($level+1)
    # ————————————————————-
    # See how clear a procedural code can be. The rest
    # are quite similar to how we specify the rules in
    # prolog. We need describe how do we access a row,
    # a col, and a grid, how to elliminate possible
    # answers and how to set an answer.As long as we
    # understand the general logic, the rest of the code
    # does not need much comments.
    # ————————————————————-
    subcode: initialize
        my @tlist=split /,\s*/, $t
        &call each_cell
            $work->[$l+10]=9
            $for $k=0:9
                $work->[$l+$k+1]=1
        &call each_cell
            my $t=shift @tlist
            $if $t ne "_"
                $t-=1
                $call setcell

    subcode: check1
        $flag_updated=1
        $while $flag_updated
            $flag_updated=0
            $flag_done=1
            &call each_cell
                $if !defined $work->[$l]
                    $flag_done=0
                    $if $work->[$l+10]==0
                        $flag_failed=1
                    $elif $work->[$l+10]==1
                        $for $k=0:9
                            $if $work->[$l+$k+1]
                                my $t=$k
                                $call setcell
                                last
    subcode: check2
        $for $k=0:9
            $(for:dir in row,col,grid)
                &call each_$(dir)
                    my $cnt=0
                    my $first
                    &call each_$(dir)_cell
                        $if !defined $work->[$l] and $work->[$l+$k+1]
                            $first=$l
                            $cnt++
                    $if $cnt==1
                        $t=$k;
                        $l=$first
                        $call l_to_ij
                        $call setcell

    subcode: try
        my $try_l;
        my $try_k;
        &call each_cell
            $if !defined $work->[$l]
                $for $k=0:9
                    $if !defined $try_l and $work->[$l+$k+1]
                        $try_l=$l
                        $try_k=$k
        $if $try_l
            my $l=$try_l
            my $t=$try_k
            my @workcopy=@$work
            $workcopy[$l+$t+1]=0
            push @trystack, \@workcopy
            $call l_to_ij
            $call setcell

    # ————————————-
    subcode: setcell
        $work->[$l]=$t
        $(for:dir in row,col,grid)
            &call each_neighbor_$(dir)
                $if $work->[$ll+$t+1]
                    $work->[$ll+$t+1]=0
                    $work->[$ll+10]
        $flag_updated=1

    # ————————————-
    subcode: each_cell
        $l=0;
        $for $i=0:9
            $for $j=0:9
                BLOCK
                $l+=11
    subcode: each_neighbor_row
        my $ll=($i*9)*11
        $for $k=0:9
            BLOCK
            $ll+=11
    subcode: each_neighbor_col
        my $ll=$j*11
        $for $k=0:9
            BLOCK
            $ll+=9*11
    subcode: each_neighbor_grid
        my $i1=int($i/3)
        my $j1=int($j/3)
        $for $i2=0:3
            $for $j2=0:3
                my $ll=(($i1*3+$i2)*9+$j1*3+$j2)*11
                BLOCK

    subcode: each_row
        $for $i=0:9
            BLOCK
    subcode: each_row_cell
        $for $j=0:9
            my $l=($i*9+$j)*11
            BLOCK
    subcode: each_col
        $for $j=0:9
            BLOCK
    subcode: each_col_cell
        $for $i=0:9
            my $l=($i*9+$j)*11
            BLOCK
    subcode: each_grid
        $for $i1=0:3
            $for $j1=0:3
                BLOCK
    subcode: each_grid_cell
        $for $i2=0:3
            $for $j2=0:3
                my $l=(($i1*3+$i2)*9+$j1*3+$j2)*11
                BLOCK

    subcode: l_to_ij
        my $i=int($l/11/9)
        my $j=int($l/11)%9
    # ————————————-
    fncode: print_result
        &call each_row
            &call each_row_cell
                $if defined $work->[$l]
                    print $work->[$l]+1, " ";
                $else
                    print "_ ";
            print "\n";
        print "——————————-\n";
 

And here is how it runs:

$ make
mydef_page.pl sudoku.def sudoku.pl
PAGE: sudoku
  –> [./sudoku.pl]

$ perl sudoku.pl "4,_,_,_,_,_,_,_,_, 6,5,_,_,7,2,_,_,8, _,_,1,_,9,3,_,5,4, 7,_,_,8,3,1,9,_,5, 9,_,_,_,_,_,_,_,1, 3,_,2,9,5,4,_,_,7, 1,4,_,3,6,_,5,_,_, 5,_,_,2,1,_,_,8, 6,_,_,_,_,_,_,_,_,3"
4 _ _ _ _ _ _ _ _
6 5 _ _ 7 2 _ _ 8
_ _ 1 _ 9 3 _ 5 4
7 _ _ 8 3 1 9 _ 5
9 _ _ _ _ _ _ _ 1
3 _ 2 9 5 4 _ _ 7
1 4 _ 3 6 _ 5 _ _
5 _ _ 2 1 _ _ 8 6
_ _ _ _ _ _ _ _ 3
——————————-
4 2 3 1 8 5 6 7 9
6 5 9 4 7 2 1 3 8
8 7 1 6 9 3 2 5 4
7 6 4 8 3 1 9 2 5
9 8 5 7 2 6 3 4 1
3 1 2 9 5 4 8 6 7
1 4 8 3 6 7 5 9 2
5 3 7 2 1 9 4 8 6
2 9 6 5 4 8 7 1 3
——————————-

$
 

Share |
Posted in Programming | Tagged , , , | Leave a comment

Node.js — events and callbacks


I only learned about node.js today. As I just looked at how Io has its threaded concurrency built in, and today I learned how node.js has the event loop and non-blocking calls built in. Either is an eye opener.

As I slowly realize how event driven programming fits in certain applications, I realize how important it is to create an intuitive interface for call backs. Treating a function call with callbacks as a normal $call function is just not going to work because (at least in my mind), a normal function call is a single unit of information, and attaching some extra complexities conflicts with that perception and cause interference in our mind’s flow. A function call with callback should be written as $if or $for. By the line $if and $for itself, our mind perceives a complete information instantly — that a switch or loop is coming. Once our mind digests that information, it moves on to expect a block and either skips or goes into it. Similarly, on the line of callback-function call should be complete with a leading symbol such as ‘&’ to note that it has a block to follow. We haven’t had trouble with well indented $if and $for, so I believe this way of coding callbacks will work.

Now if I successfully handles callbacks, isn’t object methods just a way of callbacks in a event driven application? Can’t I apply the same style for class dominated OOP? This is an inspiration from a V8 video clip from google where they mentions how they use a hidden class technique on Javascript, which is prototype based. Well, with hidden class approach, I think I can write a class-based OOP in the way of prototype based OOP.

Ever since I got my IPad, I had the thought of writing apps. However, it never got started. I just couldn’t figure out an intuitive way (at least for me) to cope with those classes. When you define classes, you are not using them, and when you use them, you have to remember the definitions. And the classes structure prevents me to organize my code in my own logic way. For example, when I want to write a handler of certain handler, the code that reads the object, saves the object, modifies the object, renders the object, …, are all over the places (well there are view classes, file classes, and controller classes, etc, all involved), and not to mention that the class declarations and implementations are separated regardless of that they are part of the same information. I just hate classes. Real world don’t live in classes.

But, if I could do it this way:

&myview=new NSImageView
    $method touchesBegan
        $get_pt pt_start
    $method touchesMoved
        $get_pt pt_cur
       
       

Eureka!

Now back to node.js. Applying JavaScript on the server side is quite a surprising decision to me. JavaScript was created for the specific web environment and often reminds me of a hack language. Its syntax is simple as the parser has to live inside the browser. But as any genius simple language, the room to write good code is quite limited. It is dynamic, and thus slow. The very fact that V8 boasts 100% speed increase from time to time is merely a manifest of its slow nature — try manage that kind of boost with C compiler. No doubt JavaScript has its shining points just as Io, but it can’t be a good language for general purposes. It is amusing to see how the team cope with binary data.

But whether something makes sense or not is largely defined from your living environment. I guess nowadays the actual programmers are all constantly dealing with JavaScript, it must makes perfect sense to apply what they are familiar most to every thing. Just as myself, I am so used to vim and would feel the vim way makes perfect sense in almost any kinds of editor that I accidentally use.

But this era is strange any way as it is defined by web. So many geniuses are engaged in all kinds of non-optimal solutions. Such as building interactive real time applications inside a browser, Implementing vast libraries in JavaScript, and most intriguing that I just discovered: defining WebSockets. The current web set up puts strong handicaps around all of us, and we start to get used the handicaps and work with it. Don’t get me wrong, I truly admire the feats our genius created so far, but I just can’t help see that they are suboptimal once we remove those handicaps.

The handicaps are browsers. Browsers have grow so far that almost all of us would think that is a complicated task beyond normal ability. So we end up all live inside the browser. That is why chrome is such a big deal, they define your world. The open source of chrome means almost nothing — our current languages (C, C++, java) are insufficient to present the information for mortal consumptions. What we need is a new language or a meta layer that focuses on how to present the code so one can immediately extract a bare minimum version of browser out of source tree (or source forest). Only then, mortals will feel comfortable to create their own world and realize how handicapped that we are today.

Share |
Posted in Programming | Tagged , , , | Leave a comment