Ask HN: What cool development languages/tools changed your career?

261 points by mirceasoaica ↗ HN
I've been a web developer for the past 10 years and I've mostly used PHP in my projects. I've also had a chance to code in JavaScript, C#, Delphi. I've had the chance to build large website (>500k users/day) and desktop apps used by millions of users per month, but I always used the technologies that felt comfortable to me. I knew Zend Framework very well, so I used that one to build the services.

My "oh wow" moment was when I discovered Phalcon PHP framework (https://phalconphp.com/en/) about a year ago. I've switched all our projects on this framework and saved thousands of $$ because of the performance impact.

The other thing that made my day was when I discovered Django (https://www.djangoproject.com/). I never knew Python, but I decided to give it a try. The performance is amazing (I always thought that it was slower than PHP - I was wrong) and it seems I can build the projects faster that I ever could using PHP (with any framework).

What were your "wow" moments in your career? What was your best decision to improve your work?

314 comments

[ 3.0 ms ] story [ 302 ms ] thread
I don't know if it was career changing, but NodeJS blew my mind when at the time our company was using a lot of PHP cron jobs.
Same thing happened to us. We moved a lot of cron logic to nodejs and we were able to increase speed and reduce hardware costs.
Tachyons.css: http://tachyons.io/

Suddenly CSS became fun again and my time designing websites went down by a guessed factor of 5.

I bookmarked it. Are you using bootstrap / foundation?
I've used bootstrap in the past, but not anymore.

Tachyons is different, it doesn't give you components but single-purpose classes and a font-relative layouting system:

http://tachyons.io/docs/layout/spacing/

It takes a while getting used to the names, but after that it's just awesome that you don't have to think about padding, margin and font-size values anymore. Just slap "pa1" or "pa2" there and everything looks pretty.

Doesn't it lead to inconsistent layout if someone forgets to add it? I am not a designer, but few things irks me more than paddings varying across the same 'components'.

From experience, your method is easier to think through, but later on it is more time consuming to modify a layout. pa1 and the like should be treated the same as magic numbers.

That is the point. Padding can't be inconsistent if there are only 7 values to choose from, not 1..7, but powers of two, so 0.125, 0.25, 0.5, 1, 2, 4, 8rem.
Joe will chooses 0.25, Mary picks with 0.125 while Huan goes with whatever is the default. There will be inconsistency if there is more than one choice available (empty is also a choice). Someone will slip up, it is only inevitable.
And if somebody doesn't use the library, but pixels or percentages, you get the same problem. You can't use a library to replace communication in a team.

But having 7 rem-relative steps, that fit together makes the common use-case way easier: Joe: "I need more padding on this, so I use pa2 instead of pa1".

If you feel the urge to check your code base it's easy to write scripts that count the occurences of "pa1..pa7". It's not so easy if you have to take into account "padding: 1px", "padding: 20%", "padding: 3em" etc.

What happens when your boss all of a sudden wants to change all the colors from blue to red?
I have the same problem, and I've yet to find an acceptable solution.

Another problem I've encountered: functional CSS (such as Tachyons) is only good for minimal layout. I was recently converting a mobile+tablet+desktop PSD design to CSS with very complicated reordering rules (this <div> is full height on the right on desktop, floated bottom of the page on tablet, etc.) and all my elements had 20+ classes attached to them.

So I went back and converted regular 60+ lines of CSS. Still, for some reason, working with Tachyons was for some reason faster and "easier" to reason about.

I think it's a step in the right direction, but we're not there yet.

That's a problem for your text-editor. Use search and replace.

Also, if you're using something like React, you can share the style strings in variables.

For me it was when I discovered React-Native. As a one man show in the beginning of our mobile application existence, developing both for Android and IOS at the same time was a blessing.
For me: https://d3js.org/ Once i learned how to use d3 i was like: This is what i want to do.
+1 for d3.js and the sentiment.

After about a year of using highcharts, for a specific custom chart project, I was given the opportunity to learn and implement it in d3. I built my first line chart by hand which took me little more than a week and then the custom chart project in about two weeks. It was definitely the most exciting project I have worked on so far.

Learning d3.js also made me rethink my 'use javascript as necessary' policy. I also came to appreciate what other charts libraries like highcharts do, but I won't be using those other libraries anytime soon if I can help it.

Django faster than raw PHP or Phalcon. I find that hard to believe. Are we talking PHP7?
I didn't do a benchmark. Phalcon is probably faster than Django (by a few miliseconds) but it is a compiled extension and also doesn't have all the functionality that Django has.

Django compared to Laravel (which is now probably the most popular PHP framework) is orders of magnitude faster. This is what I meant with Django being faster that PHP (this statement compares a framework with a programming language - not fair)

Without a benchmark I remain unconvinced. PHP7 performance was shown to have doubled since 5.6 in most cases, including with frameworks like Laravel. Prior to PHP7 it wasn't noticeably slower than Python.
Kivy (https://kivy.org) changed my career too. I make now a living mostly due to this project :)
What do you make a living with? I like Kivy but my clients would hang me from a tall tree if I would use it for actual projects because it feels very non-native.
C# + Visual Studio (2010 back then). I used to code in PSPad (Webdev, Python), then Emacs (C, Shell, Python). When I discovered VS with its debugger and C# with all the sugar, I was changed. I never stop using them since.
Clojure and Rich Hickey's sermons from the Mount. Absolutely game-changing.
My wow moment was when I quit trying to do everything in the language I was comfortable with (PHP) and became a language agnostic engineer. Since then (2 years ago) now I can write in 3 programming language, nobody can realize that I am new at these languages and I know that I can pick a new language up now in a very short time. I had to study so much in these last 2 years but since I love engineering it was funny rather than tiring. You do what you like and they pay for it, that is perfect. Before I used to search for PHP jobs and end up in low quality companies. After forgetting about languages, removing my limitations and focusing in engineering more than stack, my career significantly improved. Actually I got a tech management job in a big American company that I'd never imagine before.
This is the best advice on career management. Being able to break out of being "a php engineer" or "a java engineer" lets you target jobs and companies much more freely and ultimately lets you figure out what interests you as a developer in more real terms (and lets you go after it). It also sets you up to lead efforts on solving problems, rather than defining solutions in a more narrow window
yeah defo, learning my second language was big step in my development
for the last 7 years i've been a php developer and i'm currently in the process of learning my second language, #c. it's good to hear that someone else has been through this process before me and said it was such a big step!

thanks for giving me some more motivation!

I assure you many millions of people have been through this process before you! It gets easier after the second, particularly if you stick with mostly procedural/OO languages. So after C# you'll pick up Java, and maybe Python or Ruby in a heartbeat.

Languages with fundamentally different paradigms will still be a little tricky - Haskell, Scala, Stan, R etc don't bear a lot of resemblance to PHP.

I agree to a point... C# is fairly unlike ruby in its idioms. You will be able to write C# in ruby fairly easily but it's a language that doesn't benefit much from that.
Agree on this, and am at the same stage myself; C# is a huge transition from e.g. Php (or ColdFusion). Can't help but be amazed at the doors it opens up though - Pluralsight is definitely one of your friends here. Jon Skeet's walkthrough of C# 4, SOLID, the courses on DDD etc - so much to learn! :) MS Dev Essentials will give you a 3 month sub for free, if you didn't have that already.
In addition, you get to learn a lot of best practices from the trainers at PluralSight. If there were a similar company in the non Microsoft world with as comprehensive a library and as good a selection of trainers, I would love to know about it.

Also, check out their learning paths for C# - it can be a good option to avoid the overwhelm if you are new to the language.

C# is a really nice language. I'm hoping that the new .NET Core work will expand its reach beyond mainly Windows and get it popular on other platforms. Otherwise my book isn't going to do very well. :)
Book on .net Core on Linux; that's great timing, can't wait for you to share more info.

As someone super rusty on it, I found it remarkably easy to get up and running on the platform.

If they can only finish the tooling so that NCrunch can run properly, life will be a bliss.

The book is already out: https://unop.uk/book

The examples are in .NET Core (the cross-platform parts are more Mac than Linux focussed) but really it's a general guide on how to make web applications perform well.

My experience is the opposite, interestingly. I used to know and use a wide range of languages. Being able to say "6 years of professional Scala" has opened more doors, and focusing on a single language has allowed me to learn techniques and algorithms rather than worry about the differences between languages so much.
A colleague that I really respect told me at my last job that his career was a series of broadening and deepenings. He started with a deep knowledge of Java, but found that success came as he branched out into Python, Ruby, and Scala. At that point, he discovered that developing a focus on distributed computing with Scala was the key to the next level, and so on. I think half the challenge is identifying when its time to do one of those two.
"I had to study so much in these last 2 years" --> Could you give a glimpse on what have you studied/read? I'm very interested. Thanks!
It is not like studying a course in a organised way.. Luckily we switched to microservices architecture in my company and thus many stuff had to be rewritten. The old monolithic application was PHP and PHP was deprecated for new projects company wide. So I and my team picked GO, JAVA and Node.js for different microservices we are responsible for. (Mainly JAVA and GO, we deprecated then Node.js unofficially in our team because we did not like it at all.) So as you have a well defined project and you have to finish it in the language you are new with, you start to research and learn a lot. Tutorials, blogs etc. And when I had a problem and I could not solve the problem because of my unfamiliarity in the new stack, I started to read also after work and I started to apply what I learnt the next day. Every day I started to have less problem or finding solutions was taking less time because my involvement in that ecosystem increased. Specifically for JAVA, probably still I do not know many stuff, especially I don't have so much idea about the abandoned enterprise technologies, or legacy build tools like Ant etc. but still our applications have good quality and they are working well and my team did not receive any bad feedback from JAVA-expert fellows from the company, it means we adopted well the technology and caught the train.

I've to open a new paranthesis about Node.js. If you've never worked with Node.js before and you start in 2016 you're kinda f*cked up. The ecosystem is changing a lot and maybe 70% of the resources you can find over internet are already outdated. You start the day happy and with full batteries and you start to use some frameworks etc. The next day you realize that people already abandoned it. Beside all the disadvantages of Node.js, it's also so annoying and make the adoption process so hard. How such a simple language like Javascript could become so complicated?

GO is very cool. Relatively easy language and also very very powerful, it has a high quality community and the resources you can find are very clear. If you are trying to pick between GO and Node.js, go with GO. Your adoption will be much easier.

Thanks for the tips and insights, man! You were lucky to be in a project willing to rewrite the monolith with different technologies.

By the way, looks like you're living in Barcelona as well ;)

I used to live in Barna for a couple of years. Now in Berlin :)
Yeah. I agree. I dont understand how people build large Node projects.
> Specifically for JAVA [...] abandoned enterprise technologies

> [...]

> How such a simple language like Javascript could become so complicated?

;)

Well, let's admit that release-abandone cycle for a library/framework/approach in JS world is 100x faster :)
+1

I had the same learning moment a couple of years ago. I used to code mainly in Java so when I had to build a frontend, I tried to avoid Javascript and use some Java framework like GWT, Wicket or even Swing instead. At some point I grew tired of the pitfalls and limitations that I kept running into and decided to bite the bullet and just learn Javascript properly. It was a revelation.

TL;DR; Don't stubbornly stick to one language, choose the proper language for the job.

Sticking to one language is like being a carpenter and only having a hammer in your toolbox.
Interesting. I had the opposite experience. I started with C++ , then JavaScript, but ended up doing lots of PHP work. There are just so many PHP opportunities, the demand is still very high, but too many low quality devs, companies are willing to pay a lot for a good PHP dev. My last project was $150/hr, the one before that was $90/hr - both remote.
Any advice on increasing rates? 90$ to 150$ is rather drastic.
It's all about finding the clients willing to pay.

If you're sure you can find more clients, you can just double the rate with the existing ones.

I hear about devs billing $300-500/hr, but that must be some golden enterprise moneys.

I'm just starting my career as a dev, but my first language in school was C++.

At work I use C# - but I hope to keep learning more languages. The main thing I was worried about initially was being stuck with one language my whole career.

Anyone else ever feel that way?

If you spend extra time after work building personal projects, contributing to open source community etc. you'll not stuck in nothing. Don't let your workplace limit and dictate the technology that you know and use, feel free to develop yourself. Then it'll be very easy to jump between different workplaces until you find the best for you.
How did you get into/find side-project ideas?

Ideally I'd like to work on something others could make use of, but I've been having a hard time thinking of something interesting to work on.

Make something you would make use of. That's all.
With the way the market is, unless you stay at one job forever, its actually hard to stay with the same language... the world changes, opportunities change, your interests change...you'd have to try very hard to stick to one language.

Now, on that topic, what's much harder than learning multiple languages, is learning multiple language paradigms. If you have a C++ background, learning C#, Java, Swift, JavaScript, whatever is pretty easy.

Learning Haskell, ML, Elm, F#, Clojure, etc...now that will make your mind bend and spin for a bit. Those aren't nearly as common in a work environment, but you can gain a lot from learning at least one.

This is kind of similar to how if you're an english speaker, learning another european language isn't nearly as interesting as learning a CJK.

I'm just trying to learn all the in's and out's of my work language then I'll start branching out more.

Being stagnant as a developer is something I never want to happen.

Same story: C++ at school and VB then eventually C# at work. About 7 years into my career, I started feeling as though I had stagnated. Over the past 4 years, I took the time to learn Ruby (RoR), Scala, some Clojure, Nim, and now, some F#. Each of them has, in some way, made me a better C# programmer. I can't go out and interview for a position programming any of these languages, but they aren't blindspots for me either anymore.

I would suggest picking a language you have an interest in and a project you have an interest in and having a go at it. Then repeat the process with a new language and a new project. At the end, you will have some working software and an expanded perspective.

Have you ever felt the need to try to change positions to try to learn more about the non-work use languages that you know?
I was heavily motivated to transition from VB.NET to C# to the point where I had an offer at a C# shop. Ultimately, I convinced my department head to allow us to use C# and stayed. I don't think I would make a move exclusively for the technology anymore, but earlier in my career, I certainly did.
This is basically what I'm trying to do now. My entire career has been dominated by PHP thus far (though I've learned many other languages along the way). About a year and a half ago, I saw the writing on the wall and decided to learn something new. I chose Python as I'd heard many good things about the language, and it was more or less entirely new to me (unlike, say, Java or C which I had learned in college). It is so much more pleasant to code in than PHP. And I can't talk about it publicly quite yet, but good things are happening due to my Python abilities.
Learning Lisp, more specifically Scheme. I became curious about it after reading ESR's "How to Become a Hacker". When homoiconicity and other Lisp goodies gradually permeated my brain, the computing world seemed different.

