Ask HN: Self-doubt, inferiority complex is killing me. How do I fix that? - <AUTHOR> I'm a CS student. Recently I have been battling with self-doubt a lot. I'm super self-conscious when I'm coding as well as when I'm speaking English--my 3rd language.
As a result, I avoid trying to solve hard coding problems. I freak out when I have to pair program with someone or when someone else is reviewing my code. And I tend to make a lot of syntax errors. I also tend to rely on documentation a lot. Furthermore, I tend to make a lot of stupid mistakes when I'm speaking English even though I have been living and attending college in an English-speaking country for the past three years.<p>Could you guys please give me some advices on how to deal with that issue? Thanks  lot! <comment><USER2> \- It's amazing that you speak three languages, most English speakers will be in awe of you for that alone. Bear that in mind when you make an error! \- Who cares about syntax errors in code? This is why we build in-line checkers in IDE's. Also syntax errors are easy to find and fix, semantic errors are the killers -> the bloody thing works and then blows up... arrgggh!

Big mantra : don't beat your self up. The rest of the world will do just fine at that job without your help. Also, mostly other people simply are not watching and critiquing you, people who are are either 1. mad, 2. in love with you. Both 1 & 2 mean that this is not an issue.

<comment><USER3> I think this is a wonderful worldview to have :)

</comment></comment><comment><USER4> Relying on documentation a lot is NOT a bad thing. Your problem solving abilities are important but one could make the argument that your ability to look up how to solve a problem is just as important. I can't count the number of times I've heard developers (including myself) say "Most of my job is just Googling how to solve something...".

When I was in college, once of my classmates only used documentation as an absolute last resort claiming that he didn't want to rely on it in college since he wouldn't be able to rely on it in the 'real world'. Not only was he slow and a pain to work with, but he couldn't have been farther from the truth. Google isn't going anywhere, and if anything its more accessible in the workplace than in a college setting where at times you're forced to write syntax correct code on paper in some unrealistic testing environment.

In short, embrace the documentation :)

</comment><comment><USER5> TL;DR; Fake it till you make it

You're probably a perfectionist. Bad news: in a few years, you might still think you're not good enough, when in fact you'll good enough. Good news: perfectionism will push you forward.

So you can adopt the "fake it till you make it" attitude: stop worrying, go ahead and try to convince others you're good enough. It should be easy enough, because others are much less demanding than you might think... Then you'll see others judge you positively. That's when you'll start to make it.

In other words: I'm a very experienced (42 yo) developer, highly regarded, yet I can't write code without running it, I make typos every few lines, I rely heavily on the huge amounts of documentation found on the web...

And I know my english is not perfect, but sometimes, a native speaker tells me my english is fine... So I continue to fake it, till I'll make it.

</comment><comment><USER6> I've been in a similar situation as you. I come from a third world country and didn't have access to computers until my late teens and started learning CS fundamentals only after my undergraduate studies. Given this, the US tech scene has been quite competitive and intimidating since there are highly talented people who started coding when they were very young. Initially I was battling with self-doubt but once I understood above points, I've been trying to bridge the experience gap. And it's quite easy to chug along if you love what you are doing.

So I would say that it's unfair to compare yourself with others as the circumstances for everyone is different. Just use yourself as reference and see whether you are better off than you were in the past. One tell-tale sign of progress is that when you look at your code/work from recent past, you will think of a lot of things you would do differently and sometimes you would think "what the hell you were thinking then" which is a great thing. :)

One of my mantras (which I may have picked from somewhere subconsciously) is:

      Life is not a sprint, it's a marathon.

So slow and steady may indeed win the race.

<comment><USER7> You're right that life is not a sprint, but I'd like to go one step further:

Life is not a race. :-)

</comment></comment><comment><USER8> My advice is to code more. You will get more accustomed to the thought process that goes into writing code, more accustomed to your editor, and more comfortable with coding overall.

One thing that I did that helped me code more was challenge myself to code every day. Using GitHub helps because you can check your streak. My friend and I did this for about 2 months and we felt very productive. This is his blog post about halfway through: [http://www.ironzebra.com/post/105/abc-always-be- coding](http://www.ironzebra.com/post/105/abc-always-be-coding)

Your English is fine. I live abroad and meet people all the time who use English as a second language. Yours is by far some of the best English I've seen from a non-native speaker.

<comment><USER9> This is the best advice given based on my experience.

I am also suffering from low confidence and inferiority complex. What actually helps is coding more and pushing to github as much as I can. Especially if I think it is still not good enough. This makes you inclined to work more at it. So gradually you get better with time.

Another thing which I could associate with is pair programming which just juggles my process. There are at least 6 things that I am thinking then the guy next to me says that is should be done this or that way, and I already lost what I thought. And you need to rebuild your entire modeling over and over and over again. Its demoralizing and energy consuming way overboard. So long story short people are different and the entire point of pair programming is talking about the problem and getting better with problem-solving by communicating.

I quote one of my latest interview where the guy said "just don't sweat over it there is no best answer". Which he was trying to say that the only thing they were interested in that I could use "lego" to build and reason about my building or not.

And I could give more and more advice. But it's okay if you feel that way, Proves that you care . And there are some quotes about being human and all.

</comment></comment><comment><USER10> Hey,

Its a tricky time of day to be asking. Fortunately at least one person is up. ;)

First off there are considerable reasons why this might be happening, and a few ways to deal with it. But its going to be a lot of hard work. Rather than speculating, what Im going to suggest is that you take advantage of any programs at school and talk to a therapist or counsellor that is familiar with these types of issues.

Outside of that, prepare to roll up your sleeves. The mind and body are like an elastic and youre going to have to stretch it a little. You may have been protecting yourself from criticism for a little too long. Avoiding anything too difficult; too easy to fail at. Unfortunately this isnt the best way to grow. Try and be open to criticism, by understanding that its an opinion. Its feedback. Sometimes it helps you get better, and does not rob you of any accomplishment or success, no matter how sleight.

Try things that are difficult and fail. This is sometimes the best way to learn.

