Hacker News new | past | comments | ask | show | jobs | submit | more siempreb's comments login

> The answer is that most of our mind does not even realize that fiction is fiction, so we react to it almost as though it were real.

Yes, we are dreamers and believers. And that is also the reason why we are so easy to manipulate. I consider it a weakness that leads to stupidity. Most of our opinions are 'fiction', we think we're 'right' but the truth is that most often we're just dreaming. It's our minds favorite activity because it doesn't require any effort. It just happens, like most things in life.


I think humans who didn't find fiction compelling would be incredibly uninspired. How could it be compelling unless the brain mostly reacted to it like it were real?

Would science exist without alchemy? Or cell phones without Star Trek? Civilization without religion?


Hmm, it only works with a Spotify account which I don't have neither want..


Welcome to making money as a software developer. Your experience is nothing exceptional in IT, most startups are pretty bad if you ask me. You can be more picky with companies, but that will make it tricky to find a new job in time.

My advice for your next job: don't mention any of the bad things you've experienced, talk about all the good things you've learned, the great team you had etc.. always remain positive in every new interview. And don't expect a great developer experience when you enter a new company, (although it sometimes happens), you work for money in the first place, and coding is your skill.


There is something about this immutability thing I really don't like. In the authors example it looks like v1[0] is set to 42 (const auto v2 = v1.set(0, 42)), at least that's how you read it because it contains the word 'set', but you have to 'know' that v1 is immutable and is actually not setting the value, but returning it. So IMAO the naming should be better, I like to read code that is not confusing.

If this construct, that I actually never needed in my entire career, is handy for undo/redo, why not just have a dead simple undo stack? In what situation is an immutable structure your best choice?


They are pretty useful for certain kinds of program analysis (like abstract interpretation and symbolic execution) where you need to create slightly modified copies of the program state (e.g. when you need to split the state on a conditional, or merge two states). Immutable data structures are (space) efficient for this use case. Moreover, you can combine them with hash consing for more space efficiency (only if you are creating lots of objects that share most of their data) and fast equality checking where there is only one copy a value in heap so equality checking is just object identity checking and addresses work as hash values now so hashing large objects is faster too.

The algorithms used in these analyses are usually described in terms of mathematical objects which are inherently immutable and using immutable objects makes correctness proofs easier.

When writing a piece of code, I start with immutable data structures because of the ease of mind they bring to the table (you can pass them around and you know they will not be modified so it makes reasoning and debugging easier, this is less of a problem in C++ because it has const references and const methods). Then, if an algorithm needs a mutable data structure or if the immutable data structures are too slow (e.g. the code is in the hot path) then I switch to mutable data structures. I think it is just a different mentality when approaching programming. It works for me because (a) it is the norm in my field (program analysis, or programming languages in general), and (b) I use a programming language with an ecosystem around immutable data structures (Scala).


Thank you all for taking the time to explain, very valuable for me at least.


I see no problem with the set method name, this is what is used in other lib in other languages. When you use an immutable lib you understand the meaning and that every operation create a new base object.

This is extremely useful for undo/redo, it basically comes for free with it. You no longer have to deal with invisible mutation, listener, event, you just generate the ui on each change from the base to the leaf, and everything is always correct for free. The advantage over an undo stack is that there is a re-utilization of unchanged intermediate data structure (what is change is only the path from the base to the changed element), so you can add a simple ref check in the ui to not redraw of the underlying data has not changed. So the perf come for free.


The simplest answer is that immutability allows you to share data around without worrying about it being modified.

In the OOP world, you might have a "getter" for a property (e.g. a list of some kind) that you don't want readers to be able to modify.

Perhaps "set" was a poor name here, since it usually means something else in a C++ context. I quite like "with".


Should add that C++ has const, making some of this irrelevant. In the C++ case immutability is about making minor changes to a structure more efficient by reusing the previous version. This is only possible with immutability because you need to be sure that your "base" structure won't change underneath you!


Can't copy-on-write achieve the same thing? If you keep a reference count, you can know whether it's safe to mutate the underlying data, or whether you need to make a copy first.


Technically copy-on-write is an implementation detail.

It may or may not be implemented this way.


I mean that CoW classes like Qt's QStringList do the same data sharing without being immutable.


Admittedly, it's pretty easy to accidentally make unnecessary non-const accesses in modern C++. An immutable API would certainly avoid a lot of qAsConst casts.