I saw every config file differently, trying to see how the lines between config and code blurred. Method abstractions and bottom up design became much easier. I appreciated all those prefix-evaluation assignments in college. I found a new respect for languages with good REPL's. And finally, it opened my eyes to computing history, where I discovered newer is not always better. The elders of old really got many things right.

Scheme changed everything for me.

I feel sad when I hit special forms in languages, and can't just a macro to change the language to suit the way I want to do it.

It made every other language I used feel overly verbose. Sure, Scheme is a bit verbose, but with two or three macros, and a handful of recursive functions, I write about 1/3 of the code I would in another language.

Having readers, and parsers exposed makes it so easy to fit the language to the task, rather than bludgeoning the language with a hammer, or rephrasing the question till it almost fits.

Random example:

You need to allow a user to run half a dozen functions, with a syntax.

Normal approach, (after you've argued you shouldn't do this), is to write a parser and evaluator, and hope you didn't expose a security hole like SQL injection by accident.

Scheme approach: Generate an empty environment, attach only the necessary functions. Parse and handball to the environment.

Eval doesn't have to be evil, especially when the language provides the tools you need to sandbox users.

It's still evil - what if the input program doesn't halt, or allocates too much memory?
You design the functional building blocks. So a non-halting program would likely use a single stack, and never grow. But more than that, you can use continuations to abort the moment the calculation is too large.
Any examples of using continuations to abort when the calculation is too large? Still grappling with continuations, familiar with coroutines/csp/fibers much more for concurrency, but trying to get call/cc fully under the belt.
I'd probably nest a named let inside a continuation. Raise an exception when an iterator goes too long. Something like that.

I tend to avoid continuations in production code, because how it reacts very much depends on what you're accomplishing. Most exception handling frameworks use continuations, which you can accidentally turn into infinite loops if you don't abort the loop properly.

> You need to allow a user to run half a dozen functions, with a syntax.

You could do this with Javascript 'eval' too and I still wouldn't recommend it. Usually when this sort of requirement comes up the answer is actually visual programming, where the user just has to join blocks up and get's some sort of immediate real time feedback [1]. It's the only time VP is a good idea as the problem is in an extremely extremely constrained environment. Putting Lisp in it's place is really just an all round awful solution. Look at how the AutoCAD Lisp experience turned out [2].

[1] http://acegikmo.com/shaderforge/

[2] https://www.youtube.com/watch?v=LM1RMgIdgR8

JS doesn't have first-class environments, so you can't have the same safety guarantees. Added with its weak typing... You could instruct JS to calculate anything.

Visual Programming might possibly be useful for end users, but in most areas, there are better approaches.

Serving limited environments to users is useful in at least these situations:

* nREPL * Database APIs (ala firebase) * Mathematical APIs (ala Mathematica)

Some of these I've needed in production, such as more precise calculations for statistics. (FloNum integrations into pre-existing applications).

My main point was, LISP is unconstrained, but still gives safety to the programmer.

A simple example of a first class environment:

    (eval (read (current-input-port)) 
    (let
      ((add (lambda args (apply + args))) 
        (null-environment))) 
The only function exposed is called add. There isn't a way to break that. It makes embedding Scheme into applications such as GIMP or games much easier.

(Just a side note, antimony [0] seems to be gaining popularity in its niche)

[0] https://github.com/mkeeter/antimony

A Paul Graham article lead me to Common Lisp and Scheme, SICP, On Lisp which lead to Clojure which lead to being more interested in functional programming, which lead to functional reactive programming and Scala. Quite a long ride, but I'm so happy I'm not writing OOP C++ which was a very dull and frustrating part of my career.
Zope in 1998 was a complete game-changer.
Wow that brings back memories. Is that still used/supported?
Yes, the Plone CMS still runs on Zope2. https://plone.com

The ZODB (Zope Object Database) is also still going strong: http://www.zodb.org

Worth noting here for folks that aren't familiar with Plone that compared to more popular CMS systems like Drupal, Joomla, or Wordpress, Plone's security record is rock solid (in fact, the best security record of any popular Open Source CMS) and is an excellent choice for Intranets and Extranets.

ZODB is also the underlying technology of the recently launched ZeroDB, an e2e encrypted NoSQL DB: https://opensource.zerodb.com/

Scala, back in 2010. I realised that I didn't have to sacrifice productivity for safety, I could have it all: code that's more concise than Python, but safer than Java. Best thing I ever did was finding a way to try it in my then job (a low-risk standalone tool); over the next couple of years I shifted gradually into doing more and more Scala, and now use it full-time.
> more concise than Python, but safer than Java

really? or was that supposed to be the other way around?

Personally, I can't help thinking of scala as a hipster beard on the face of java.

Yes, really. You can write Scala in a very Python-like style, but "_.foo" is much more concise than "lambda x: x.foo", and class declarations are much more concise too ("class Foo(x: Int, y: String)" rather than "class Foo(object): def __init__(self, x, y): self.x = x; self.y = y").

Compared to Java, the inherent safety level of the type system is very similar, but since it's much lighter weight you can do a lot more of it; "newtypes" are much more concise, and for/yield makes it possible to treat errors as values in a lightweight way rather than using the second parallel type system that is Java checked exceptions.

Opinions on Scala aside, it should be said that Python isn't the epitome of conciseness that a lot of people think it is. There are more concise languages out there and languages that are as concise as Python that end up offering more elsewhere.
There are languages that use a denser notation than Python for the same number of syntactic elements, but I don't think many allow you to express the same things in fewer elements. It's famous for looking like pseudocode, which suggests it contains exactly the information that humans need to communicate.
I would argue that pseudocode doesn't present the "end goal" of readable brevity.

Without getting into specifics all too much, an example of things that can make code much shorter, yet readable, is piping data through a series of functions, which is something that Python doesn't allow without repetition, as far as I know. There are lots and lots of things you could point to. I don't think the point is to change Python, but I do feel that people who are too snowed in could accept that the time wherein Python was the most concise, yet readable language has passed quite a while ago, so it might be less of an argument for Python than they'd think.

The same will end up happening with the "ecosystem argument" as well, by the way. It will be touted as Python's greatest strength 10 years into the future when it no longer holds true, but since it's something that's been repeated for tens of years it'll still be repeated, based solely on history.

Came here to say the same thing. Programming in Scala feels elegant and exciting and all of the projects (Akka, Spark, etc) means that there are always new things to learn. Thanks Martin!
Python, hands down. After 10 years of other languages (mostly Java) it opened my eyes to how simple programming can be.
Go recently, and Clojure previously.

Clojure forced me to think in a radical different way than I was used to. I started with massive functions that easily became unreadable, and slowly adapted purity and wrote side-effect free code. The paradigm shift affected me so much that even in other languages, I started writing pure code and use function composition more and more often. Coming from an imperative background, functional programming was a bit difficult at first to wrap my head around, but now I love it! (Eventually I even ditched JavaScript for ClojureScript).

Go recently because it was my first truly compiled, statically typed language after almost 7 years of working (I know, right?). My entire career consisted of Python, PHP, JS, Ruby - you get the idea. Go changed that. On top of that, it is a very biased language that forces it's coding standards on you. Not all are good but you learn a lot about the design decisions behind them and why things work in the way they do.

Plus after working with it for a while, even other compiled, statically typed languages like C++ became a good chunk easier.

And as a extra, very recently: Elixir. Loving functional language, Elixir taught me erlangs genservers and process manage and oh boy! I don't understand why that's not the default tool we use for webservers all the time. It just seems like a natural fit vs other languages. Thanks to supervision trees, it is very easy to write fault tolerant, highly concurrent applications that span multiple servers, without the need for extra tools.

For example: You can spin subprocesses up at any point, communicate with them, kill them, let them crash without fearing that anything else in your application is affected. When previously you needed a queue server, a cache server, background workers, service crash recovery, long running requests processing and more to build a concurrent system, Elixir makes it very easy to implement these things extremely easily as subprocessed without the need to leave your application and grab tool X (upstart/cron/rabbitmq). Worried that something will crash? Just let it crash and the supervisor restarts it. Worried that the supervisor crashes? Then the supervisor of the supervisor restarts the supervisor.

Your background worker process is on server 2 and you want to dispatch something from server 1 from the same mesh? Just use it's PID and let BEAM handle the rest. Same for Queues, Stores, Caches or anything really.

I am highly convinced that learning Elixir is something every web engineer should learn.

I am decade old Java dev, but Elixir changed the way I design web apps.
So, what stack would/do you use/recommend? Elixir + Go + ???
I would almost always use Elixir these days, the advantages are just that good. I don't see anything python or ruby can give me in a server context that Elixir doesn't bring. If I need to go for speed or write a CLI tool, then I'd probably pick Go.

For frontend work, clojurescript. So Elixir+CLJS for almost all web-based apps (or, you know, react native).

There's no need to involve Go in that stack if you're building on Elixir. If you absolutely need interop with something else it'd be better to go with something more focused (either on speed, correctness or something else, as Go doesn't really focus on much of anything, except design-wise) and use it through ports or the like, from the BEAM.

Go as an addition to a BEAM app won't add anything as it mostly does nothing much better than the BEAM and what it does better will be better handled by other languages. Some people would attempt to make a case for it being able to spawn threads, etc., but its scheduling makes in inherently as incompatible with the BEAM as any other language, so it's not a reasonable point to make.

Learning Python (in 2003). I use 5 different languages regularly and I've tried a half dozen more. I've worked in quite a few parts of the industry. Python seems to be the bread and butter -- it gets things done quickly and reliably in so many areas.
PHP developper since +10 years, I learned little by little client side Js through Mootools (object programming 5 y ago). I started nodejs 0.10 2y ago and got a serius wow when i realised node 4 & generators & tj/co could efficiently replace line-per-line how i used to work in PHP (async-co, pg-co) with so much more power (browserify, mocha, istanbul, npm, ...). I guess today the switch is complete for me
Nobody mentions RUST? I thought it,s popular here...
Rust is extremely new, with way fewer people who have tried it. So there wasn't much opportunity to change someone's career (both on the time and the people axis).

Additionally, Rust is a very well-engineered language, but it has few ground-breaking attributes. The borrow checker has never appeared in a non-esoteric language before, I guess. Most of the other goodies could have blown people's minds long before in another language.

I think the borrow checker is actually pretty mind-blowing. In general, I'd say that the combination of modern language features with a real systems target (i.e. low-level, no GC) certainly has the potential to be game changing, in the sense of making it that much less scary to write things in a systems language.
Rust has been great. Not so much for the language itself but rather as a vehicle to explore the layers under the language runtimes I've been using for most of my career.

It hasn't really changed my perspective on programming. I haven't been doing it long enough to have it transform my career. As an answer to the OP, it's not a particularly good one for me.

The biggest impacts on my professional thinking were caused by learning Ocaml and F#. Those impacted greatly the way I approach systems design and programming in general. The second biggest impact was probably learning Scheme and writing a scheme interpreter.
Combo of vim+tmux+tmuxinator.

I work on many projects with many different modules, languages, databases... What this enables me is to be one single command and a seconds away from completely switching context while still maintaining basically identical environment. It encourages experimentation because you're language/project agnostic and it reduces friction to getting started which is a great boon for productivity.

Ocaml, F# for programming languages and ZeroMQ in terms of libraries. And recently HTC Vive in terms of hardware.
In a sense, Javascript.

But more importantly, when I read Javascript: The Good Parts by Douglas Crockford. It was my introduction (though I didn't realize it) to functional programming, closures, and thinking much more about scope. I went from thinking of JS as a pile of junk to a language with remarkable flexibility.

That doesn't mean I do everything in JS, but I find I like the language a lot more than most of my peers.

When I decided to build my own programming language. I had a handful of smaller projects under my belt beforehand. Before that, I had never thought much about what goes into the design of a language, and how important that decisions are (as well as the interactions different parts can have).