Find a mentor or someone you look up to and ask for guidance. You might feel awkward at first, but most people will be flattered. This is a more "safe" way to learn from experience.

Please remember to be kind to yourself during this process. Its easy to have negative self-talk. Be aware when this happens and try and steer your narrative to something that acknowledges your progress; do not rely on comparisons.

</comment><comment><USER11> Consider the following approach: start with simple problems you know you're good enough to solve, and then _send them out of the ballpark_ \-- basically, do such a complete, perfectionist job that you can't help but be impressed with yourself. If a subject is baffling you, consider picking a small area within it and then throwing all your energy at it and killing it dead. Confidence comes with success. Small successes can build up to bigger ones.

Edit: But persevere. It's my experience that it takes at least a year of work for any significant rewiring of personality and attitudes.

</comment><comment><USER12> > I'm super self-conscious when I'm coding as well as when I'm speaking > English--my 3rd language.

Wow, most people only speak one language and they do that badly. You speak 3! Your English is good in that post.

If this anxiety is affacting your day to day life you might want to consider a short corse of therapy. You could probably use a book or website.

"Mind Over Mood" is a respected book. [http://www.amazon.com/Mind-Over-Mood- Change-Changing/dp/0898...](http://www.amazon.com/Mind-Over-Mood-Change- Changing/dp/0898621283)

MoodGym is a respected Australian website. [https://moodgym.anu.edu.au/welcome](https://moodgym.anu.edu.au/welcome)

If you decide to use a therapist make sure you find someone with a reputable registration and that you are clear going in what you want to work on. Cognitive Behaviour Therapy is probably useful. It should take 8 to 14 weeks at an hour per week.

> And I tend to make a lot of syntax errors. I also tend to rely on > documentation a lot. Furthermore, I tend to make a lot of stupid mistakes > when I'm speaking English even though I have been living and attending > college in an English-speaking country for the past three years.

You are not stupid, and the mistakes you make are not stupid. English is hard! There are at least 7 different ways to pronounce "ough" (like in "rough" or "through" etc). It's tough for people to learn. Stresses on syllables come in different places. You might think that making mistakes is always bad and that everyone will judge you. Some people will judge you, but many more won't notice and even of the people who notice there'll be some people who don't care.

</comment><comment><USER13> > tend to make a lot of syntax errors.

Rely on your compiler. I'm a senior dev and I _still_ so a build on my machine before doing a code review. One less thing to worry about if you make it a habit.

As for the poor English: I would think that any reasonable English person would care about the quality of your English. I assume that most reasonable people would realise that English is the "universal language" and would then also realise that it isn't everyone's first language.

Professionally I have been working in almost the same situation as you: 7 years at an Afrikaans company and I started off not knowing a word of the language. _Friendly_ jokes were made, but everyone always realised that it's more important that we could communicate and not how well we could communicate.

Basically what I'm saying is that the only person who actually cares about the quality of your English is: _you._

</comment><comment><USER14> You provided a lot of details about what's happening, but not a lot of details about what's going wrong (the emotions)... so I'm not sure if this will apply to you, but I'm going to say it in the hope it'll be useful to someone:

The goal of programming isn't that _you_ perform flawlessly, the goal of programming is to have fun while building something that performs well.

To put that another way: It doesn't matter how many mistakes you make while coding, what matters is that you eventually build something that works. Lean on test cases, write drafts that don't work, say dumb things. It's great. It's learning. Find the flaws, and then fix them -- mistakes don't matter as long as you remove them before shipping the code... and spotting errors seems to be something you're good at :p

</comment><comment><USER15> Lots of great advice already.

There will always be people smarter and better than you. All you can do is do your best.

It's hard to be a programmer in a world where 99% of every article about programming is some sort of epic tale of mindblowing success. What those stories don't tell you is the road it took to get there. Most success stories are results of the team banging their heads against the wall for months or years until they found what works.

The life of a programmer is a neverending series of fixing your own, or if you're unlucky other people's, mistakes. There is no such thing as a perfect computer program. Occasionally you get to see the results of your work have positive impact on something or someone. Savor those moments, they don't come often for most of us.

</comment><comment><USER16> > I also tend to rely on documentation a lot.

I rely heavily on resources like StackOverflow, Google, official docs and Dash.app is a godsend for offline-coding. There are many functions (python) standard library functions that I know by name, but I never remember the call- signatures for. I am _always_ looking things up in documentation.

Things that I use all of the time are ingrained into memory through rote repetition.

That said, the most important thing is knowing what exists. If you don't know that a function or method exists, then you don't know to use it. As long as you know that it exists, you can (usually) easily lookup the documentation for how to use it.

> I freak out when I have to pair program with someone or when someone else is > reviewing my code.

I've always hated being in the driver's seat for pair programming. I always feel like I make stupid mistakes and my fingers stumbled over the keys whenever someone is looking over my shoulder (this doesn't just apply to pair programming). I much prefer to just put in my headphones, get into the zone and let the rest of the world melt away as I dive into the problem at hand.

My suggestion here? Let someone else into the driver's seat for pair programming and don't be afraid to ask questions, especially if you consider the other person more skilled than yourself. If the person gets annoyed at your asking questions, then they aren't a very good mentor.

</comment><comment> aki-xiii As someone with a similar background as yours (I was an international CS student who first learned programming in the freshman year at a English- speaking college), I can only say that you are not alone in this struggle. If I can give an advice to my younger self, I would ask myself not to beat myself too much for not being able to be as smart as the people around me. In short, don't compare yourself to others, because it gives more harm than good. Instead, appreciate the good thing you have done and keep doing your best at whatever things in front of you.

> I tend to make a lot of syntax errors. I also tend to rely on documentation > a lot.

Believe it or not, many of us who work in the software industry rely heavily on IDE to fix syntax errors. My suggestion here is try to pick your favorite language and keep practicing (and make mistakes) until you're comfortable using it. I hate to say that there is no shortcut in getting better. Small mistakes are tolerable, even when you're doing whiteboard interview later on. More importantly, I would say that understanding concepts in programming languages is a LOT more important than remembering syntax (i.e. memory management in C, heavy emphasis of OO in java, functional programming in scheme, and so on).

As for relying on the documentation, it does not come across as a bad thing to me. For example, before I call a function from a 3rd party library, every so often I check the documentation for it. From there I can learn the contract of the code or some gotchas that I need to be aware of.

</comment><comment><USER17> You are battling. Good! You are alive! Even better- you have and are conscious of your strategy for the fight. You are already 90% of the way to superhero.

As pointed out elsewhere, this is a long game. You may not be happy with your current scoring capacity, but you have plenty of time to improve your techniques, alter your strategies. Perhaps "avoid solving hard coding problems" is not the best approach (though it may be, every one is different and perhaps your confidence builds by successfully tackling a large number of easier problems). Your self consciousness can morph into self awareness.

Does making syntax errors help you? If not, try a different approach. Look, making errors MIGHT help you. You learn exactly where you need to sharpen and improve your thinking. Valuable feedback.

One more thing: mind and body are one. Get to a gym 3x week, and do squats. Two sets, 20 reps per set. First day do it with an empty bar. Each time you are in the gym, up the weight by 4 lbs. Six months from now your mental toughness will be through the roof. People _will_ look at you differently.

</comment><comment><USER18> > _I also tend to rely on documentation a lot._

I'm writing some code in a language that I made myself from scratch. I rely on the reference manual quite a lot. Thank goodness I wrote one or else I'd have to go into the source code.

I make syntax errors even though I designed the machine that is telling me that I make syntax errors.

</comment><comment><USER19> \- You're allowed to make mistakes, that's what being a student is all about. If you knew it all already, you wouldn't need to study, right?

\- Practice makes perfect. You just gotta keep trying and failing; eventually you'll find you fail less often than you try. Don't avoid trying out of a fear of failing, or you'll end up doing nothing, which is worse than feeling embarrassed.

\- Don't feel self-conscious about your English skills. Ultimately it doesn't matter; I've worked with programmers from around the world, often with "quirks" in their written/spoken English skills, and never has it been a barrier to communication. A common understanding of the theoretical CS concepts should help.

\- Try mindfulness meditation. Focusing on the present and awareness of the world around you might help direct your focus outwards instead of inwards.

</comment><comment><USER20> My two cents: Work hard at improving your knowledge and experience, find yourself a tribe (it really helps in learning when you are not in it alone and having someone to work with as time goes on becomes invaluable), and find yourself a mentor. A mentor will help you learn by exposing you to things that will not only keep you interested and engaged but also push you just beyond your capabilities so you grow at a bearable/reasonable pace. That mentor may be the leader of your tribe or just a more knowledgeable resource. A mentor will be someone that believes in you, which is also invaluable. Fake nothing. Ask questions, learn, and alway admit what you don't know. When you do suddenly it becomes clear how to fill in the blanks. Don't be afraid to fail or be wrong. That's just part of learning.

</comment><comment><USER21> Realize (accept, internalize) that we make mistakes no matter how hard we are trying to avoid them, so being too anxious about making one is just a waste of effort (oxigen, glucose) and self-impoverishment.

Grammar mistakes in third languages are OK, the meaning of what you are intended to say is what is important. From could be imperfect if it makes sense. Striving for a perfect order of long words is what killed lots of would be writers.

Same concepts work for programming. As long as your data-structures are repressing the problem domain adequately and choice of related algorithms is reasonable, all the minor mistakes or errors doesn't matter.

BTW, there is no such thing as error in universe. It is mere a wrong path (branch) taken (take a look at what is a heuristic-based depth-first limited back-tracking search).

</comment><comment><USER22> I agree with other posters who say that everyone makes syntax errors, and that relying on documentation is fine (consulting documentation, and not just banging out something that seems to work, is a mark of a good developer)

With that said:

Coding fluency is something that can be improved with practice. Google Code Jam has all the previous rounds available, and there are other similar sites. Do a round once a week, and hold yourself to the time limit. It will be unpleasant, and you might not think you do well, but no one will be watching. That context trains you to write correct code quickly, and you will improve with practice. You'll find that the coding fluency you gain helps your programming more generally.

</comment><comment><USER23> "The root of all our problems is our inability to let go", Leo Babauta in the free "Letting go book" [http://zenhabits.net/lg/](http://zenhabits.net/lg/)

So if that holds true, you might be holding on to a statement like "my poor english makes people think I am less of a person" \- but if you try to investigate that statement you might discover that the world is full of people speaking poorly english that is not a lessor person.

Try see what internal beliefs that your are holding on to, often these belief is not true when examined, and if you let go of these beliefs you also let go of your self doubt.

</comment><comment><USER24> Someone else smarter than I am should tell you how to deal with this issue. I just wanted to say that having been in a similar situation and then starting work, I can tell you are going to be a great developer just because you care.

From all the people I've worked with, the ones who cared were always better than the ones who didn't, and you'll be surprised at the number who don't. Of course there are other things like experience and all that, but the fact that you actually care about your ability and hopefully want to improve already will take you very far. So have faith in yourself because I certainly have faith in you random person on the internet =D

</comment><comment><USER25> Take a deep breath. Relax. Pick up a hobby that doesn't require you to sit in front of a computer. Life's too short to be stressed, and no one is judging you.

</comment><comment><USER26> I think these issues are normal for most people starting out. Just accept that there will be many challenges. With diligence and time, you will be able to conquer them all. Keep pushing yourself and eventually the hard stuff won't be hard anymore.

Accept that you will mistakes, and that it's okay to do so. Correct them and learn from them. Keep working and keep getting better. Your biggest competition is yourself in the past.

</comment><comment><USER27> It's called Imposter Syndrome, and you are certainly not the only one.

My advice?

Read this: [http://www.hanselman.com/blog/ImAPhonyAreYou.aspx](http://www.hanselman.com/blog/ImAPhonyAreYou.aspx)

Watch this: [https://www.youtube.com/watch?v=hIJdFxYlEKE](https://www.youtube.com/watch?v=hIJdFxYlEKE)

</comment><comment><USER28> Let me say right off the bat your written English is impeccable, IMO as a native English speaker. I understand it's quite possible you spent a lot of time reviewing and revising your post... I do that too, with all of the code I feel most proud of :)

I used to be pretty bad at programming. I also used to be pretty bad at walking; when I was born I couldn't even sit up straight or crawl, let alone walk!

I have not always been a big fan of pair programming. In fact sometimes I feel very introverted and just down-right don't want to sit down with a coworker and go through something. But, some of my best memories from school are sitting with my OS and later RTOS partner, who was from China and spoke pretty poor English, and working through our issues into the middle of the night and beyond. And these past few weeks, I've spent hours every day with a very extroverted coworker getting our code just right (it's still not done). I mentioned offhandedly how "dealing with people is a skill, one I'm still working to develop" and he said that he thought I was good at doing it. I asked, "Really?" and he said "yes", and I replied that I really appreciated the comment and the thought.

I don't think I can allay your fears, and I can't say with certainty that they are misplaced, but I believe to some (perhaps large) extent they are. But I understand them, deal with similar issues of my own, and I have a pretty successful career by my standards.

If I were in your shoes, I'd try to sit (alone) and work on some of those hard coding problems. I've heard good things about the book "Cracking the Coding Interview" and I have made a couple of half-assed attempts to go through it, and lately I intend to go at it full force and see where it takes me. I'd also try to list all of the things that I've learned and how far I came from when I first started programming - I learned from the gentle introduction in C for Dummies, quickly got in over my head, and had a friend help me with pointing out all the off-by-one errors in my new fancy lightbar menu code bit that I wrote for Borland C/DOS, and my fancy console input routines. I've looked back on my journey, and taken large steps backwards due to personal issues. But I've always moved forward in the end...

</comment><comment><USER29> > I also tend to rely on documentation a lot.

This is the best way to work. I am speaking from my experience. It will keep you on right track to get things done.

> I tend to make a lot of stupid mistakes when I'm speaking English

try to be friends with your class\batch mates. It is far easier than becoming friends with outside people (strangers). Go out on lunch\drinks with them. Slowly your circle with increase and eventually you will see improvement in your communication and socializing skills.

</comment><comment><USER30> Secular meditation.

The second half of this helped me with the effects of my doubt. [https://www.youtube.com/watch?v=KmEG3zzCUQs](https://www.youtube.com/watch?v=KmEG3zzCUQs)

The thing I did was to hold my doubt like a mother cradles a baby, don't deny it, acknowledging it. Until this is a joke and you're laughing at what the hell you were so worried about :) "Love your thoughts to death"

</comment><comment><USER31> Your written english is outstanding. I wouldn't have guessed non-native. I found two errors in the last sentence (advice instead of advices, a lot instead of lot) but these are minor ones.

Set yourself up for success. If you do better when someone reviews your code then spend your time on reading documentation and writing good code before review. In pair programming, look for opportunities to shadow and review rather than write.

</comment><comment><USER32> When comparing yourself to the rest of the world, always remember that you only know how "great" other people are because they told everyone that they are. Then remember this: [https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect](https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect)

</comment><comment> andrew-lucker Just stop it.

Seriously though, you learn a new human language and jump into one of the most intense fields of study and start having an inferiority complex? With that attitude you'll need to be world renowned before you have confidence to speak in public.

If there is anything I can do to help, as a native English speaker with programming/CS experience, my email is in my profile. Best of luck.

</comment><comment><USER33> some great advice already posted.

try to not get to lost on where you are and how big of a delta to where you envision it is that you want to be. slow down if needed.

Try to enjoy where you are and master it. give your self credit at the level you are at. be proud of your code even if others are not kind. strive to make it better. always be improving.

be pragmatic. don't get lost in the weeds of politics, status, or any specific sort of rabbit hole that you won't learn from. if you aren't sure whether you will learn from, you probably will.

someone posted recently. if it's not a hell yes, then it's a no. I really like that. don't take on too much.

anxiety can suck. take it one day at a time, and learn to get the courage to ask questions when needed and practice the art of asking questions. it will be invaluable.

if you can find something passionate that excites you, remember this moment. occasionally refer to what makes you passionate and recalibrate as needed. if you find no passion, maybe take a break and revisit later.

good luck!

</comment><comment><USER34> _Before you treat yourself for depression, make sure that you are not in fact surrounded by A_ _holes_

\- William Gibson

</comment><comment><USER35> I know how you feel. Just finishing up my biosciences degree and the stress has really screwed up my learning. Projects and coursework were fine but examinations were awful. Never did figure out how to get over it and I regret not seeing my doctor about my issues.

</comment><comment><USER36> Hey man - don't beat yourself up. I can barely code and still can amaze myself. I would say just do things that you think you cannot do. And don' think about the outcome. You would find just by taking the initiative you can do anything.

</comment><comment><USER37> Clearly the anxiety is getting in the way of work and study, so it's time to visit a specialist in psychotherapy. Your college advisors or your primary physician should be able to suggest the right person in your location.

Your English is fine, by the way.

</comment><comment><USER38> [https://en.wikipedia.org/wiki/Impostor_syndrome](https://en.wikipedia.org/wiki/Impostor_syndrome) is extremely common in high achievers--you're not alone.

</comment><comment><USER39> the key to success is being able to walk through fear and anxiety and learn from it. it doesn't matter if you make plenty of syntax errors, it only matters if you pay attention and learn why you made those errors. rome wasn't built in a day. stop beating yourself up and cut yourself a break. most programmers in the world are the same as you and many of them (including me) have gone through periods of inferiority or self-doubt (or imposter syndrome).

just try to stay focused and dont spread yourself too thin when it comes to learning. build a foundation one day at a time.

have fun, laugh a lot, live free follow your dreams.

</comment><comment><USER40> I don't have any actionable advice, but I do recommend you get it sorted out if at all possible. I'm a former programmer who now works as a janitor, and I have no plans on ever returning to tech.

</comment><comment><USER41> This is what it's like to learn something real. Also, every programmer makes mistakes. That's never going to stop. Ever. A good IDE will help with syntax errors.

It gets better.

</comment><comment><USER42> heh, relying on documentation means literally nothing for programming. I have multiple tabs of documentation open and the IDE is the only thing that keeps me from checking in broken code on a regular basis(still happens though). But... to my manager and my co-workers, I'm a god of programming cause I do shit that they didn't even think was possible.

<comment><USER43> There's a joke that the job of Dev Support is looking up documentation for people too distracted, too stressed, or too stupid to look it up themselves.

<comment><USER42> Man, I would love to just have someone with perfect recall sitting next to me full time. "What's the arguments to this function?" "Where's the class that handles blah?". Intellisense and go to definition and such only help so much, and only in certain languages.

</comment></comment></comment><comment><USER44> Work on things that no one else is doing. If there is no precedence, the better.

</comment><comment><USER45> Lots of good advice here already!

My suggestion is to tackle this from the language side first. It's really frustrating to be "trapped" behind a foreign language, feeling that you can't express yourself. It gets harder to learn languages as one gets older, and learning a language is like climbing a staircase: you struggle for what seems for ever with something, then you jump up a level, and everything seems a bit easier. Until you realize you're on a plateau, and you don't seem to be getting better. Again. And again. And again.

So that's one thing: even when you feel like you're standing still, as long as you're immersed in a foreign language, you _are_ improving. Even if it doesn't feel like it.

Best advice here is just to find low-stress arenas to practice. Join a sports club, chess club, book club, film club, martial arts club... you get the idea -- find some people that share your interest and hang out. Talk without having to deal with a foreign and difficult subject at the same time.

That might help with the anxiety connected to English.

You mention English is your third language, are you using both the other two actively? If you can, it is usually much easier to learn a language if you can avoid switching back and forth -- and just stay in the new(est) one all the time. Talk, think, do everything in English. Avoid phone/video calls in your native tongue (within reason) -- try to stick to email/letters. If you think it's hard, try to make a deal with anyone you call regularly, say you'll try to give it three months. Let your brain work for you.

Don't worry about the syntax errors in code. Just code more, and you'll make fewer mistakes. Try to code for fun, or at least outside of a class setting, without any pressure. Maybe sign up at codeeval.com and try your hand at some of the easy exercises first.

Many of the problems there are pretty much lifted from project euler -- and that's a good resource too. But with codeeval everything is wrapped up nice, very little setup needed, and you can just play around.

Last, but not least -- you mention you're attending college -- try and talk with one of your TAs, professors or fellow students. See if someone might have the time to pair program with you, on something not directly related to class (again, try to avoid to stack different kinds of pressure anxiety). For example, you could make a deal to try and solve some easy codeeval (no, I'm not affiliated, it's just an easy source of a few exercises) challenges.

Finally: the best way to learn is to make mistakes. It's certainly _much_ better to make mistakes than do nothing. And if you make errors while pair programming, not only do _you_ learn from your mistake, your partner does to!

</comment><comment><USER46> Don't</comment>


Critiquing Facebook's new PHP spec - <AUTHOR> http://blog.circleci.com/critiquing-facebooks-new-php-spec/

<comment><USER2> "One other thing they specified is that array cursors are internal.... This would manifests if a new PHP implementation wanted to use a different threading model: would two threads looping through the same array use the same cursor? Sounds pretty racy."

Is it even worth it to leave room for a threaded PHP? At this point that would _de facto_ be another language anyhow... the changes required to add threading to a language like PHP [1] _20 years_ after it was born are too insane to even think about. It would be so many years before it was stable enough to begin building any sort of library infrastructure that would make it into any sort of common use that the language would probably be on the way out by the time this gauntlet could be run. See Perl's experience with trying to add threading.

It would certainly require another specification document anyhow.

I'm of the opinion that languages around the 10 year mark (which PHP is obviously well past) really ought to focus on becoming the best X they can be, rather than chasing the tail lights of constantly-moving best practice. Seems like you're better off just making PHP be the best PHP it can be rather than try to add threading in to the mix. PHP certainly simply isn't going to be able to compete with existing languages that build some sort of solid threading story in from day 1, and, frankly, it shouldn't try. (And most of _those_ languages simply can't compete with PHP on its home turf, after all.)

[1]: Mutable-state imperative dynamic. Basically, the answer to the question "What's the hardest sort of common language to add threading to after the fact?"

<comment><USER3>
      I'm of the opinion that languages around the 10 year mark
      (which PHP is obviously well past) really ought to focus on
      becoming the best X they can be, rather than chasing the
      tail lights of constantly-moving best practice.

Would that include not adding:

      * Anonymous functions and closures
      * Namespaces
      * Late static binding
      * Dynamic dispatching to static methods
      * Rackup/SimpleHTTPServer-like web server
      * "finally" in exception-handling
      * Being able to call foo()[0] instead of the clumsy
        assign-then-dereference two-step.

What does "the best PHP it can be" mean? Anonymous functions (for example) are arguably way outside the style of the PHP from ten years ago, but they're tremendously useful.

(I used to use PHP. I dislike it as a language, but I have nothing against them continuing to improve it like they have over the last nine years.)

PS: PHP already supports threading via a PECL module. [http://php.net/manual/en/class.thread.php](http://php.net/manual/en/class.thread.php)

<comment><USER2> "Would that include not adding:"

A whole bunch of completely standard features to add to a mutable-state dynamic scripting language, almost each and every one of which had been successfully added to a mutable-state dynamic scripting language before PHP did it? Of course not.

(I'm not sure about that last one, though I suspect one could find a version of Perl early into its reference experimentations that would have an equivalent problem. Even today, I'm not sure if a function that returns a list (not list ref) can be directly dereferenced into via [] notation. Or at least it's klunky. And let me clarify that I do mean _added_ to an existing language, not programmed in from the beginning, which is a very different problem.)

I'd also add generators into that list.

Adding pervasive threading is a different story. Adding threading to a mutable-state dynamic scripting language has a long and sordid history... even when it is nominally successful (as in Python) it is still not very useful, and at times it has been simply a failure (like Perl).

As another example, though, I would suggest the principle would be firmly against trying to add Hindley-Milner typing to the language, or making some big move in an immutable direction. That's not PHP... that's not "mutable- state dynamic scripting language". I'd also suggest against burning any time in trying to make PHP not a "scripting" language anymore, on the grounds that Hack is the right approach; create a companion language that may integrate well, may even still be a "dialect" of PHP, but is not "PHP" anymore, and can do the non-scripting work without actually trying to bodge that into PHP proper.

"PS: PHP already supports threading via a PECL module."

Yeah. Perl "supports" threading too... for sufficiently small definitions of "supports". Unsurprisingly, when I googled "PHP thread" (without quotes in the search), once you get past what are for me the first three links which are for the documentation itself, the remainder of the results consist of people asking and/or explaining why you can't trust it or use it. Compare with the Google search for "perl thread". (Pretty much the same except with Perl, even the documentation warns you away from using it.)

PHP is a mutable-state dynamic scripting language. It can continue importing anything it likes from that realm as all the mutable-state dynamic scripting languages continue to converge on the same basic core of features, which I have in the past called CLispScript but really there's any number of things you could reasonably call it. Good threading support is not in that core set of features. The history of other extremely similar languages extremely strongly suggests it would be little more than a staggeringly enormous waste of time.

But of course, if PHP would like to ignore that history, go nuts. I see no reason to believe that its internals and API are so especially cleanly designed that threading will be a breeze to add on, but hey, go prove me wrong. (That might sound like a sarcastic snipe at PHP at first. And I won't lie, I don't like PHP. But the truth is simply that adding threading on 20 years later is _insanely difficult_ if you haven't been planning for it all along, and that's pretty much regardless of the underlying language. If you have been planning for it it's merely very difficult. So very, very many things will fundamentally depend on the implicit lock that you get by everything being single-threaded that you don't even realize it until you try to add the threading on and realize just how _thoroughly_ the assumption has been baked into the VM, the runtime, every library, every framework, every binding... everything.)

For another "see also", look at Javascript, another fairly similar language to PHP in the grand land of programming languages (mutable-state dynamic scripting language). There is a _reason_ we have "Web Workers" and we don't have "Javascript Threading", and it isn't all "browser".

Incidentally, since for I don't even know what reason HN has somehow decided that my first post is unworthy, do note that it's a serious engineering question. Spending design capital on "keeping things safe for future threading" is not free, and if there really isn't any chance that PHP is going to be threaded in the future, you're better off claiming the bounty of staying single-threaded in the spec than complexifying it with things that will never be used, because being able to _guarantee_ single-threadedness is actually a big win in its own way... if you've got it, _use_ it. And, again, the actual _history_ of adding threading to this sort of language is not very promising at all.

(Edit: A bit more searching finds a few people suggesting that PHP threading may be usable, though it made the transition to that quite recently. It still doesn't sound like it's something I'd touch after all the other times I've been burned in other environments with similar level of promises and experiences. YMMV.)

<comment><USER4> > Even today, I'm not sure if a function that returns a list (not list ref) > can be directly dereferenced into via [] notation.

Unless it's changed very recently, you cannot; you have to wrap it in an arrayref, e.g.

        [returnsAList()]->[0]

<comment><USER5> all lists can be sliced with the [] notation.

the above example would returnsAList, put it in a new array reference, then dereference it. probably not want you want.

To get the first item from the sub with [] notation would be (returnsAList)[0]

perl -e 'sub returnsAList { return 0..5 }; $v = (returnsAList)[3]; warn $v'

</comment></comment></comment></comment></comment><comment><USER6> After reading your critique, I'm now very confused on where this spec stands. Is Zend bound by it (I don't think so)? For example, you mention absence of RAII, I don't think that Zend's PHP will lack RAII (because they don't break BC), but new implementations following this (proposed?) spec are free to disallow it

<comment><AUTHOR> No, but I believe they're excited by it (according to Facebook's post at least).

I'd expect Zend to keep supporting RAII, but I doubt new implementations will - its a real drag on building better GCs, and that can be as much as half the performance of a program.

<comment><USER7> I think the language would really need more features, like using blocks from C#, to be effective without RAII. The finally clause was only just added in the last release.

The spec, as it stands, is flawed. Any removal of RAII should be left to major version (e.g. PHP7). Since this spec is meant to represent the _current_ state of PHP, it's completely incorrect in this area.

<comment><AUTHOR> I disagree. They underspecified the language, so it still technically represents the current state of the Zend implementation of PHP.

(I take no position on RAII being useful or not, I don't write PHP for a living).

<comment><USER7> It's in direct conflict with the PHP manual:

[http://php.net/manual/en/language.oop5.decon.php#language.oo...](http://php.net/manual/en/language.oop5.decon.php#language.oop5.decon.destructor)

"PHP 5 introduces a destructor concept similar to that of other object- oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence."

It's _very_ common to rely on this behavior to do cleanup as PHP did not have a finally clause (like C++) until recently.

<comment><AUTHOR> I think we're talking at cross-purposes. I'm just saying that because it's underspecified, the Zend engine can be both accurate to what's in the PHP manual, and to what's in the spec.

Anyway, it's a slightly pedantic point, so I'm probably not contributing much to the conversation here :)

<comment><USER7> I understand your point. The spec as written means the Zend Engine itself is accurate the spec. The problem is the spec isn't accurate to the language, as it exists, in the wild. Existing correct and valid PHP code executed to this spec will behave incorrectly. Therefore, it's not really a PHP spec.

PHP Code > PHP Spec > PHP Engine

</comment></comment></comment></comment></comment></comment></comment><comment><USER8> >Rather than trying to specify the exact algorithm for everything (which is what the JS spec typically does, for example), they chose to describe the Zend model (or close enough) and say "it has to appear to work like this".

To be fair, the JS spec may say those things but no modern JS engine actually does it that way. Despite the wording, "must appear to..." is the common interpretation of that spec. It is nice that this one makes that explicit, though.

<comment><USER9> On the other hand, there's been a fair bit of work (esp. for ES6, and to a lesser extent ES5) to minimize the number of things the specification states contrary to implementations.

</comment></comment><comment><USER7> Under GC:

> I read this as saying that when a variable dies, you must immediately clear > it up. I suspect that this will make the GC a little less flexible than it > has to be.

I think the key reason for this is that objects have deterministic destruction in PHP which allows for the RAII pattern. This is in contrast with garbage collection in Java or C# where finalizers aren't called immediately (or sometimes at all) and the RAII pattern is impossible.

I suspect if you could leave memory lying longer around as long as you destructed objects and resources immediately but there probably isn't any advantage to that. But changing the destruction characteristics would break code that depends on it.

<comment><AUTHOR> That part of the spec refers to variables (which the spec calls VSlots), not objects (which the spec calls HStores).

Objects have different lifetimes, and the spec actually allows the destructors to be run anytime between the object being dead and the program ending. So it looks like there won't be any RAII here.

<comment><USER7> No RAII would be a big change in the behavior of PHP; you should add that information to your critique. I have code that relies on RAII for error recovery and rollback. Any PHP implementation that doesn't do RAII is going to subtly break a lot of code.

It doesn't make sense to force very specific memory lifetimes for variables and then also not do it for objects.

<comment><USER10> The problem being it's not RAII but a side-effect of reference-counting[0] (Python had the same issue, it's been a pain for alternative implementations and a big reason for `with` being added to the language)

[0] it doesn't work when there's a cycle for instance

<comment><USER7> PHP developers specifically took into consideration RAII when designing the language. This is why the finally clause for exceptions was not originally part of the language -- it was unnecessary for cleanup if you have RAII. Cycles don't really affect RAII in meaningful way.

<comment><USER10> > PHP developers specifically took into consideration RAII when designing the > language.

No part of that phrase matches reality.

> Cycles don't really affect RAII in meaningful way.

Which is irrelevant because once again what PHP has _is not RAII_ it's reference counting, same as CPython and Objective-C. And because it's refcounting it _does_ have an impact: objects involved in or linked from a cycle are not immediately cleaned up once the cycle goes out of scope because all objects still have a refcount of at least 1.

Cycles which, by the way, PHP did not bother breaking until 5.3: [http://php.net/manual/en/features.gc.collecting- cycles.php](http://php.net/manual/en/features.gc.collecting-cycles.php) so these objects would live until process death.

<comment><USER7> > No part of that phrase matches reality.

It's true. When exception handling was added to PHP, RAII was absolutely factored into the design. This is why it didn't get a _finally_ clause to start with -- it's unnecessary.

> Which is irrelevant because once again what PHP has is not RAII it's > reference counting

[http://www.hackcraft.net/raii/](http://www.hackcraft.net/raii/)

[http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initial...](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)

If you have reference counting or stack allocated objects than you can do RAII. You seem to be confused as what these terms mean -- they are not contradictory, they are complimentary. Ref counting allows RAII.

</comment></comment></comment></comment></comment></comment></comment><comment><USER11> I can see the appeal of allowing behavior variant from Zend in areas where there is a big benefit, and I like the approach of defining these areas as "implementation-dependent" rather than specifying one or the other.

However, it seems to me that some of these are in areas where PHP code would need to know the runtime behavior of the platform they're on; the alternative is just to avoid all such areas ("there be dragons here") or to give up on portability and be implementation-dependent, in which case it seems to me that there's not much value in having a PHP standard (other than as a base document on which to build the Zend or HHVM specifications).

Why not have the specification allow runtimes to expose their choices of behavior into the runtime to allow code to determine what their platform does? Of course, one can probably write tests for these behaviors and build a library, but it seems like it would be better to just delineate the alternative behaviors and put them into the ABI.

<comment><USER12> > _Why not have the specification allow runtimes to expose their choices of > behavior into the runtime to allow code to determine what their platform > does?_

Because the idea is that it should be transparent to the code. If you start doing that you get into mess like the "feature sniffing" BS JS does in browsers, IFDEFs etc...

So, which of these specifically seem to you to be "on areas were code would need to know the runtime behavior"?

<comment><USER11> I don't know the details of PHP, but it seems to me that all the areas that are referred to as "implementation-dependent" are code-observable: e.g. the deferred array copying decision discussed in the critique: if your code depends on a behavior, you'll get different results on the other platform. So if you want to be portable, you need to sniff the behavior and take a different route on the alternate platform, or you need to avoid the quicksand in the first place.

<comment><USER12> > _are code-observable: e.g. the deferred array copying decision discussed in > the critique: if your code depends on a behavior, you 'll get different > results on the other platform._

I don't see how the "deferred array copying" ever leak to the program you write. Copy-on-write and such is a classic example of implementation detail that the higher layer is not concerned about.

<comment><USER11> Read the post; apparently Zend doesn't make deep array copies in some circumstances.

The quote from the spec is "Unlike conforming deferred string copy mechanisms discussed in §§ that must produce the same observable behavior as eager string copying, deferred array copy mechanisms are allowed in some cases to exhibit observably different behavior than eager array copying."

Note the phrasing "observably different behavior".

<comment><AUTHOR> It is definitely observable.

</comment></comment></comment></comment></comment></comment><comment><USER13> I don't understand what you wrote about "deferred array copying".

When I ran your code I got "PHP Notice: Undefined offset: 1"

If I removed that line then I got "2 3" which seemed wrong to me since those two variables should have been aliases to the same thing. But copying the values instead of the reference seems slower, not faster.

</comment><comment><USER14> Good to finally see a PHP spec! You might also be interested in a formal semantics for PHP which has been presented today at the ECOOP'14 conference in Uppsala, Sweden. Details can be found at www.phpsemantics.org. As I wrote before, I wish we had this spec a couple of years before - our life would have been so much easier! :)

</comment><comment><USER15> > describe the difference between

$a = new Point(1, 3)

and

$a =& new Point (1, 3)

Answer: I forget! I think it's that the next assignment to "$a` will do something odd, but honestly I don't remember the subtleties.

So what is the difference exactly?

</comment><comment><USER16> I don't think your comment on Overflows - "Zend is by definition a correct implementation" \- is necessarily right - elsewhere we're definitely looking at Zend having to change their implementation, right? Great article, BTW.

<comment><USER17> No, the spec leaves implementing it open. Something I'm trying to change as the behaviour in the spec is wrong.

</comment></comment><comment><USER18> Glad the conditional/ternary operator's atypical associativity is documented now...

</comment><comment><USER19> When I read the new PHP spec, I threw up in my mouth after I saw that empty("0") was a special case of empty that returned TRUE. I know that's how PHP normally works, but that doesn't really make my mouth taste any better.

<comment><USER7> The thing you have to understand about PHP, is it's meant to easily work in a world where every value is in a string. You get strings from the browser, you get strings from the database, and strings from the file system.

It was expected that these strings contain numbers and that you should be able to rationally use them as numbers without conversion. So "10" > "5" returns true in PHP where as that would be false in most other languages. The underlying representation of the value (sequence of characters, 2s compliment binary, or IEEE 754 double) means nothing in PHP; they are all supposed to be equivalent. So "12", 12, and 12.0 are the same and "0" and 0 are the same.

The consequence of this design ripples through to every aspect of the language. And it ripples down to the implementation of empty. Empty(0) is true. So therefore Empty("0") is also true. The fact that one is an integer and the other is a string is not a distinction that exists in PHP. It's super weird and unexpected but it's not illogical given the rules of the language.

<comment><USER20> > You get strings from the browser

Really? I thought browsers sent HTTP requests.

> you get strings from the database

Really? I thought databases returned tables, ie. ordered collections of rows with individually-typed columns.

> and strings from the file system.

Really? I thought filesystems returned streams of bytes.

Just because lots of values _can be represented by_ strings, doesn't mean they _are_ strings. "X is a string" is the cause of:

* XSS vulnerabilities: "HTML is a string" and "user input is a string"; why not concatenate them?

* SQL(/shell/eval/etc.) injection vulnerabilities: "SQL queries are strings" and "user input is a string"; why not concatenate them?

* Multilingual issues: "byte streams are strings"

* Malformed requests/responses (ie. 'message not understood', invalid markup, etc.): "requests/responses are strings"

I know you're stating the rules of PHP, rather than a personal opinion, but I think it's important to reiterate this point whenever "x is a string" comes up. Strings are an _implementation detail_ which should be abstracted over. After all, strings themselves are just an abstraction over bytes/words.

[http://c2.com/cgi/wiki?StringlyTyped](http://c2.com/cgi/wiki?StringlyTyped)

<comment><USER7> Much of the reasons for PHP being stringly typed are historical. For example, extremely old database drivers used to stringify everything so you didn't get individually-typed columns. An HTTP request, specifically an encoded GET or POST, all values from the browser are strings. A file system is a stream of bytes, but many common web file formats stringify all values (JSON, XML, INI, etc).

> Strings are an implementation detail which should be abstracted over.

That's exactly what PHP does -- PHP doesn't care what representation a value has. But that is also then the source of it's strangeness.

<comment><USER20> > > Strings are an implementation detail which should be abstracted over.

> That's exactly what PHP does -- PHP doesn't care what representation a value > has. But that is also then the source of it's strangeness.

I don't know if that's a valid use of the term "abstract", but it's certainly not what I meant. Rather than passing around low-level values for as long as possible, and only interpreting their contents when forced to (eg. when "+" forces them to be treated numerically); instead, I meant interpreting values as soon as possible so that they're treated as the appropriate type.

> An HTTP request, specifically an encoded GET or POST, all values from the > browser are strings.

Again, they're only _represented_ as strings. When I use an "order" parameter in my application, I want it to be an Order. I don't want it to be NULL. I don't want it to be a string which may-or-may-not be the numeric ID of an Order which may-or-may-not be stored in my database. If it's not an Order (eg. if the "readOrder" function I declared as the handler for this parameter returned [] instead of [$the_order]), the request is malformed so a HTTP 400 response should have been sent. My application should never even start if the data it needs isn't available.

Of course, that's exactly what "dependency injection" is in the OOP world; it's also a major use-case for the Reader monad in the Functional Programming world.

<comment><USER7> That is sort of the opposite of abstracting over the type but I get what you mean. I totally agree that interpreting values as soon as possible into the appropriate types is superior. I'm a big proponent of fail early. PHP, as with many scripting languages, are designed for short-term programmer convenience over long-term programmer convenience. Which given it's history and the original tasks it was designed for, that makes sense.

But PHP is moving in the direction of interpreting types quickly and failing early. Specifically, scalar type hinting seems like an almost certainty once there is an agreement on the semantics.

</comment></comment></comment></comment></comment></comment><comment><USER21> Critiquing the critique of Facebook's new PHP spec:

You used affect when you should have used effect. They probably don't teach that in the CS PhD program:)

Of course my post may be subject to Muphry's Law. But still. If you're going to spend so much time establishing your credibility, do you really want to ruin it by demonstrating you don't have a basic understanding of English grammar?

[http://en.wikipedia.org/wiki/Muphry's_law](http://en.wikipedia.org/wiki/Muphry's_law)

<comment><USER6> I'm not sure I would place any significance on something I have seen many native speakers screw up consistently. If you're not familiar with the author, you could take the time to read the blog post he linked to where he talked about HPHP and phc

<comment><USER21> If the affect/effect error was in isolation it wouldn't have been a big deal. When combined with a rant of how much of an expert he was the contrast led to quite a bit of cognitive dissonance.

<comment><USER22> He never claims to be an expert on English grammar.

<comment><USER23> Any grammar mistake negates any intellectual merit on the Internet...</comment></comment></comment></comment></comment>