Persistent data structures are thread-safe and are useful for concurrency. That's partly why they are a core part of functional programming languages like Clojure and Haskell. Persistent data structures are also useful for version control.


In scheme, mutating functions end with "!". (append lst lst2) creates a new list without modifying lst, whereas (append! ...) is allowed, but not necessarily required, to mutate the list.


what would be a good word for this ? recreate ? recompute ? with_new ?


In general, I think verbs should be avoided, when possible, as names of functional operations. For instance, in Java, 'BigInteger.add' should have been 'plus'. Compare:

  x.add(y);
  x.plus(y);
People have been known to write the first one expecting 'x' to be updated. With the second, I think it's clearer that it's a value that needs to be assigned to a variable.

For the operation in question here, I suggest 'with'. This is what I have used in my own functional collections libraries; I think it originated in SETL.


I am a fan of nouns(or gerunds) for pure functions, and verbs for mutating functions. I.e:

    x.add(y); // x now equals x + y 
    x.adding(y); // returns x + y without mutating x


Clojure as `(assoc col key val)` and `(update col key fn)` though I don't know that the naming scheme is significantly clearer.


I'd probably be happy with "update", which is similar to Clojure's API for its persistent vector and map.

https://clojuredocs.org/clojure.core/update


update is a different operation, it takes an update function for the value. The clojure equivalent to set is assoc.


> C++

> Pros: none

> Cons: ill-defined, far too big, Object Oriented Programming, loads of baggage, ecosystem that buys into its crap, enjoyed by bad programmers.

This is just rubbish. Fair chance the author wrote this with the help of C++ (your OS or browser maybe?). And I enjoy C++ and it's eco system as well, compared to other languages. So that makes me a bad programmer? I'm surprised people are taking this post serious.


Honestly most people I meet in real life (so not representing at all) who enjoyed C++ where technically skilled but had to fight with following problems:

- bad at keeping code simple

- to much focused on details instead of the broader picture

- bad as team leads due to missing some relevant management skills

- bad at producing solutions which where "just good enough" (instead of perfect)

Some of them where aware of their weakness and learned to improve on that areas, setting them on a path of becoming excellent software engineers.

Others where obvious about it or even in denial about it.

In a certain way they had been examples about how a person can be both a technical skilled programmer, as well as as bad programmer who on a subtile way accidentally makes it hard to produce a good end product in any reasonable amount of time.


'there is widely used software written in language x' != 'language x is good'

C++ definitely has its uses (and for a long time was best-in-class for many of them) but it is largely being superseded by other options (not necessarily Rust).


Just as an example it's really hard for me to do low level CUDA GPU programming in any other language.

I'm trying hard to use Julia, but understanding its PTX output is really hard for me, and also I don't know how to use the matrix multiplying GPU instructions.

Rust's PTX output is not supported, so I haven't really tried it.


I agree. Given that I do not like C++ and try to avoid it at all costs, it is unfair to say it does not have any advantage:

- It is available on a very wide range of platforms

- Several implementations are available

- It is updated regularly

- Etc.


>Fair chance the author wrote this with the help of C++ (your OS or browser maybe?)

Which OS would that be? Most OSes hardly touch C++, except at higher layers than the kernel.


Just a quick look at the code. One of the first lines in the random first file I checked:

> function printBasis( state: any, dynamicBasis: any, staticBasis: any, indent: number = 0 ): string { ...

When Microsoft removes the 'any' type this language (and hype) is dead. I've never came across a TS code base that is actually 100% type safe, and that apart from the fact that at run time there is no type checking at all, just Javascript.. That's why I still prefer the ease and security of dynamic type checking, because it is real safety. I know TS can still help in a large code base especially for the less experienced dev's out there, but it comes with a very high price that no TS proponent dears to admit or cannot assess. We live in a world of dreamers.


I’ve never had any trouble avoiding usage of any thanks to how powerful TS generics and interfaces are. Also why would it type check dynamically? TS is a static typing utility, there are other ways to type check JS at runtime if you need to do so. These statements (and that you seem to think TS is most helpful for “less experienced secs”) make me think you’re not actually that familiar with its usage

I’ll be the first person to say that I’m eager for a viable front end solution without any JavaScript (shoutout vugu, an awesome but young and experimental go lib), but TS isn’t going to die with the removal of any lol


By "random first file" you mean "first file in the directory," which is for the cli. The printBasis function is the driver for the P part of the REPL, and it's not exactly something that the interpreter depends on for correctness. Poking around the codebase, it looks like they could give types fairly easily to this function, but they just haven't done it yet.

It looks to me like you found one of the only functions that use 'any' in the entire codebase. Others are things involving bindings in an environment (where anything really can appear, though one might argue a union type restricting to only ML value types would be more appropriate) or generic functions like for equality testing, which I'm not sure exactly why they take 'any'.


Dynamic type checking? What?

You can turn strict mode on and remove the 'any' type.

It's for transitioning your JS codebase or if you don't need 100% soundness.

I like to type the core of the app and slowly type other less important things when I have time.


I have not used TS, but I have used Flow, which is just a typesystem for JS from Facebook.

I was never confident that the typing I was adding was doing anything other than making the Flow interpreter(for lack of a better word) happy. I had no more confidence in my code that with out it.

So I removed it.

I believe that well maintained linting rules, and good code reviews (you are doing code reviews, aren't you) give you all the same protection, and less false sense(s) of security.

Like you imply (I think), it is still just JS. I beleive you are better served by understanding that, and coding carfully.


I think pretty much anyone who writes TS is well aware of the dangers of any. However, I think it is a necessary convenience since TS does not use nominative typing.


> It cannot be stressed enough that pools of water should not be forming at the top of mountains. That’s just not what Mother Nature had in mind.

Does the author really know what Mother Nature had in mind than? When statements are clearly made up, it is not good journalism and the whole article becomes questionable.


About 4 million lines of Python code is just a bad decision from the start. Now they are trying to fix it with types, but IMHO the fault is not in the language. They just should have started out with a statically typed language that scales better.


Yeah, I'm sure Dropbox's founders remember and regret that fateful day when they said to each other, let's write 4 million lines of Python to get this fledgling business idea off the ground!


> The worst, buggiest, least maintainable code I've ever dealt with was a 500ish line (heavily tested!) untyped Python file at my last job. Caused more trouble than all the Java and C++ and Go combined.

That cannot be because of missing types. If you make just 500 lines python unmaintainable you're just a terrible programmer! In it's core it cannot be a type problem. And that is my main point here; there is a hype going on in the dynamic languages to add types, as if it solves everything. IMHO it's not that simple.

To avoid unnecessary explanation about the value of static typing; I am not against, I'm doing c++ and it serves me well.


The code in question was somewhat experimental, didn't have a clear owner and was modified by a number of people fairly frequently. There would've been much less room for sloppiness and shortcuts (let me just stick this extra field on this object) in Java, C++ or Go.


Lets try to be a little more honest.

> 1. What do you want to do differently in your next role?

Earn more money

> 2. Imagine yourself in three years. What do you hope will be different about you then compared to now?

Being more wealthy

> 3. For the last few companies you've been at, take me through: (i) When you left, why did you leave? (ii) When you joined the next one, why did you choose it?

  1. Because the job sucked
  2. Because I need to pay the bills


> 4. Among the people you've worked with, who do you admire and why?

The CEO of company X, because she managed to free herself from this life sucking process

> 5. Tell me about a time you took unexpected initiative. Follow-up: Can you tell me about another?

I left several jobs because the code base and the colleagues sucked too much

> 7. What motivates you to work?

The need for money

> 8. Looking back on the last five years of your career, what’s the highlight?

Every time again, the holiday

> 9. What are you really good at, but never want to do anymore?

Being a brown noser

> 10. What’s the difference between someone who’s great in your role versus someone who’s outstanding?

Even better ass licking

> 11. How did you prepare for this interview?

I didn't prepare, I just try to be honest

> 12. What do you believe you can achieve with us personally or professionally that you can't anywhere else in the world?

Hopefully I can up my salary for the next gig

> 13. What are the three most important characteristics of this function? How would you stack rank yourself from strongest to least developed among these traits?

It is not sane to rank myself against unknown factors

> 14. Tell me about your ideal next role. What characteristics does it have from a responsibility, team, and company culture perspective? What characteristics does it not have?

My ideal next role is developing software for my own product. The main characteristic would be:

   - no annoying managers to manipulate me
   - no forced 'happy team'
   - no agile or scrum
   - no spaghetti codebase
   - no code reviews
   - no managers and self made 'important' people taking a cut of my produce
   - no need to lick ass of colleagues to survive the office politics
   - no traffic jams, no commuting
   - a healthier and happier life in general


At this point I expect to be rejected from the interview, and wish them all the best.


I'd hire you over a candidate who gives the 'ideal' answers given in the article. Atleast I'd get an honest no BS assessments about work without having to coax it out.


Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: